foursquareの11時間にも及ぶサービスダウンの原因を詳細に調査してみた。blogスマートフォン用の表示で見るスターをつけました引用をストックしましたストック一覧を見る閉じる引用するにはまずログインしてくださいログイン閉じる引用をストックできませんでした。再度お試しください閉じる限定公開記事のため引用できません。blog2010-10-14foursquareの11時間にも及ぶサービスダウンの原因を詳細に調査してみた。titMongoDBこんにちは、@doryokujinです。前回に引き続き、MongoDBに関するエントリーです。今回は10月4日にMongoDBが原因で起きた、foursquareのサービスダウンに関して、その原因や復旧に至る経緯を詳細に調査しました。TechCrunchJapanの記事、Foursquare:「対策を講じたはずなのですが、また6時間もダウンしてしまいました」にも紹介されていたのでご存知の方も多いと思います。MongoDBが原因で引き起こったとするならば、企業で実際に運用している僕にとっては放っておけない問題になります。実は5月にも長いサービスダウンがあったのですが、それはAmazonEC2の停電によるものでした。本質的な原因はどこにあったのか復旧後の状況foursquareの行なった対策についてfoursquareにおけるMongoDBfoursquareのサービスにはScalaの言語が用いられ、WebフレームワークであるLiftを使用して作られています。61.5万回のチェックインが行われています。これまでに5000万回のチェックインが行われました(2010年5月時点)。8月末の時点で会員数は300万人を超えたとロサンゼルス・タイムズのインタビューの中で報じられています。チェックインの情報を保存しておくデータベースとして現在はMongoDBが使われています。元は1台のPostgreSQLインスタンスをデータストアとして使用していましたが、急速のサービス拡大に伴ってMongoDBに切り替えた経緯があります。切り替えた理由は主にスケールアップ(レプリケーションとシャーディング)の観点で、MongoDBの方がSQLデータベースよりもはるかに容易に導入・管理できるからと考えたためです。この機能が使えるMongoDBのバージョンは1.6からなので、foursquareはバージョン1.6(最新)を使用しています。チェックイン・Tips、そして現在地の施設などにつける、Venueと呼ばれるマーカ情報(とそれに関するデータ)がMongoDBに書き込まれていきます。axes)に関するデータに対して特殊なインデックスを作成することができます。"2d"})と、インデックスを作成することで以下のようなクエリーでの検索が可能になります。1]}).limit(20)さらに多くの情報は公式ドキュメント日本語訳の地理空間のインデックスを参照してください。この1時間半の間に偏りをなくすためのバランシングを試みたがうまく機能しなかった。シャードの追加によっても1台のシャードのパフォーマンス低下が解決されなかったために、インデックスの再構築を行ない、メモリの断片化を修復することを決めた。5時間以上におよぶ再構築とバックアップ作業の後、サービスが復旧。幸いにもデータの損失などの障害は避けられた。この約11時間の間、foursquareのすべてのサービスは完全にダウンしてしまっていました。bummer.本当にMongoDB自体の問題だったのだろうかfoursquareのダウン時はまだデータベースの記録容量はまだ120GB程度でしかありませんでした。直近のレポートでは1日約100万チェックインが行われ、これは1秒当たり60チェックイン(=書き込み数)が行われたことになります。nodes)の構成で秒間10,000トランザクションをさばけたという報告があります。(Riakについてはこちらのスライドが参考になります。)なので、今回の問題はMongoDBの本質的な性能不足によるもの以上に、foursquareのMongoDBのデザインやトラブル対応に少し不備があったのではと考えるほうが自然になります。problemサービスダウンの引き金となった出来事foursqareではサービスダウン当時、AmazonEC2上で66GBのメモリを積んだ2台のマシンでシャーディング(データベースを分割することで負荷やディスク・メモリ容量を分散させる方法)を行なっていました。シャーディングはユーザーIDを元に行われていました。それまでの2ヶ月間の運用では、データは2台のサーバーに均等にうまく振り分けられていてどちらのシャードも約33GBのメモリを消費する程度で安定していました。片方のシャード(shard0とする)のメモリが物理限界の66GBをオーバーし、著しい性能低下を引き起こしたであったと報告されています。第3のシャードを追加することによってshard0から5%のチャンク(データの塊)を移行しようとしたが、その後もshard0のメモリ容量が減らず、状況が解決されなかったために、復旧に11時間もかかってしまいました。幸いにも一部のデータが失われるといった状況にはなりませんでした。mortem本質的な原因はどこにあったのかそれではこれに関する本質的な原因をMongoDBの特徴と絡めて詳しく見ていくことにします。前者に関しては、ユーザーIDをキーにした分割方法が適切でなかったが考えられます。ちなみにもう片方のサーバーのメモリ消費量は50GBでした。ユーザーIDを分割のキーとしていたために、片方のシャードに何度もチェックインを繰り返すヘビーユーザーが偏ってしまう振り分けになってしまっていたとしたら、このような状況になってしまう可能性があります。後者の原因にはMongoDBが密接に絡んでおり、インデックスに使用したメモリの断片化によってshard0の負荷を低減させることに手間取ったことが考えられます。foursquareが記録していたチェックインに関するレコードは1レコード当たり約300バイトでしかありませんでした。実はMongoDBでは4KB以下のレコードの集合に関しては、それが別のシャードに移動したり削除されたとしてもインデックス作成に使用された一部のメモリは開放ずに残ってしまう(断片化)状況が起こってしまうのです。foursquareの場合は、データが連続しているチャンクから効率よくデータを移行することができずにこの状況が起こってしまいました。(10gen)は以下のように述べています:シャードの条件に設定されたキーの振り分けが挿入順序で行われる場合ソースとなるシャード(ここではshard0)に高負荷がまだかかっていない状況時にシャードを追加した場合1つ1つのレコードが4kBより少し上回る程度の容量を持っている場合もしこれらの条件のすべてを満たしていない場合は、速やかにデフラグを行い、断片化の進行を防ぐ必要がある同サイトに、4kBより遥かに小さい大量のレコードで構成されたコレクションを作成して検証が行われています。このコレクションはインデックスに約300MBの容量を消費していましたが、このコレクションを削除したあとも2.3MBの容量を消費していることがわかります。このコレクションを作成しては削除するといった動作を繰り返すたびに、どんどん消費量が増えていっています。今回のケースでもこの断片化が引き起こされていたことが考えられます。他の2条件も満たしていなかったので、なかなか追加シャードへのデータの移行が進みませんでした。bug?復旧後の状況その後shard0の復旧が進み、また3番目のシャードに一部のデータの移行が完了したために、現在はデータが均等に振り分けられ安定に動作していると報告されています。MongoDBには全てのインデックスを再構築するためのrepairDatabase()コマンドがあり、これを実行したようです。このコマンドは、すべてのデータが壊れていなかチェックし、壊れているものがあった場合取り除きます。データファイルを少し縮小します。いうコマンド(すべてのインデックスの再生成)を実行して最適化した後、このスレーブをマスターに昇格させることで約20GBの消費に抑えたと報告されています。今回明確となったMongoDBのボトルネックは、現在10genの技術チームが解決に向けて取り組んでいるとのことです。参考(MongoDBのrepairコマンドについて):耐障害性と修復(公式ドキュメント邦訳)参考(MongoDBのインデックスについて):インデックス(公式ドキュメント邦訳)foursquareの行なった対策について今回11時間にも及ぶサービスダウンはユーザーに対しての信頼を損ねてしまう結果になってしまいましたが、やはり新しい技術を使用する以上はこのようなリスクは避けられないと思います。status.foursquare.comを新たに作成したより意味のあるエラーページを作成することにした。現在どのような状況でそれが起きているのかを詳細に記述するようにしたとしてすぐにサービスに反映しました。僕はこの一連のきちんとした対応には好感を持っています。この大きな出来事を元にMongoDBがより良いものに、そして他の企業この事例を学んで同じ状況が起こるのを回避できるようになっていくことを願っています。終わりに今回、様々な海外サイトを参考にさせていただきましたが、英語面・技術面ともにまだまだ未熟ですので訳や解釈の違いが多々あると思います、その場合はご指摘していただけると幸いです。今回はMongoDBの少しネガティブな部分を書きましたが、他にも色々とネガティブな部分があることがわかっています。MongoDBのメリット/デメリットという軸でそのうちエントリーが書けたらなと思っています。Outageまた、この日本語訳も公開されていますので参考にしてください。05:04foursquareの11時間にも及ぶサービスダウンの原因を詳細に調査してみた。blogのメイントピックをトレジャーデータ日本語公式ブログへ移設しました。Blog|ブログを報告する。