MongoDBが適さないケース
> 原文(Why MongoDB is a bad choice for storing our scraped data)
私自身はMongoDBを推進する立場なのだが、確かにMongoDBに適さないケースはある。
闇雲に推進しても結局は全員がアンハッピーになるので、この様なネタもどんどん紹介していこうと思う。
この記事はMongoDBを徹底的に使い尽くしたエンジニアが書いている様で状況が良く解った。
ちょっと難しい所もあるので要点を意訳して、軽く解説を書いてみる。
(もちろん是非原文で読むのをお勧めする)
状況
最初はMongoDBでうまく動いていたが、だんだん苦労が増えてきて
元々のアーキテクチャを刷新するタイミングでMongoDBから別のプロダクトに乗り換える事にした。
システムの規模
詳しく書かれていないが、1ノード辺り数TBとあるのでSharding環境ではないかと思われる。
が、、この手のデータでShardingは難しいのでやってないかもしれない。
ドキュメント
色々なドキュメントを扱っていそうだが、メインは(階層構造が有り得る)小さなクロールログデータを大量に扱う。
データ構造は事前予測不能。
クエリー
PV単位での参照の様な短いクエリーと、ある程度時間を要するクエリー(一括export/delete,フィルタリング,ソートなど)がある。
問題
ロック
MongoDB 2.2以前はReaders-Writerロックなので、長いクエリーが走ったその瞬間から、短いクエリーもロックされる。
WebからのPVを捌く様なシステムの場合、一瞬でもロックが走れば、WEBサーバ上の全てワーカースレッドが潰されてサイトがダウンする。
この為、色々やった
ディスク領域が非効率
これはpaddingFactorの問題(MongoDB 2.4 の性能 徹底評価 - 全件(relocation)1カラムアップデート -でも触れている)をまともに食らったのだろう。
ドキュメントを事前予測できないならば仕方がない。
『ドキュメントを事前予測できない事』
これこそがMongoDBに適さない最大の理由だろう。
大量のデータベース
結果的に管理しきれない程の大量のデータベースを作る事になった。
またmongodをリスタートする際のチェック時間も膨大になった。
データをソート
大量のデータをソートして出力するのは非現実的だ。
MongoDBで順番を保持できるのは、capped collectionだけだが、これはクロールログには適さない。
実はかなり核心をついた部分だ
- #FF0000;">性能面:MongoDB 2.4 の性能 徹底評価(レコード長による評価)- シーケンシャルFETCH性能 -で述べたとおり、MongoDBは(特に小さなデータ程)シーケンシャルアクセスしないと性能が出ない
- #FF0000;">capped collection:性能面、ソートなどは解決できるがアップデート出来ないなど、使い難い
- #FF0000;">データ順序面:in-placeアップデートを保証できなければ入れた順番は保持されない
- #FF0000;">ソート:かといって大量データのソートは非現実的
しかしMongoDBに限らず殆どどんなシステムでも結局辛い。MongoDBはロック問題がこれを深刻にしていた(2.2以前)。
このソート問題、私ならPV系はインデックスに頼って、集計系はMongoHadoopで逃がすかもしれない。
Skip + Limitが遅い
そりゃ当然遅いよね・・・
カーソル処理とはいえ、大量の読み飛ばしはキツイ。
こんなの上手く処理できるシステムあるのか??
フィールド名の制限
MongoDBのフィールド名には、dot(.)とdollar($)が使えない。
私もついウッカリやってしまう
まとめ
MongoDBでクロールデータを扱っても巧く行くケースはある。実際我々は暫く使ってきた。
しかしココで述べた様に最早我々の要件には合わなくなった。
(最終的にはhBase Cassandraにした模様)
私自身の見解
同じくログデータはMongoDBでは扱わないだろう。
既に述べられてる事の中では特に、ソートの問題が厳しく、更に時系列データは根本的にShardingに向かない。
カラムベースのCassandraはこの辺りに確かに向いているので、私もそちらに一票。