最近、MongoDB に関して非常に好ましくない内容のかなり話題になった市場報告が2つあった。批判の大部分は、パフォーマンス問題とデータ損失の組合せに集中している。この話を続ける前に、これらは公式の事例研究でないことを肝に命じて欲しい。そうではなくて、最近 MongoDBを使った開発チームによる市場報告である。
まず Urban Airshipの Michael Schurter氏のレポートから始める。 Urban Airshipは既に、MongoDBの問題を経験しており、このレポートを書く前にデータのほとんどを PostgreSQLに移行を済ませていた。残ったデータはMongoDBにとって理想的のようだ。
- 短命-もしそれを失っても、短い間サービス低下を経験するが、 壊滅的ではない
- 小さい-容易にメモリーに収まる(~15 GB)
- 二次索引-キー/値のストアで二次索引をマニュアルで管理する必要がある
Schurter氏が引用した始めの問題は、MongoDBがプライマリサーバーで複数のコアを利用できないことである。16のコアが使えるのに、グローバルのライトロックが事実上、それらを1つのコアに制限していた。この制限に対処するために、彼らはサーバーで複数の mongodを使おうとした。mongod は、「個々のサーバー上で走る、プライマリ・データベースプロセス」である。複数のmongodを使うと shardingを伴うことになり、これがそれ自身で非常に複雑なものになる。この中には以下のものが含まれる。
- 正確に3つのmongod configサーバー
- 1つのアプリケーションサーバーに1つのmongosルーター
- Arbiterがレプリカ セットにつき最低3つ要る
- mongod自身
mongosルーターは、データをバランスするのに非常に効果的である。しかし、彼らは時々クラッシュを経験しており、10genは最近リリースされた v. 2.0.1では問題は修正されている、と信じている。氏が指摘するもう1つの問題は、「mongosインスタンスは多くのCPUを使うことができるが、各コアを非常に短時間、目一杯使うと、ランダムに飛んでしまうようです。」
mongodの問題は、新しいレプリカメンバーを持ち込む時で、ある一定期間すべてのライト操作をサスペンドしなければならないことだ。氏は、「1秒間に40回のアップデートで、新しいセットメンバーが RECOVERINGから SECONDARYにならないようにするのに充分だった。新しいメンバーをセットするのに全てのトラフィックを断つために、mongosをシャットダウンしなければならなかった。」と書いている。Javaクライアントに特有のバグがあるようで、mongodがリカバリモードにある間は、クライアントはいかなる操作も終えることができなかった。
氏は以下のように結論している。
今我々は、2つの専用サーバーに2 shardで動かしている。Mongosとconfigサーバーを他のサーバー上に分散している。いくらかのデータロスがあるようだ。 このデータセットの性質は短命で早く変化するので、特定するのが、すなわち独立に再現させるのが非常に難しい。
なので、我々は MongoDB からこのデータセットにもっと相性のいいカスタムサービスに移行しようとしている。
2つ目の市場報告は、匿名者からのもので、MongoDBを使うなという題である。報告者は、「何千万のユーザー」がいる「知名度の高い会社」で大規模なデータにMongoDBを使っていた、と言う。もしこれが本当なら、報告者が匿名でいたい、と言うのは確かに納得のいくことである。尚、我々もこの報告が Schurter氏の報告と関連していなかったらここで報告することはなかった。
最初の問題はよく知られている。 MongoDBの既定の設定は、非同期ライトである。ほとんどの人々は、ライト操作が成功したかどうか分からないことから直ぐに派生する問題について知っている。この人が言っているもっと厄介な問題は、いつライト操作が終わったのか知る方法がないことである。もしコネクションプーリングを使っていれば、コミットされる前に情報を読もうとすることになるかもしれない。
データロスは報告者にとって深刻な問題である。彼はデータの失われ方を以下のように言っている。
我々が個人的に経験したレコードの失われ方をリストすると、
- 単に時々消える。原因不明。
- 化けたデータベースの復元は成功しない、プレ トランザクションログ。
- マスターとスレーブ間の複製には、oplog中に「ギャップ」があり、マスターにあるレコードがスレーブにない原因である。チェックサムが無いし、複製のステータスがスレーブを最新としている。
- 複製がエラー無しで時々単に止まる。複製のステータスを監視する!
Schurter氏のように、 MongoDBのグローバルライトロックが起因の問題についても話している。彼はまた、運用中のシステムにshardを追加するのに問題があった。「高負荷の下で shardを追加するのは悪夢だ。 Mongoは、shard間でchunkを非常に速く動かすので、すごいトラフィックを生成するか、もっとchunkを一緒にするのを拒否する。」
Monogosの信頼性が再び取り上げられている。
mongod/config サーバー/mongosのアーキテクチャは実際非常に理にかなっており、巧妙です。不幸にして、mongosは完全にゴミです。負荷があると、数時間ないし数日毎にどこかでクラッシュします。リスタート管理も必ずしもb/cに役立たず、時々クリティカルなスレッドを救う、あるアサーションを投げるが、そのプロセスは走り続けています。二重に失敗しています。
非常に困ったので、我々が見つけた唯一の使用可能な方法は、数十の mongosインスタンスの前でHAproxyを走らせ、それらの間でゆっくりジョブを回して、それらをkillしてプール中のインスタンスをフレッシュに保つことです。これは冗談ではありません。
レプリカセットが時々間違ったノードを選び、大量のデータロスの原因になる、古い1.6のバグについて語ってから、報告者はビジーなサーバー上のレプリケーションの問題を挙げている。
レプリケーションはしばしば、マスターをDOSするか、複製が非常に遅いので、余りに時間がかかるし、oplogが枯渇する(50Gのoplogでも)。
我々のデータセットは、ビジーで大きいので、簡単にこの動的なb/cを複製できませんでした。他のデータベースシステムに移るまでは、祈るだけの非常に苦痛な1、2ヶ月でした。
報告者は 10genがデータロスを防ぎ、可用性を保証するよりも「リソース当たりの生のリクエスト処理効率」に重きを置いているからだ、と結論づけ、非難している。
10genからの返答
10genのCTOであるEliot Horowitz氏は、時間をかけて匿名の報告でまとめられている苦情に答えた。
まず、私は我々の顧客の中で、このような報告歴があるか探そうとしましたが、ありませんでした。私は自分で、全顧客から報告されたすべてのクレーム(約1600件)に眼を通しましたが、この話と一致するものはありませんでした。どこからの情報なのか困惑していますので、あるケースに関しては応えることができません。
最初の4つのデータロスに関して彼は以下のように回答している。
- 我々が直ぐに修正できるバグか、他の環境的な問題へトレースできないようなレコード消失が起きたケースはこれまでありません。もしあなたがケース番号を教えてくれれば、我々は少なくとも何が起きたのか理解、あるいは説明しようとすることができます。明らかにこのようなケースは著しく深刻です。もし起きたなら我々に話して欲しかったし、そうしてくれたら、我々は理解ができ、直ぐに修正できたでしょう。
- これは予想通りで、修正は一般に、それ自身ジャーナリング無しでは推奨できないシングルサーバー用です。もし secondaryがジャーナリング無しでクラッシュしたら、primaryと再シンクすべきです。ちなみに、ジャーナリングは既定で、 v2.0でほとんどいつも使われています。
- ケース番号を持ってますか?これが起きたようなケースが見当たりません。しかしもし本当なら、これは重大なバグです。
- もしあなたがクライアントへエラーを出さずに、エラー状態が起きる、という意味であるなら、そうです。可能性があります。もしあなたがレプリケーションがライト時に動いていることを確かめたければ、 getLastErrorのパラメータ w=2で試すことができます。
氏は、一旦 MongoDBシステムがデータ容量一杯に達するとshardを追加できなくなる、と認めそして、そうしたのは、グローバルライトロックの影響を軽減するためだ、と言った。
残りの問題に関しては、氏はこれまで聞いたことがなく、もっと詳細を知りたい、と言った。彼はまた、欠陥トラッキングシステムは、誰でも見えることを強調した。
人気サイトの Foursquareのエンジニアである、というユーザー “harryh”は彼を支持している。
約1年半前に、同僚と私は、プライマリデータストアを MongoDBに移行する決定をしました。現在何十もの MongoDBインスタンスがいくつもの様々なクラスタ中にあり、テラバイト以上のデータを保存し、1秒に数万のリクエストを処理しています(ほとんどがリードで、ライト負荷もそこそこに高いです)。
匿名報告者からフォローアップ
いくつかは、また(かなり)疑わしい「なぜ匿名なのか?」と「どこに証拠があるのか?」のことである。
これら2つのことは関連しています。私は身元を明かさずに証拠を提供することはできません。なぜ匿名か、というと幾つかの小さなデータベースが今も、 10genのものでサポート契約がまだあります。システム全体を移してからこれら全てを公開するつもりでしたが、 MongoDBでトラブルのある人々からどんどん報告が上がってきています。まるで報告を遅らせることが分別のないように思えました。匿名の警告のほうが何も言わないより価値があるでしょう。