2006-05-09 画像配信の負荷分散も比較的簡単?(その3)

初めての方は画像配信の負荷分散も比較的簡単?(その1)からどうぞ.
アクセス/保持データ量ともに多くなってきてどうにもならなくなったらどうするか?お金があるところはサーバを強化したりメモリを増やしたりするのも手だろう.ただもっと安上がりで効果的な方法がある.
どうにかなるまで1台あたりのアクセス数と保持データ量を減らせばいいのだ.
ずっこけた人がいるかもしれないけど,こっちは大真面目である(笑).別にアクセスが少なくなるまでサービスを縮小させろという意味ではないので,もうちょっと付き合っていただきたい.
下記のような仮想の実装例を考えてみよう.
http://i.yimg.jp/images/search/head_050825.gif
にアクセスがあったらURLを10で割ってその余りに応じて
img0.yimg.jp
img1.yimg.jp
img2.yimg.jp
img3.yimg.jp
...
img9.mixi.jp
の10個のHostに振り分けてみる.具体的には
http://i.yimg.jp/images/search/head_050825.gif なら
http://img0.yimg.jp/images/search/head_050825.gif
にリダイレクト.
http://i.yimg.jp/images/search/head_050825_1.gif なら
http://img1.yimg.jp/images/search/head_050825_1.gif
にリダイレクトといった具合だ.
この方法だとi.yimg.jpに当たるサーバはただ振り分けのみを担当すればいいので,アクセスが増えてもただ単純にサーバを増やせばよい.
一方実体ののimg?.yimg.jpのサーバ群は自分の受け持つデータは全体のデータの1/10なので,ここをメモリキャッシュに収まる程度に抑えることによってやはりサーバを足せば足すほどパワーが増すことになる.さらにデータが多くなってメモリキャッシュからあふれ出すようなら10で割るのを20なり30なりで割るようにして1台あたりの受け持ち量を抑えられるように全体構成を変えればよい.
また過去にアクセス数と保持データが少なかった時は
サーバの単位時間のリクエスト処理能力 > ユーザの単位時間のリクエスト数
が維持できていたことを思い出してみよう.つまりはこの状態を意図的に作り出せばいいわけだ.
この考え方はいわゆるコンピュータサイエンスの成功法則のひとつ,ローカリティ(局所性)の考え方で,キャッシュなどもこの考えを基礎においている.この考え方は非常に重要にもかかわらず,大学の授業とかではその真に意味するところを教えてくれなかった気がする.私がこのエントリを書こうと思ったのもこのあたりのこときちんと説明しようと思ったからだ.
コンピュータはいろいろな仕事をさせすぎると遅くなっちゃうけど,データ量を抑えて処理する分には十分過ぎるほど速いというわけだ.
この方法を使っているところは随所に存在する.たとえばFFシリーズが一定ユーザ数になるたびにワールドを分けたり,2chで板が増えるたびにxxx.2ch.netなサーバ名を増やすのもデータを分散させてローカリティを維持することにより,負荷を安定させるための苦肉の策なんだろうと想像できる.
ただHTTPアクセスごとにリダイレクトしちゃうのはどうよ?ってのとデータごとにHost名が変わってしまうのはいやんなので,1個のホスト名で何とかしたいという要望はあるだろう.
実際Googleのイメージ検索の画像のURLはimages.google.com1つで1,187,630,000の画像を保持している(ように見える).
ここにもやっぱり秘密がある.
アクセスが特定の画像に集中した場合には問題が出ると思うのですが
どのように対応したらよろしいでしょうか?
例えばある画像が1枚某ブログにウプされて
2ちゃんのいろんなスレに画像への直リンクURLが貼り付けられて祭りになり
1台の画像鯖に負荷が集中しさばききれなくなった場合、
先生の方法ではいくら鯖を増設しても負荷は分散されないし
アクセスが集中している画像鯖だけ別にDNATやmod_proxy+mod_rewriteとかその他の方法との併用で
負荷分散はできますけど祭りが起きるたびに毎回毎回特定鯖だけネットワークに手を加えるのも
めんどくさいと思うのですがこの辺はどのようにしているのでしょうか?
確かに上記のケースに関しては書いていませんでしたね.
http://d.hatena.ne.jp/yamaz/20060407
のコメント欄にちょっとだけ書いてありますが,
動画と静止画では少し事情が違うのと,内容が少し長くなりますので,
別エントリで書こうと思います.