高可用の設計は故障個所毎に
MongoDBに限らず、システムの高可用構成を設計をする場合にキーとなる考え方は「故障箇所毎に処理を継続できる設計を考える」です。故障個所は様々ですが、データベースシステムを考える際は、プロセス、ストレージ、サーバ、サーバ間ネットワークなどを考えることが多いです。
MongoDBにおいては、mongodプロセスがストレージを管理していますので、両方を同一とみなせます。よって、故障個所として想定するのは各プロセス、サーバ、ネットワーク、データセンタの4つを考えれば十分でしょう。順に説明していきます。
プロセスの故障を想定した高可用構成
MongoDBにはmognodの他にもmongosルータと設定サーバという3種類のプロセスがあります。それぞれのプロセスをどのように高可用構成にするかを以下の表にまとめます。
プロセス | 高可用構成 |
mongosルータ | 複数起動 |
mongod | レプリケーション |
設定サーバ | レプリケーション(バージョン3.0以前はミラーリング) |
はじめにmongosルータですが、mongosルータはそれ自身が状態を保持しないプロセスなので、もしmongosルータのプロセスが故障したとしても、新しいプロセスを立ち上げれば元に戻ります。そのため、高可用構成を取るには、複数のプロセスを起動してあげればよいです。
次にmongodですが、これはレプリケーションを用いて高可用構成をとります。レプリケーションでは複数のプロセスがデータを複製して持ち合いますので、一つのプロセスが故障しても他のプロセスで処理を継続できます。ただし、プライマリのプロセスが故障すると、新しいプライマリが選出されるまでの間、書き込みができなくなります。MongoDB 3.2になり、プライマリ選出までの時間は短くなりましたが、ゼロではありません。もしも、完全に書き込みを止めたくないのであれば、MongoDB以外のマルチマスタレプリケーションを採用しているデータベース(例えばCassandraやCouchbase Server)を検討してください。
最後に設定サーバですが、バージョン3.2からはレプリケーションを用いて高可用構成をとります。プライマリの設定サーバプロセスが故障した場合は、一時的にシャーディングに関する情報の更新ができなくなります。具体的な影響としては、チャンク移動やチャンク分割ができなくなるだけであり、アプリケーションからのクエリ処理には影響がありません。また、バージョン3.0以前は2フェーズコミットを用いて完全に3台の情報が一致するミラーリング構成であったため、アーキテクチャに違いがあることを知っておく必要があります。
このような構成を取ることにより、どのプロセスが故障しても100%の読み取り可用性と高い書き込み可用性を、維持することができます。
サーバの故障を想定した高可用構成
プロセスごとの高可用構成を理解したところで、それを実際にサーバ上にどのように配置するとサーバの故障にも対応できるのかを、説明していきましょう。
以下の図に典型的なプロセスの配置図を掲載します。
まずmongosルータについてですが、mognosルータは何個立ててもよく、状態を維持しないステートレスなプロセスであるため、同じくステートレスなアプリケーションが動作するサーバに同居させ、スケールアウトさせるのが一般的です。そしてアプリケーションに対する負荷分散をロードバランサなどで行います。この構成であれば、どのサーバが故障しても処理は継続できます。また、アプリケーションの負荷が上がってきた場合は、アプリケーションとmongosの組み合わせでスケールアウトさせてあげれば、負荷分散をすることができます。
注意として、mongosルータとmongodの間にはロードバランサは置いてはいけません。その理由は、mongosルータに負荷分散の機能がついているためと、mongosルータがmongodと常駐コネクションを張るためです。
次に設定サーバですが、設定サーバはシャーディングの構成情報を管理するだけの軽量プロセスなので、mongodと同居させてやるのが一般的です。わざわざ設定サーバのために専用のサーバを用意する必要はありません。それに、mongodと同居させてもシステム全体の可用性は変わりません。