Hatena::Groupdann

dann's blog このページをアンテナに追加 RSSフィード

Fork me on GitHub

2008-10-06

ストレージサーバーのスケールアウト

| ストレージサーバーのスケールアウト - dann's blog を含むブックマーク はてなブックマーク - ストレージサーバーのスケールアウト - dann's blog ストレージサーバーのスケールアウト - dann's blog のブックマークコメント

アプリケーションサーバーやDBサーバーのスケール方法については一通り情報が出そろっていて、どこも同じような方法でやっているような気がしているのですが、ストレージサーバーについてはあまり情報がないなぁと思っていました。

自分が知る限り最良の記事である、kazeburoさんの記事とgreeのイメージクラスタの記事を読んでざっくりまとめてみました。

ストレージサーバーの構築は経験がないので、もう少し運用方法とか含めてしりたいですね。ご存知の方がいれば、他の方法もあるよ!とか、他ではこうやってるよ!など、是非教えてください。

画像のWriteの分散

  • アプリケーションでは、非同期で画像変換タスクをQueueに追加
    • Gearmanでやってるところもあれば、TheShwartzでやってるところもあるみたいですね
  • WorkerでQueueからタスク受け取って画像変換
  • 画像変換後、画像をWebDAV経由でStorageサーバーにコピー
    • アップロードはバックアップをかねて2台のサーバーにコピー
    • どのサーバーにアップロードするかはファイル名から分散させるように、

できるアルゴリズムを決定する

(Consistent Hashing or so)

画像のReadの分散

Reverse Proxy
  • mod_proxy_balancerでSquidサーバーを分散
    • キャッシュするほどアクセスのある部分はSquid
    • それ以外はSquid介さずにスルー
Squid
  • Squidによるcacheサーバとそれを分散するbalancer
  • Squidのbalancer
    • Squidサーバーの分散は、CARP(Cache Array Routing Protocol)を使う
      • URIcacheサーバのhash値を組み合わせてアクセスするサーバを決定
      • mod_proxy_balancerのbalanceアルゴリズムを追加すれば、balancerは不要かも
director層
  • mod_proxy(mod_proxy_balaner)とmod_rewriteが組み込まれています。
  • Reverse ProxySquidcacheサーバからのリクエストのURIから、

画像ファイル名の剰余を求め正しいストレージサーバへproxy

SquidのキャッシュサーバーとStorageサーバーを密に結合しないようにすることで、

設定ファイルのメンテナンスコストを下げ、かつストレージサーバーへの負荷の

balancingもしていると。AppServerとDBサーバーの間のLVS的な存在のようなものみたいですね。

ポイント

何点かポイントがあるようなので、少しまとめてみました。

  • 画像のストレージ先をどう分散させるか
    • CARP, Consisten Hashing
  • ストレージサーバーへのwrite/readはhttp
      • NFSサーバーが死んでappserverが応答しなくなることを避ける
  • 画像のキャッシュ
  • ストレージサーバーの対障害性
    • ストレージ先をファイルシステムとしてマウントするのではなくHTTPでアクセスする形にする
    • 画像は複数サーバーにコピー
      • WebDAV + アプリで頑張る
      • DRBDでコピー
      • MogileFSなどの分散ファイルシステムにまかせる?

疑問点

  • storageサーバーの冗長性の確保方法はどうする?
    • 複数のストレージサーバーにアプリ側でコピーするのは失敗したとき面倒そうだなぁとか。
    • DRBD + Heartbeat?
  • ストレージサーバーのバックアップとリストアの方法
    • サイズ大きいだけに復旧するのが面倒そうだなぁ
  • 画像のサイズが大きくなると、どうキャッシュさせていくのがいいのか
  • そもそも自前でこんなのやらないのかなぁとか

See also

TODO

  • MogileFSについても後でまとめる

special thanks to Hな人!

Perlでテスト数を数えずにテストをする方法

Perlでテスト数を数えずにテストをする方法 - dann's blog を含むブックマーク はてなブックマーク - Perlでテスト数を数えずにテストをする方法 - dann's blog Perlでテスト数を数えずにテストをする方法 - dann's blog のブックマークコメント

Perlでテストをしていたときの一つの疑問は、assert書いてるのに、なんでわざわざそれを手動で数えなきゃいけないんだろうということでした。

一応、Test::Moreにno_planというのがあるんですが、これが使えないんですね。

use strict;
use warnings;
use Test::More qw(no_plan);

ok 1;
exit;
ok 2;

なぜかというと、上記のケースではテストが失敗せずに成功してしまうからです。。。これでは全然使えませんね。

そこで、Test::Mostのdefer_planを使います。

http://search.cpan.org/dist/Test-Most/lib/Test/Most.pm#Deferred_plans

use strict;
use warnings;
use Test::Most qw(defer_plan die);

ok 1;
exit;
ok 2;
all_done;

この場合、テストは成功せずに失敗します。これでテスト数を数えなくてもいいですね

# Test::MostはPerlモジュールで使うにはおおげさですが、アプリケーションで使う分には結構よさそうです。

perlcodesampleperlcodesample2009/01/31 15:31exit;
だとテストは成功しますけれど、
die
にすると試験は失敗しません?

Test::Moreのドキュメントを読むと、dieしたときは、255という終了コード(成功した場合は0)が返ってくると書いてあります。

no_planを使っても、テストに成功したかどうかには気がつけると思いますが、どうなんでしょうか?