シャーディングの性能を考えるためには、まず仕組みを完全に理解している必要があります。そこで今回はシャーディングの仕組みを丁寧に解説し、次回シャーディングにおける性能の考え方やアンチパターンを紹介していきます。
本記事は中級編ですので、シャーディングの用語や動作概要はすでに理解しているものとして説明を行います。
シャーディングすべき時
本連載の冒頭でも伝えたとおり、MongoDBの大原則は「できるだけシャーディングしないこと」です。その理由はシャーディングが難しいためです。シャーディング構成は単体構成やレプリケーション構成と比較して遥かに複雑です。また性能を出すために入念な設計が必要です。加えてバックアップが困難になります。これはMongoDBに限った話ではなく、どんなDBMSでもシャーディングは難しいチャレンジングな機能です。
そのため、多くのMongoDBユーザはシャーディングは行っていません。私は多くのMongoDBユーザを知っていますが、シャーディングを行っているユースケースの殆どはインターネットにシステムを公開して大量のクエリを受付けています。目安としては秒間5000件以上のクエリがあるシステムと思っておけばよいでしょう。
どうですか?皆さんの担当するシステムはそれほどの負荷はありますか?もし当てはまらないのであれば、シャーディングをするのではなく、この連載でこれまでに紹介してきた性能の考え方を参考にして、今ある構成で最大まで性能を出してください。それをしてもなお性能が足りない場合に、初めてシャーディングを検討してください。
シャーディングの構成要素
まずシャーディングを構成する設定サーバ、mongosルータ、シャードについてその仕組みについて正確に理解しましょう。
設定サーバは特別なmongodです。主にチャンクの定義とそれを格納するシャード情報を格納します。加えてmongosが用いるロックも格納します。設定サーバのデータが失われるとシャーディングは機能しないため、3台構成の場合はレプリケーションではなく2フェーズコミットにより一貫性をもった書き込みが行われます。
mongosルータは設定サーバのデータをメモリにロードして動作する軽量プロセスです。主にクエリの割り振りを行い、他にもチャンク分割やチャンク移動も指揮します。メモリ上のみの存在であり動作に必要なデータは全て設定サーバに格納します。何個設置してもよく、アプリケーションが動作しているホストで一緒に動作させるのが一般的です。
シャードはデータ格納と処理の実態です。単一mongodかレプリカセットをシャードにすることができます。理解を深めるポイントは、シャードを構成する各mongodは自分がシャーディング構成の一部だという事をほとんど意識していないという点です。クエリはmongosが割り振ってくれるのでそれに応答するだけです。インデックスは各mongodが独自に管理しており、シャーディング全体にまたがるインデックスというものはありません。チャンク移動の際はmongosの指示に従ってデータを削除・追加するだけです。その証拠にmongodを起動する時にシャーディング用に特別必要なオプションはありません。
--shardsvrというオプションを付けている文献がありますが、このオプションはデフォルトのポート番号を27018に変えるだけで、他に意味はありません。