SoftLayerでMongoDB環境を構築してみよう
[PR]
MongoDBはMongoDB Inc.という会社が中心となって開発しているオープンソースのデータベース管理システムです。NoSQLと呼ばれるデータベースの中でも、特にドキュメント指向データベースといわれるものです。
さまざまに特徴はありますが:
- JSON的な階層型データをどんどんと押し込める動的スキーマ
- インデキシングや豊富なクエリーといったアプリケーションから使いやすい豊富な機能
- シンプルな考え方で高可用性やバックアップなどを実現できるレプリカセット
- データサイズやアクセス数が増えたときに水平スケールで容易にパフォーマンスアップ可能なオートシャーディング
といったところがよく挙げられるところでしょうか。
筆者としては、アプリケーションの作りやすさと、可用性をカンタンに担保できるレプリカセットは、やはりMongoDBのわかりやすい嬉しさだと思います。ということで、MongoDBのレプリカセットをSoftLayer上に構築してみましょう。
レプリカセットとは
MongoDBのレプリカセットというのは、MongoDBが標準で採用しているレプリケーションの仕組みです。検索すれば沢山の解説ページが出てくるので詳しくは省略しますが:
- 通常3台のノードから構成
- 書き込みはプライマリノードに対して行い、複数のセカンダリノードに自動的にレプリケーション
- 原則はプライマリノードから読み書きすることでConsistency(データの整合性)を担保するが、負荷分散やレイテンシーを考慮して明示的にセカンダリノードからデータを読むことができる(Eventual Consistency)
- あるノードがダウンしたときでも2ノードで暫定的に動きつづけることが可能 ・プライマリノードがダウンした場合でも、セカンダリノードの一つが自動的にプライマリノードに昇格しサービス継続できる
といった、いろいろ美味しいことがあります。
SoftLayerではノード間の通信は内部ネットワークになり、拠点間のネットワークも回線が太いので、レプリカセットのノードの一部を国外のデータセンターに配置してディザスタ・リカバリ対策にする、といったときにも威力を発揮できると思います。
MongoDBのインストール方法の選択
SoftLayerにMongoDBをインストールする方法として、ぱっと思いつくのは次の方法でしょうか。
- SoftLayerのサーバーデプロイ時にデータベースオプションで「MongoDB」を選ぶ
- デプロイ後にOS標準パッケージでインストールする
- デプロイ後にMongoDBで配布しているパッケージでインストールする
- MongoDB Management Service(MMS)でインストールする
どれでやってもよいといえばそうなのですが、今回はSoftLayerならではのお気軽さということで、1.を選んでみましょう。
SoftLayerでサーバー払い出し
さきほど説明したとおり、レプリカセットは最低3台のノードが必要です。ついでに、アプリケーションサーバーを模したサーバーを1台用意します。ので、さくっと3台+1台のサーバーを振り出しましょう。
今回はお試しなので、構成としては一番安い仮想サーバーにします。
データセンター | 香港 |
---|---|
COMPUTING INSTANCE | 1x2.0GHz |
RAM | 1GB |
OPERATING SYSTEM | Ubuntu Linux 14.04 LTS Trusty Tahr - Minimal Install (64 bit) |
FIRST DISK | 25GB(SAN) |
DATABASE SOFTWARE | MongoDB Community Edition |
OSはWindows Serverでなければ大丈夫です(MongoDBの実体は実行ファイル一個だけなので、Windowsでも可能は可能なのですが、積極的に選ぶ理由はないです)。本番構成なら、SECOND DISKとしてSANのディスクをMongoDBのデータ格納用に別途確保するのがよいでしょう。
アプリケーションサーバーにはMongoDBはいらないのですが、別にデプロイするのが面倒という理由と、MongoDBのクライアントシェルが欲しいので入れてしまいます。
マシン名は仮にこんな感じにしましょう。
アプリケーションサーバー | app |
---|---|
MongoDB ノード1 | mongo1 |
MongoDB ノード2 | mongo2 |
MongoDB ノード3 | mongo3 |
構成としては次の図のようになります。
デプロイされたら基本的な設定をしておきましょう。アプリケーションサーバーappとMongoDBの3ノード間の通信はすべて内部ネットワークです。sshもappからするとして、app以外はufwなどでグローバルからのアクセスを拒否するとよいでしょう。
内部ネットワーク側については、MongoDBは基本27017ポートをLISTENするのでここは解放しましょう。またMongoDBはノード間の死活監視にpingを用いるので、ICMPも許可する必要があります。
本来なら、このあたりはProvisioning ScriptでやるのがSoftLayer流でしょうか。
MongoDB レプリカセットの構築
ではいよいよレプリカセットの構築です。app経由でmongo1にsshで接続しましょう。
まずは動いているmongodbをチェック。
$ mongo --version MongoDB shell version: 2.6.9 $ ps aux | grep mongo[d] mongodb 796 0.1 3.6 349760 36548 ? Ssl Apr02 1:46 /usr/bin/mongod --config /etc/mongod.conf
バージョン2.6.9が動いていて、設定ファイルは/etc/mongod.confの下にあるということがわかります。
ではレプリカセットに関する設定をします。
$ sudo vi /etc/mongod.conf
まずはlocalhost外からの接続ができるようにbind_ipの設定をコメントアウトし、
# Listen to local interface only. Comment out to listen on all interfaces. bind_ip = 127.0.0.1 ↓ # Listen to local interface only. Comment out to listen on all interfaces. #bind_ip = 127.0.0.1
レプリカセットの名前を指定します。ここでは「replSetSLDemo」にしましょう。
# Replication Options # in replicated mongo databases, specify the replica set name here #replSet=setname ↓ # Replication Options # in replicated mongo databases, specify the replica set name here replSet=replSetDLDemo
これでサービスを再起動しましょう。
$ sudo service mongod restart
同じ設定をmongod2、mongod3にも行ってください。これでMongoDBノードの設定はOKです。ではappに戻って、mongo1のMongoDBに接続しましょう。
$ mongo 〈mongo1のプライベートIP〉 >
mongoコマンドはMongoDBのシェルです。JavaScriptインタプリタが動いています。まずはレプリカセットに自分自身だけを追加しましょう。MongoDBシェルではあらゆる情報がJSON形式なので、設定もJSONで書きます。
> config = { _id: "replSetSLDemo", members: [{_id:0, host:"〈mongo1のプライベートIP〉"}] }
_idは先ほど設定ファイルに書いたレプリカセット名と同じにします。
この設定を使ってレプリカセットを初期化します。レプリカセット関係のコマンドはrs.で始まることになっていて、初期化はrs.initiate()です。
> rs.initiate(config) { "info" : "Config now saved locally. Should come online in about a minute.", "ok" : 1 }
ちょっと間をおいてエンターキーを叩いてみると、プロンプトが次のように変わるはずです。
replSetSLDemo:PRIMARY>
これは、「今つないでいるMongoDBノードは、レプリカセットreplSetSLDemoに所属している、プライマリノード」という意味です。レプリカセットの立ち上げに成功しました。
では残りのノードも追加しましょう。それにはrs.add()コマンドを使います。
replSetSLDemo:PRIMARY> rs.add("〈mongo2のプライベートIP〉") { "ok" : 1 } replSetSLDemo:PRIMARY> rs.add("〈mongo3のプライベートIP〉") { "ok" : 1 } replSetSLDemo:PRIMARY> rs.config() { "_id" : "replSetSLDemo", "version" : 3, "members" : [ { "_id" : 0, "host" : "〈mongo1のプライベートIP〉:27017" }, { "_id" : 1, "host" : "〈mongo2のプライベートIP〉:27017" }, { "_id" : 2, "host" : "〈mongo3のプライベートIP〉:27017" } ] }
これでレプリカセットの構築は終わりです。