BT

最新技術を追い求めるデベロッパのための情報コミュニティ

寄稿

Topics

地域を選ぶ

InfoQ ホームページ ニュース Redditで学んだ7つのこと

Redditで学んだ7つのこと

原文(投稿日:2010/05/18)へのリンク

Redditの共同創業者であるSteve Huffman氏は、Redditを小さなWebアプリケーションから巨大なソーシャルWebサイトへとスケールする過程で学んだ教訓を公開した。

RedditはSteve Huffman氏とAlexis Ohanian氏によって、2005年に開始されたサービスだ。サービス開始当初は、Webアプリケーション、アプリケーションサーバ、データベースがすべて1台のマシンで動いていた。やがてRedditは、7.5Mユーザ/月、270Mページビュー/月まで成長した。Huffman氏はここに至るまでにどんなことを学んだかをプレゼンテーションにまとめ、これまでやってきた数々の間違いと、それらをどのように正してきたのかについて語った。

1. 頻繁なクラッシュ

Redditはサービス開始当初から頻繁にクラッシュした。Huffman氏は寝るときにもノートPCを枕元に置いて、数時間おきに起きてはWebサイトが動いているか確認していたそうだ。ここで見つけた解決策は、Superviseを使うことだった。これはクラッシュしたアプリケーションを再起動してくれるデーモンだ。これを使うことで、アプリケーションの動作とその設計は興味深いものになった。つまり、アプリにメモリリークがあったり、メモリを使い過ぎると、単にアプリを殺して、最初から再起動したのだ。これは最終的な解決策ではないが、ログファイルを調べてアプリケーションを修正するまでの一時的な解決策になった。

2. サービスの分離

Huffman氏は、リソースを消費するたびにコンテキストスイッチが起こるのを避けるため、似たようなプロセスをひとつのマシンあるいはマシンのグループにまとめるよう提案している。また、インデックスキャッシュがたえずスワップするのを避けるため、似たような種類のデータにはひとつのデータベース用マシンを使い、異なる種類のデータは別のマシンに移すのがすぐれたプラクティスだと考えている。

またHuffman氏は、Pythonにおけるスレッドは「危険な行為であり、遅延をもたらすもの」だとして、利用を避けるよう強く提案している。各種タスクをスレッドではなく個別のプロセスに割り当てておくと、需要が増えて追加のリソースが必要になったときに、そのプロセスを別のマシンに移動させやすくなる。唯一の問題はプロセス間通信が必要になることだが、その代わりに、アーキテクチャはスムーズにスケールできるようになるので、こちらの方が望ましい。

3. オープンなスキーマ 

どんな新機能を追加するのにもスキーマの更新が必要だったが、DBが大きくなるにつれて、これは骨の折れる作業になる。1000万行のテーブルに新しい列をひとつ追加するのは、かなり時間がかかる。バックアップコピーやレプリケーションコピーがあればなおさらだ。当時はレプリケーションを構築していたので、バックアップせずに動かしている時期もあった。

解決策となったのは、オープンなスキーマやエンティティ属性値、キー・バリュー型ストアを使うことだった。今ではデータタイプごとに2つのテーブルがある。

image

ThingはUser、Link、Commentなどになるもので、すべて同一のスキーマを共有している。Dataテーブルは膨大な行から構成されるが、列にはID、Key、Valueの3つしかない。この新しいスキーマを使うことにより、新機能を追加してもスキーマを変更する必要はなくなり、新たなテーブルを作る必要もなくなった。また、もはやDB内での結合がなくなったので、簡単にDBを分散させることができる。

4. ステートレスを維持する

すべてのWebアプリケーションの目標は、アプリサーバがリクエストをすべて処理することだ。これはマシンが1台しかないときには(明らかに)非常に簡単だ。しかし、複数のサーバとキャッシュされたアプリケーション状態を扱うようになると、複雑になってくる。サーバが追加されるたびに、キャッシュの冗長性は増し、キャッシュされたデータにアクセスする際の難しさも増すためだ。

この場合の解決策は、memcacheに切り替えて、すべてのアプリサーバで状態を扱うのをやめることだった。直接のメリットのひとつは、ひとつのアプリケーションサーバがクラッシュしても、他のサーバには影響を及ぼさないことだ。また、サーバを追加するだけで、簡単にスケールすることができる。

リソース競合を避けるためには、キャッシュサーバを他のサーバから分離しておくことが重要だ。

5. あらゆるものにMemcacheを使う

Redditでは、データベースデータ、セッションデータ、レンダリングされたページ、記憶された内部関数、事前に計算したページ、グローバルロックなど、あらゆるものにmemcacheを使うようになった。また、データ永続性にはmemcachedbを使った。

6. 冗長なデータを格納する

「必要になるまでデータを正規化したままにする」と遅延をもたらすことになる。ユーザが特定のフォーマットでデータを表示する必要があるときに、生のデータを取り出してその場で処理しようとすると、レスポンスが遅れてしまいユーザは待ちきれないかもしれない。解決策となるのは、データを表示するのに使われるすべてのフォーマットをメモリやディスクに格納しておくことだ。このアプローチはディスクやメモリにいくらか影響を与えるが、ユーザのリクエストに対してすばやくレスポンスできるという利点がある。

Redditにとって、スピードの鍵となるのは「すべてを事前に計算しておき、それをmemcacheにダンプしておく」ことだ。

7. 裏で動かす

ユーザがリクエストをすると、システムは適切なレスポンスを返すために絶対に必要なことを実行しなくてはならない。それ以外のジョブはすべて、優先度を落として、裏で実行するためのキューに入れられる。裏でやる作業としては、例えば、リストの事前計算、サムネールの取得、不正の検出、スパムの削除、アウォードの計算、検索インデックスの更新などがある。ユーザがリンクに投票したときも、すべてのインデックスとリストが更新されるのをユーザが待つ必要はない。そうしたタスクはレスポンスがユーザに返された後に実行されることになる。

次の図の青い矢印は、ユーザのリクエストによって実行されるアクティビティを示している。ピンクの矢印は、裏で実行されるアクティビティを示している。

image

この記事に星をつける

おすすめ度
スタイル

BT