パスワードを忘れた? アカウント作成
167218 journal

taro-nishinoの日記: 非リレーショナルデータベースを選ぶ(私達がMySQLからMongoDBへ移行した理由)

日記 by taro-nishino

先日のYuval Kogman氏のエッセイ″Why I don't use CouchDB″の私家版和訳(私は略して私訳と呼んでいます)が私の周辺のCouchDBファンに冷や水を浴びせたようです。どうも誤解もあるようで、Yuval Kogman氏は頭からCouchDBを否定しているのではないのです。氏のような一流のPerler(いや、Perlerでなくても)は野心的である反面、非常に現実的です。ですから、現時点においてはCouchDBがかなりスピード面で劣るのであるから、それを補って余りある野心的な(現にロードマップに載せていますよね)フィーチャーを早く見せなさいと、氏は言っているのです。これは叱咤激励でもあると思います。
私はたまたまMongoDBを選びましたが、夢を持ちたい人はCouchDBを選べばいいし、もっと現実路線の人は他のNoSQLデータベースを選べばいいのです。
そんなことよりも、実際問題として、平均的な人々が持っている先入観、NoSQLデータベースへの抵抗の方が余程難題だと私は思います。実際、PerlのMongoDBドライバのメンテナであるKristina Chodorow女史のブログを読むと、Twitterでネガティブに毎日さえずられているそうです。例えば「何という馬鹿がnosqlを思い付いたんだ?」、「nosqlは、人が40年前にした間違いと同じことをしている...リレーショナルは完全に勝った」、「やぁ、nosqlを使えよ...データ全てを失うことに平気ならね」とか。
近年のアジャイルの傾向から言っても、RDBMSがほぼマッチしなくなっていることも人々は感じているはずなんですが、平均的な人というものは元来保守的です。私個人の意見ですが、ここ30年前後に見られる、プログラミング方法論がどうのこうの、プログラミング言語がどうのこうの、ソフトウェア管理技法等がどうのこうのは瑣末的なことであって、最も根源であるデータベース技術に革新が無い限り、ソフトウェアの実質的進歩は無いと思っています。後世、瑣末的なことばかりやっていて不毛の時代だったと記録されるかも知れません。1970年代にCodd博士がリレーショナルモデルを提唱して以降、本当に革新的なことがあったかと私も思います。極端な話が、データベース屋が失職するくらいに、手頃でフレキシブル且つユーザフレンドリーな、そして硬くない(今のRDBMSってハード顔負けの硬さを持ち合わせているように感じます)ものがあれば、それ以外のソフトウェアはどうにでもなります。
非常に前置きが長くなりました。珍しく知人より″Choosing a non-relational database; why we migrated from MySQL to MongoDB″を読みたいとリクエストがありましたので、その私訳を以下に載せておきます。あまり面白い記事ではないのですが、RDBMSよりNoSQLへ移行した実例ですね。

非リレーショナルデータベースを選ぶ(私達がMySQLからMongoDBへ移行した理由)
2009年7月25日 David Mytton

最近まで、私達のサーバモニターリングアプリケーションServer DensityはバックエンドとしてMySQLを使って動いていた。私達は主にホスティングサービスとして提供しているけれども、自前のサーバにインストールしたい顧客用にスタンドアロンとして動くように書いてきている。これは、各顧客が自身でMySQLデータベースを持っていたことを意味する。

私達は多くのデータを集める。すなわち、モニタリングエージェントが60秒毎にレポートを返し、多様な統計(その内には、サーバスナップショットが、走っているプロセス毎に詳細なデータを集めているので、最大のデータを持つ)を含む。やがて、これが、モニタしているサーバごとに、一月のデータだけでさえ、データベース内で何百万行となる。

この膨大なデータにもかかわらず、パーフォーマンスは悪くなかった。私達はクエリとサーバを結果が迅速に返るようにチューン出来た。クエリの大部分が、最小数の読込み付きの、挿入である。まだ、キャッシングもしていない。スケーリング計画の段階になれば、最新の値はメモリに格納されるので、DBからの直接の読込みは無くなるだろう。

私達の遭遇した問題は管理運営だった。レプリケーションを使ってスケーリングしたかったが、MySQLが特に初期syncに追いつくのが厳しいことが分かった。そういうことで、バックアップが問題となったが、私達はそれを解決した。しかし、将来的には計画している通りに、多重クラスタリングされたサーバ上でMySQLのスケーリングは難しい。レプリケーションを通して(しかし、読込み重視のアプリケーションだけに実に適している)するか、MySQLのクラスタを使うかのどちらかである。クラスタは非常に良いように見えるが、私は幾つかの問題を読んだことがあり、私達のニーズに適しているか確信が持てなかった。

現在の流行は、非リレーショナルデータベース管理システム(non-RDBMS)またはスキーマレスデータベースとも知られる、key/valueストアを使うことである。そういうことで、私は可能なオプションについて幾らか調査をした。

異なるオプション
私達の要求は、ちゃんとしたアクセス・インターフェース、永続性ディスクベースのストレージ(大部分はメモリ内のみである)、良いコミュニティとドキュメントのある比較的に安定している製品だった。それに基づいて、私がレビューしたプロジェクトは以下である。

        ★Cassandra
        ★CouchDB
        ★Hypertable
        ★MongoDB
        ★Tokyo Cabinet
        ★Project Voldemort

各プロジェクトに対して、詳細な、良いブログ投稿が多くある。

私は遅延時間を最も重視していたので、例えばAmazon SimpleDBのような「クラウド」を考慮しなかった。

MongoDBを選んだ理由
私は実際のデータを使ってテストを行い、幾つかの理由のためMongoDBを選んだ。
        ★インストールが非常に易しい。
        ★PHPモジュールが使用可能である。
        ★マスターマスタを含んで、レプリケーションが非常に易しい。これは、テストの際、私達の生DBを素早く、何の問題なくsyncに対応するであろう。
        ★自動シェアディングが開発されている。
        ★良いドキュメント

実装の詳細
リレーショナルから非リレーショナルへの切替えは時間のかかることであるが、難しくない。そうは言っても、必ずしも望んでいない違いがある。これらの幾つかはMongoDB特有だが、幾つかは一般的にも適用されるだろう。

スキーマレス
これは、将来の構造変更に対してずっとフレキシブルであることを意味するが、すべての行がフィールド名を記録することも意味する。私達は、例えばtimeAddedまたはvalueCachedのような、比較的長く、記述的な名前をMySQLで持っていた。少数の行なら、この余分なストレージが行につき数バイトだけだが、1千万行でフィールド名にもしかして100バイト付くなら、不必要にディスクスペースを食う。100 * 10,000,000 = ~900MBがフィールド名のためなのだ!

私達は名前を2-3文字列に削減した。これはコード上で少し混乱となるが、ディスクストレージ節約のためにはする価値がある。大文字小文字を区別する名前を使うならそれ程悪くない。例えば、timeAddedからtAのような。フィールド名に対して、10,000,000行の行につき約15バイトの削減は、~140Mバイトを意味し、大変な節約である。

カストマ毎のデータベース手法が動かない
MongoDBはバイナリストレージオブジェクトを使ってデータをフラットファイル内に格納する。これは、データストレージが非常にコンパクトで効率良く、高度なデータボリュームのためには完全であることを意味する。しかし、データベース毎にファイルのセットを占有し、スピードのためファイルシステム上でそれらのファイルを予め占有する。
(訳注:以下の引用は原文ではどこからのものか明記されていないのですが、ここからの引用です。)

各データファイルは与えられたサイズで予め占有される。(これは、他の理由のうちで、ファイルシステムのフラグメンテーションを阻止するためである。)データベースに対して最初のファイルは.0、そして.1などと続く。2GBとなるまで、.0は64MB、.1は128MBなどと続く。サイズがいったん2GBとなれば、続く各ファイルもまた2GBである。
従って、最新のデータファイルが例えば1GBとするなら、そのファイルが最近の到達で90%が空かも知れない。

これは、MongoDBが頻繁に前もって占有するので、データが別のファイルに「拡がる」ことが殆ど無い又は別のファイルのちっぽけな量である時には問題だった。これは、私達が一月後にデータをクリアするフリーアカウントが好例である。そんな先取り占有は、ディスクスペースを使い果たす大きな総量の原因となった。

従って、私達は単一のDBを持つためにデータ構造を変更し、その結果、使用可能なストレージを最も効率的にした。テーブル毎にシングルファイルを使うMySQLと違い、ファイルが別れるからと言ってパフォーマンスの打撃は無い。

予期していないロッキングとブロッキング
MongoDBでは、行をロックし、全データベースをブロックして、削除する。インデックスを追加することもまた同じことをする。私達はデータをインポートした時、インデックスが完了するまでの幾らかの時間の間、大きなデータセットがロックを存在させる要因となったので、このことが問題となった。「collection」(MySQLでのテーブルに相当する)を最初に作る時には、行が少し(又は全く無い)あるからと言って問題にはならないが、後でインデックスを作る時に問題を引き起こす原因となるだろう。

以前のMySQLでは、私達はWHERE句を広く適用して、例えばデータ範囲またはサーバIDによる行を削除するだろう。今やMongoDBでは、全行をループし、個々に削除しなければならない。これはより遅いが、ロッキング問題を防げる。

データ破損
MySQLでは、データベース(と言うより、幾つかのテーブル)が破損になれば、個別に修繕出来る。MongoDBでは、データベースレベルでの修繕をしなければならない。これをするためのコマンドがあるが、それはデータを全て読み、それを新しいファイルのセットに書き直す。これは全てのデータがチェックされ、ファイルがコンパクトになるのでディスクスペースを解放すること意味するが、その間、全データベースがロックされブロックされることも意味する。60GBのデータベースであれば、この操作は非常に時間がかかる。

オペレーションの最中に、データベースのプロセスを殺すとデータ破損が起こるであろう。

パフォーマンス
私達がMongoDBへ移行した理由はパフォーマンスではないが、多くの場合に、クエリ時間がMySQLよりも断然に速いことが分かってきている。これはMnogoDBが可能な限りデータをRAMに格納するからであるが、それがキャッシュされるデータのためのmemcachedと同様に速くなっている。キャッシュされないデータでさえも素晴らしく速い。

私達は詳細な数字を持っていないが、幾つかの場合において、キャッシュされたクエリは約7ミリ秒であり、キャッシュされない時にクエリに応じて約50-200ミリ秒を見ている。多くの場合インデックスはクエリのスピードアップを助けるが、書込みが集中する場合は、インデックスは遅くなり得る。

PHPのCネイティブモジュールもパフォーマンスを助け、コードレベルでインタラクション全体が最適化されていることを意味する。Python、Java、Ruby、C++、Perlのための他のドライバも使用可能である。

コミュニティまたは商用サポート
MongoDBはオープンソースだが、ニューヨークの会社10genによって開発されている。開発が続けられ、バグフィックスされることを安心出来るので、このことは有用である。実際、移行の間、メーリングリストは私達にとって非常に役立っている。ドキュメントは良いが、はっきりしない又は文書化されていない事柄がまだある。数時間以内に開発者からメーリングリストの回答を得られることは非常に役立つ。

MongoDBはMySQLのようなものと比べて全く新しいプロジェクトであり、コミュニティには経験者が少ない。そういうことで、私達は問題があれば、至急に助けを得られるように、10genとサポート契約、休日なしの電話且つメール対応をも結んでいる。

テストし、何がアプリケーションにとっていいのか選びなさい
FriendFeedの人はMySQLを使っているし、私達よりもデータ量が多い。しかし、彼等はkey/valueストアのように使用していて、アクセス率が違う。アプリケーションはすべて異なるのである。MySQLがFriendfeedに適する一方で、私達はより良い解決を見つけた。ニーズの適合性を相互にテストする必要がある。
実際、Server Densityは完全にMongoDB上で動いている一方で、私達のアカウントシステム、インボイスと請求書作成はMySQLのままである。MnogoDBはアトミックでない(訳注:これはちょっと筆者の認識不足だと私は思います。正確にはアトミックにしようとすれば出来ます)。これは私達の一般的なアプリケーションには問題にならない。つまり、少数行しか書き込まれないならクリティカルではない。しかし、これは私達の請求書作成システムではそうではない。すべてが正しいことを保証するにはトランザクションを使う(例えば、顧客にだぶって請求したくない)。そのために、MySQL InnoDBをなおも使っている。
私達のMongoDBへの移行は面白く、問題にも出会っている。しかし、回避出来なかったことは何も無い。パフォーマンスは増し、ディスク使用量は減り、私達はスケーリング計画を続行する絶好の位置にいる。

この議論は賞味期限が切れたので、アーカイブ化されています。 新たにコメントを付けることはできません。
typodupeerror

計算機科学者とは、壊れていないものを修理する人々のことである

読み込み中...