はじめに
前置き
昨今クラウド上でパズルみたいにサーバー群を組み合わせてサービスのインフラを構成できるようになっています。
今まで便利だなあくらいでその構成についてはをあまり気にしてこなかったのですが、何がどうしてそうなっているのかを推測できることはアプリケーション開発的にも重要で、それを教えてくれる先輩がちょうど!近くに!いて内容がQ&Aでわかりやすかったのでまとめようと思いました。
以下そんな内容ですが、この場合はこういう解決策あるよ!等教えていただけたら幸いです。
ECサイトを構築するとしたら、その最小構成はどうなる?
登場人物はシンプルに、
- Webサーバー
- DBサーバー
です。
ユーザーPC =(問い合わせ)=> Webサーバー =(問い合わせ)=> DBサーバー
||
ユーザーPC <=====(結果)== Webサーバー <=====(結果)== DBサーバー
ユーザーが増えてリクエスト数が増加しました
最初にオーバーワークになりそうなのは?
アクセス内容やアプリケーションの作りにもよりますが、だいたいの場合においては
A. DBサーバー
です。それも書き込みリクエストに比べて参照リクエストが多く、それが負担になりはじめます。
参照リクエストを上手にさばこう
キャッシュを利用する
WebサーバーとDBサーバーの間にキャッシュを置き、一定時間更新されなくても良いデータはそちらでさばいてもらうようにします。
ただしこれにも限界があり、特にECサイトのようにリアルタイムで変化する情報を確実に同期させていなければいけないアクセスが多い場合(在庫数など)、あまり有効な手立てではありません。
参照DBを増やしましょう(レプリケーション構成)
参照先のDBをコピーで増やして負荷分散します。
これがマスター1:スレーブ(マスターのコピー)nのレプリケーション構成です。
この場合、マスターとスレーブのデータ同期が問題となってきますが、
ユーザーPC =(処理)=> Webサーバー =(書込み命令)=> マスターDB -(書込み/非同期)-> スレーブDB
||
ユーザーPC <=(処理OK)= Webサーバー <=(処理OK)= マスターDB
-----
ユーザーPC =(参照)=> Webサーバー =(参照命令)=> [割振り] => スレーブ?号のDB
||
ユーザーPC <=(結果)= Webサーバー <=========(結果)======= スレーブDB
こんな感じで書込み処理に対しては非同期にマスターからスレーブに書換えの命令が走り、参照リクエストに対しては空いてるスレーブDBからデータが返却されます。
各テーブルのデータ量を減らしましょう
参照リクエストに対して答える際、他にボトルネックになりそうなのはデータ量の増加です。ユーザーデータに紐づくログデータなどは特に増加具合が激しく、データ量が多いがゆえに検索時間がかかってリターンが遅くなってしまうケースが考えられます。
この場合に考えられる対策としては、
- スレーブ1:ユーザー1〜1000までのデータを保存
- スレーブ2:ユーザー1001〜2000までのデータを保存
- ...
というように、ユーザーID単位でテーブルを分ける方法ですが、管理が複雑になるため単純にDBのスペックをあげるほうが有効だったりするそうです。
DBのスペックをあげられない場合、クラスター構成といって複数の低スペックPCを一つのPCとみなして稼働させるような方法もあるらしいのですが、ここまで大規模になることはほぼないらしいので今は突っ込まずにおいておきます。
(書込みデータが10011011001100001だった場合、4台のPCでDB1が1001/DB2が1011...みたいに分割して保存したりするイメージ)
DBサーバーを改善したら、今度はWebサーバーへのアクセス増加がボトルネックになりました
アクセス集中でWebサーバーのほうがボトルネックになった場合、どうするかというお話です。
Webサーバーを増やしてロードバランサーをかます
DBの場合同様、負荷分散のためにWebサーバーを増やします。このとき振り分けをしてくれる仕組みが必要になるのですが、これを担当するのがロードバランサーです。
静的コンテンツサーバーの分離
それでも限界がきた場合、静的コンテンツを分離して静的コンテンツサーバーに保存・そこからDLしてもらうように変更します。
手法としてはなんとなく知っていたのですが、なぜそれで改善するのか聞かれて答えられず。。何となく知っていて何となくやっているとこういうところが弱くなります。。
静的コンテンツと動的コンテンツは何が違うのか?
A. ファイルの大きさと生存期間
です。
静的コンテンツ(動画や画像)は大容量のため、素早くユーザーに届けるために必要なノウハウがそもそも動的コンテンツとは大きく異なります。そのため、サーバーを分けて処理を分離したほうがお互い得意なところで改善勝負ができるというわけです。
また、静的コンテンツは動的コンテンツに比べて生存期間が長いので、キャッシュが良い仕事をします。
静的コンテンツの問い合わせ分だけWebサーバーが楽をできるようになる
そもそも一般的なWebページを考えたとき、html持ってくる => imgタグから画像を問い合わせる => ...という何往復ものリクエストをWebサーバーが捌いています。
その往復回数が減るというだけでもWebサーバーはかなりの楽ができるようになります。
番外編:そもそもアクセス先サーバーが物理的に遠かった場合、応答が遅くなる問題の解決(CDN)
静的コンテンツはキャッシュが良い仕事をするという話ですが、物理的に遠いサーバーへのアクセス速度を改善する仕組みとしてContentsDeliveryNetwork(CDN)という仕組みがあります。
CDNを設定すると静的コンテンツを世界各国のどこかのサーバーに適当にキャッシュしてくれるので、一番近いキャッシュサーバーから重たい静的コンテンツを持ってこられるようになり、速度が改善するというわけです。
終わりに
以上、この話は実はCDNって何ですかという話から派生したのですが、それ以外のほうをしっかり教えてもらうことになりました。
これを機にちゃんと「なぜそうなっているのか」をはっきりさせる根気を持つようにしようと思った次第です。