2010年05月12日 03:09
Introducing FlockDBの続きを訳しながらメモ。
前半→Introducing FlockDB (1)
「教訓」で述べられていることは参考になる。特に正常系とエラー系で同じパスを通るようにする、というのは応用出来そうなアイデア。
(続き)
書き込み処理はシステムに入力された時刻に対して冪等で可換である。
我々は操作の実行の順序によらず同じ結果を得ることができる。
故に我々は一時的なネットワークやハードウェアの故障を隠すことができ、
時間がったったあとに再実行することができる。特にこれは初期の展開に
効果的である。
可換な書き込みは新しいパーティションを育成するプロセスを単純化する。
新しいパーティションは書き込みトラフィックを即座に受け入れることができ、
同時に古いパーティションからのデータのダンプをゆっくりと背後で
受け取ることができる。ダンプが一度終わると。パーティションはすぐに
"live"かつ読み取り可能になる。
アプリケーションサーバ("flapps"という愛称)はScalaで書かれていて
ステートレスで水平にスケーラブルである。クエリの負荷が増加してきたら
データベースとは独立してアプリケーションサーバを追加することができる。
それらは非常に小さいthrift APIをクライアントに向けて公開していて、
もっとリッチなインターフェースのためにクライアントはRubyで書いている。
我々はGizzard Libraryを使ってパーティショニングレイヤーを管理している。
フォワーディングレイヤーはsource IDの範囲から物理データベースへのマッピング
を定義し、レプリケーションを同じフォワーディングアドレスに対してそのような
テーブルをツリー状に構築する事によって管理される。書き込み操作はローカルに
ジャーナリングされたあとに認識される。データベースの可用性やパフォーマンスは
Webサイトのレスポンスタイムとは分離される。
それぞれのエッジは二回保存される。ひとつは前向き(ソースIDでインデックスが
つけられ、パーティショニングされる)で、もうひとつは後ろ向き(宛先IDでインデックス
がつけられ、パーティショニングされる)である。「だれが私をフォローしているか?」
のようなクエリが「私がフォローしているのはだれ?」と同じように効率的で、
どちらも必ず同じ単一パーティションで結果を得ることができる。
最終的な結果は必要に応じて拡張できるコモディティサーバのクラスタになった。
冬の間に、我々は誰にも気づかれずに50%ほどデータベースを拡張した。
我々は現在130憶の園児を保存していており、ピークのトラフィックは
秒間2万回の書き込みと10万回の読み込みを維持している。
教訓
もとのゴールとは違うにせよ、いくつかの有用なパターンが我々の経験のあとに残った。:
・ロングテールをカットオフするために積極的なタイムアウトせよ。
あなたはシステムの不公平さを完全にふるい落とすことはできないだろう、例えば
99.9パーセンタイルにあたる問い合わせが非合理に長く待たされるなど。もし複数の
ステートレスなアプリケーションサーバがあったら、あなたは合理的な時間が経った
クライアントを切断し、別のアプリケーションサーバを試す機会を与えることができる。
・すべてのケースをエラーケースとせよ。
または、別の言い方をするとエラーでも通常動作と同じコードのパスを使うようにせよ。
非常事態のみに使われるあまりテストされていないモジュールを作っては
いけない。少なくとも新しいことに挑戦するような感覚になる。我々は
すべての書き込み操作をローカルにキューに入れている(Kestrelをライブラリとして
使っている)、そしてそれらが失敗すれば分離されたエラーキューに投げられる。
このエラーキューは書き込みキューに周期的にフラッシュバックされ、つまり
リトライは最初の実行時と同じコードのパスを通る。
・はじめのうちは何も無意識に実行するな。
たくさんの計器やレバーを与え、一度現れたパターンはスクリプトによる自動化する。
FlockDBはそれぞれの異なったサービス(MySQLやKestrelやThrift)に対するクエリの
レイテンシの分散を測定しタイムアウトの時間を調整することができ、それぞれの
操作のカウントをレポートする、我々はクライアントライブラリがクエリのロードを
突然二倍にしたりするのを見ることがある(または、さらなるハードウェアの追加が)。
手動インスペクションのためになんどもエラーキューを循環している書き込み操作は
ログにダンプされる。バグが発覚することがあれば、それを直して、ジョブを再投入
し、クライアントのエラーであればそれはよいバグレポートとなる。
以上。
(だんだん後半の訳がひどくなってるが・・。)
前半→Introducing FlockDB (1)
「教訓」で述べられていることは参考になる。特に正常系とエラー系で同じパスを通るようにする、というのは応用出来そうなアイデア。
(続き)
書き込み処理はシステムに入力された時刻に対して冪等で可換である。
我々は操作の実行の順序によらず同じ結果を得ることができる。
故に我々は一時的なネットワークやハードウェアの故障を隠すことができ、
時間がったったあとに再実行することができる。特にこれは初期の展開に
効果的である。
可換な書き込みは新しいパーティションを育成するプロセスを単純化する。
新しいパーティションは書き込みトラフィックを即座に受け入れることができ、
同時に古いパーティションからのデータのダンプをゆっくりと背後で
受け取ることができる。ダンプが一度終わると。パーティションはすぐに
"live"かつ読み取り可能になる。
アプリケーションサーバ("flapps"という愛称)はScalaで書かれていて
ステートレスで水平にスケーラブルである。クエリの負荷が増加してきたら
データベースとは独立してアプリケーションサーバを追加することができる。
それらは非常に小さいthrift APIをクライアントに向けて公開していて、
もっとリッチなインターフェースのためにクライアントはRubyで書いている。
我々はGizzard Libraryを使ってパーティショニングレイヤーを管理している。
フォワーディングレイヤーはsource IDの範囲から物理データベースへのマッピング
を定義し、レプリケーションを同じフォワーディングアドレスに対してそのような
テーブルをツリー状に構築する事によって管理される。書き込み操作はローカルに
ジャーナリングされたあとに認識される。データベースの可用性やパフォーマンスは
Webサイトのレスポンスタイムとは分離される。
それぞれのエッジは二回保存される。ひとつは前向き(ソースIDでインデックスが
つけられ、パーティショニングされる)で、もうひとつは後ろ向き(宛先IDでインデックス
がつけられ、パーティショニングされる)である。「だれが私をフォローしているか?」
のようなクエリが「私がフォローしているのはだれ?」と同じように効率的で、
どちらも必ず同じ単一パーティションで結果を得ることができる。
最終的な結果は必要に応じて拡張できるコモディティサーバのクラスタになった。
冬の間に、我々は誰にも気づかれずに50%ほどデータベースを拡張した。
我々は現在130憶の園児を保存していており、ピークのトラフィックは
秒間2万回の書き込みと10万回の読み込みを維持している。
教訓
もとのゴールとは違うにせよ、いくつかの有用なパターンが我々の経験のあとに残った。:
・ロングテールをカットオフするために積極的なタイムアウトせよ。
あなたはシステムの不公平さを完全にふるい落とすことはできないだろう、例えば
99.9パーセンタイルにあたる問い合わせが非合理に長く待たされるなど。もし複数の
ステートレスなアプリケーションサーバがあったら、あなたは合理的な時間が経った
クライアントを切断し、別のアプリケーションサーバを試す機会を与えることができる。
・すべてのケースをエラーケースとせよ。
または、別の言い方をするとエラーでも通常動作と同じコードのパスを使うようにせよ。
非常事態のみに使われるあまりテストされていないモジュールを作っては
いけない。少なくとも新しいことに挑戦するような感覚になる。我々は
すべての書き込み操作をローカルにキューに入れている(Kestrelをライブラリとして
使っている)、そしてそれらが失敗すれば分離されたエラーキューに投げられる。
このエラーキューは書き込みキューに周期的にフラッシュバックされ、つまり
リトライは最初の実行時と同じコードのパスを通る。
・はじめのうちは何も無意識に実行するな。
たくさんの計器やレバーを与え、一度現れたパターンはスクリプトによる自動化する。
FlockDBはそれぞれの異なったサービス(MySQLやKestrelやThrift)に対するクエリの
レイテンシの分散を測定しタイムアウトの時間を調整することができ、それぞれの
操作のカウントをレポートする、我々はクライアントライブラリがクエリのロードを
突然二倍にしたりするのを見ることがある(または、さらなるハードウェアの追加が)。
手動インスペクションのためになんどもエラーキューを循環している書き込み操作は
ログにダンプされる。バグが発覚することがあれば、それを直して、ジョブを再投入
し、クライアントのエラーであればそれはよいバグレポートとなる。
以上。
(だんだん後半の訳がひどくなってるが・・。)
コメント
コメントの投稿