カテゴリー
技術

fav.or.it創業者による「もしtwitterを作り直すなら」

コメントつきソーシャルRSSリーダーfav.or.itの創業者Nick Halsteadさんが、自分がtwitterのスケーラビリティを直すならこうする、というエントリを書いている。 twitterは今日も「データベース […]

コメントつきソーシャルRSSリーダーfav.or.itの創業者Nick Halsteadさんが、自分がtwitterのスケーラビリティを直すならこうする、というエントリを書いている。

twitter.png

twitterは今日も「データベースがロストした」とかで落ちていて、不安定さに対する不満の声をそれこそ毎日のように見かけるようになっている。

技術的な興味から、訳しながら読んでみたのだけれど、ほんとうにこれですべてた解決するのか、については僕はわかっていない。わからないものを出すのもどうかと思い数日放置してたんだけど、もっと手の長い人に読んでもらうのも意味はあるかなと思い直し、以下に公開する。

「fav.or.itはこれよりもっと複雑だ」と言ってるけれどfav.or.itはtwitterほどユーザいないし(笑)。


前段では有名ブロガーのRobert Scobleさんが、技術的な理解無しにtwitterをMS Exchangeになぞらえたり、改善提案したりしていることに対して「黙れ」と書いている。

Nickさんの設計の基本はShard(シャード)にある。システム中のどのポイントを取ってもスケールするように、台数を増やせば対応できるようにしておけば、スケーラビリティの問題はなくなる、と。

キュー Shard

ユーザIDからハッシュで求まるShardにメッセージキューを持たせる。追加速度が重要なのでオンメモリに置く。

重要な点は、このサーバが日付とつぶやきのidの関係だけを扱うこと。

友達 Shard

ユーザの友人を保持するShard。キューShardより一台あたりより多くのユーザを持てるはず。あるユーザの新着メッセージを受け取ったら、友達リストを返す。

ハッシュを使って、それぞれの友達が存在するキューShardのリストを得る。

これで、たとえScobleさんのように25,000人の友人が居たとても、各キューShardは1000以上のinsertを扱うことはなくなる。

Joiner Shard

新着の(20個とかの)つぶやきを取得するときは、つぶやきのidのリストをキューから取得するだけなので、実際のつぶやきはつぶやきShardから引き出さないといけない。このJoinするShardはたぶんmemcacheを使うことになるだろう(つぶやきShardへのアクセスを減らすため)

もう一つのポイント。キューShardはインメモリなので、正規化を崩されて非効率な形式で格納されている。ディスクに保存しようとしたら重大なオーバヘッドがかかるだろう。JoinするShardはキューShardから一部分だけを取得することでこれに対処し、そのあと正規化されたDBから残りを取得するようにする。

つぶやき Shard

あたらしいつぶやきはつぶやきShardに格納される。ハッシュをつかってこれを複数サーバに広める。古くなったつぶやきは、取り出し速度よりも保存に適した大きなストレージに移動させるようなアルゴリズムを使う。

ウェブ Shard

ここは簡単だ。上記のShardsで複雑なデータベースが動く仕組みはできあがっているので、ウェブShardは実際のAPI/HTTPなどのリクエストの処理をして、リクエストを関連するShardに受け渡せばいい。

特定の(一番よく呼ばれる二つの)処理でどのShardがどう呼ばれるかをいかに説明する。

つぶやく
  1. ウェブShardはリクエストを受け、つぶやきShardにメッセージを送り保存させ、そのメッセージに対応するつぶやきIDを受け取る。次に、このメッセージの送り主の友人が格納されている友達Shardを探す。
    1. つぶやきShardはメッセージを受け取り、保存し、新しいIDを発行して返す
  2. 友達Shardは、メッセージを受け取る。ユーザのすべての友達のキューが存在するキューShardにシグナルを送る
  3. キューShardは自分の担当内の友達リストを受け取り、メッセージIDをそれらのキューに挿入する
  4. 正規化されたキューShard、長期保存用の長期アーカイブ(そのかわり取り出しは遅い)に保存する
つぶやきの一覧を作る
  1. ウェブShardはリクエストを受け取る。Joiner Shardにユーザのストリームを作るようにリクエストを送る
  2. Joiner Shardはデータを探すべきキューShardのリストをルックアップする。そしてつぶやきShardから実際のつぶやきを取得する。両方をまとめてウェブShardに返す
  3. つぶやきShardはリクエストされたつぶやきリストを返す

キューShardやつぶやきShardからデータが取れないときは、上記はもっと複雑になる。その場合には、長期保存用アーカイブにデータを見に行くことになる。

結論

これは複雑に見えるが、まあ複雑だ。しかしスケールするアプリケーションを作るという観点からすればかなり単純ともいえる(fav.or.itにはもっと複雑なところが多数ある)。twitterの人々は再設計が許されず徐々に動かしたまま改善しないといけないのでたいへんだろう。幸運を祈る。ところで-よかったら http://www.twitter.com/nickhalstead にフォローするといいかもよ。


[追記 2008.06.09] きたきた。期待してます。