MongoDB Enterprise Advanced:In-Memoryストレージエンジンを構築する
こんにちは、菊池です。
MongoDBの商用ライセンスであるMongoDB Enterprise Advanced、前回はインストール手順を紹介しました。
MongoDB Enterprise Advancedをインストールする
今回は、商用版のみの機能の1つである、In-Memoryストレージエンジンの構築について紹介します。
In-Memoryストレージエンジン
In-Memoryストレージエンジンは、その名の通り、メモリ内にデータを保持することで高速なクエリパフォーマンスを実現します。MongoDB Enterpriseのバージョン3.2.6以降で利用可能です。
メモリにデータを保持するため、そのインスタンスでは永続化されず、mongodプロセスが再起動すると書き込まれた全てのデータは消えてしまいます。そのため、単体ではキャッシュなどの一時的なデータの格納に利用するのが適しています。
永続化が必要なデータの保管にはレプリカセットを利用することで、データを保全しつつ、高パフォーマンスな環境の構築が可能です。MongoDBでは異なるストレージエンジンを組み合わせてレプリカセットを構成できます。アプリケーションからのアクセスをIn-Memoryストレージエンジンのノートで処理し、データの永続化のためにWiredTigerストレージエンジンを使うことで、In-Memoryのパフォーマンスを提供しつつ、データの永続化が可能になります。
WiredTigerのノードはHiddenとして指定することで、クライアントからはアクセスされない状態とすることができます。今回はこの構成で構築します。なお、レプリカセットの構成パターンは以下を合わせて参照ください。
構築手順
それでは、In-Memoryのレプリカセット環境を構築していきます。
前提環境
- OS:CentOS 7
- mongod:MongoDB Enterprise 3.4.6
- MongoDB Enterprise Advancedをインストールするに従い、3台のノードを用意しておきます。
- SELinux、firewalldは停止しています
設定ファイルの作成
各ノードの/etc/mongod.conf
を編集します。In-Memoryストレージエンジンを利用する、ノード:mongo0/mongo1の設定は以下のようになります。
$ cat /etc/mongod.conf net: port: 27017 systemLog: destination: file logAppend: true path: /var/log/mongodb/mongod.log storage: engine: inMemory dbPath: /data inMemory: engineConfig: inMemorySizeGB: 1 processManagement: fork: true pidFilePath: /var/run/mongodb/mongod.pid replication: replSetName: s0
データの永続化を行うHiddenとなるノード:mongo2は以下のように記述します。ストレージエンジンを指定しなければ、バージョン3.2以降でデフォルトのWiredTigerとなります。
$ cat /etc/mongod.conf net: port: 27017 systemLog: destination: file logAppend: true path: /var/log/mongodb/mongod.log storage: dbPath: /data processManagement: fork: true pidFilePath: /var/run/mongodb/mongod.pid replication: replSetName: s0
データディレクトリの作成
データディレクトリを作成します。In-Memoryの場合にも、データは保存されませんが作成が必要です。
$ sudo mkdir /data $ sudo chown mongod:mongod /data
レプリカセットの作成
準備ができましたので、mongod
を起動しましょう。
$ sudo systemctl start mongod $ mongo MongoDB shell version v3.4.6 connecting to: mongodb://127.0.0.1:27017 MongoDB server version: 3.4.6 Server has startup warnings: 2017-07-24T08:05:52.920+0900 I CONTROL [initandlisten] 2017-07-24T08:05:52.921+0900 I CONTROL [initandlisten] ** WARNING: Access control is not enabled for the database. 2017-07-24T08:05:52.921+0900 I CONTROL [initandlisten] ** Read and write access to data and configuration is unrestricted. 2017-07-24T08:05:52.921+0900 I CONTROL [initandlisten] MongoDB Enterprise >
ノード:mongo0レプリカセットの設定を行っていきます。
MongoDB Enterprise > rs.initiate( { _id : "s0", members: [ { _id : 0, host : "mongo0:27017" } ]}) { "ok" : 1 } MongoDB Enterprise s0:SECONDARY> MongoDB Enterprise s0:PRIMARY>
レプリカセットにノード:mongo1/2を追加します。mongo2はpriority: 0
、hidden: true
を指定します。
MongoDB Enterprise s0:PRIMARY> rs.add( { _id : 1, host: "mongo1:27017" , priority: 1, votes: 1 } ) { "ok" : 1 } MongoDB Enterprise s0:PRIMARY> rs.add( { _id : 2, host: "mongo2:27017" , priority: 0, votes: 1 , hidden: true } ) { "ok" : 1 }
レプリカセットの状態を確認します。
MongoDB Enterprise s0:PRIMARY> rs.status().members [ { "_id" : 0, "name" : "mongo0:27017", "health" : 1, "state" : 1, "stateStr" : "PRIMARY", "uptime" : 1060, "optime" : { "ts" : Timestamp(1500852207, 1), "t" : NumberLong(1) }, "optimeDate" : ISODate("2017-07-23T23:23:27Z"), "electionTime" : Timestamp(1500851725, 2), "electionDate" : ISODate("2017-07-23T23:15:25Z"), "configVersion" : 3, "self" : true }, { "_id" : 1, "name" : "mongo1:27017", "health" : 1, "state" : 2, "stateStr" : "SECONDARY", "uptime" : 442, "optime" : { "ts" : Timestamp(1500852207, 1), "t" : NumberLong(1) }, "optimeDurable" : { "ts" : Timestamp(0, 0), "t" : NumberLong(-1) }, "optimeDate" : ISODate("2017-07-23T23:23:27Z"), "optimeDurableDate" : ISODate("1970-01-01T00:00:00Z"), "lastHeartbeat" : ISODate("2017-07-23T23:23:32.364Z"), "lastHeartbeatRecv" : ISODate("2017-07-23T23:23:31.342Z"), "pingMs" : NumberLong(0), "syncingTo" : "mongo0:27017", "configVersion" : 3 }, { "_id" : 2, "name" : "mongo2:27017", "health" : 1, "state" : 2, "stateStr" : "SECONDARY", "uptime" : 422, "optime" : { "ts" : Timestamp(1500852207, 1), "t" : NumberLong(1) }, "optimeDurable" : { "ts" : Timestamp(1500852207, 1), "t" : NumberLong(1) }, "optimeDate" : ISODate("2017-07-23T23:23:27Z"), "optimeDurableDate" : ISODate("2017-07-23T23:23:27Z"), "lastHeartbeat" : ISODate("2017-07-23T23:23:32.370Z"), "lastHeartbeatRecv" : ISODate("2017-07-23T23:23:31.528Z"), "pingMs" : NumberLong(0), "syncingTo" : "mongo1:27017", "configVersion" : 3 } ]
各ノードが正しく認識されました。設定が正しいか確認します。
MongoDB Enterprise s0:PRIMARY> rs.conf().members [ { "_id" : 0, "host" : "mongo0:27017", "arbiterOnly" : false, "buildIndexes" : true, "hidden" : false, "priority" : 1, "tags" : { }, "slaveDelay" : NumberLong(0), "votes" : 1 }, { "_id" : 1, "host" : "mongo1:27017", "arbiterOnly" : false, "buildIndexes" : true, "hidden" : false, "priority" : 1, "tags" : { }, "slaveDelay" : NumberLong(0), "votes" : 1 }, { "_id" : 2, "host" : "mongo2:27017", "arbiterOnly" : false, "buildIndexes" : true, "hidden" : true, "priority" : 0, "tags" : { }, "slaveDelay" : NumberLong(0), "votes" : 1 } ]
ストレージエンジンの確認です。ノード:mongo0/1ではinMemory
となっています。persistent: false
から、データの永続性がないこともわかります。
MongoDB Enterprise s0:PRIMARY> db.serverStatus().storageEngine { "name" : "inMemory", "supportsCommittedReads" : true, "readOnly" : false, "persistent" : false }
一方で、mongo2はwiredTiger
となっており、persistent: true
です。
MongoDB Enterprise s0:SECONDARY> db.serverStatus().storageEngine { "name" : "wiredTiger", "supportsCommittedReads" : true, "readOnly" : false, "persistent" : true }
データ永続性の確認
実際に、データを書き込み、レプリケーションによりデータが保全されることを確認します。
MongoDB Enterprise s0:PRIMARY> use test switched to db test MongoDB Enterprise s0:PRIMARY> db.users.insert({name:"hoge"}); WriteResult({ "nInserted" : 1 }) MongoDB Enterprise s0:PRIMARY> db.users.find() { "_id" : ObjectId("597530c5a400db8f5b4dfc17"), "name" : "hoge" }
書き込めたので、mongodを再起動してみます。
MongoDB Enterprise s0:PRIMARY> exit bye $ sudo systemctl restart mongod $ mongo MongoDB shell version v3.4.6 connecting to: mongodb://127.0.0.1:27017 MongoDB server version: 3.4.6 Server has startup warnings: 2017-07-24T08:27:42.331+0900 I CONTROL [initandlisten] 2017-07-24T08:27:42.331+0900 I CONTROL [initandlisten] ** WARNING: Access control is not enabled for the database. 2017-07-24T08:27:42.331+0900 I CONTROL [initandlisten] ** Read and write access to data and configuration is unrestricted. 2017-07-24T08:27:42.331+0900 I CONTROL [initandlisten] MongoDB Enterprise s0:SECONDARY>
再起動によりフェイルオーバーが発生してますので、SECONDARY
となっています。データを読み込んでみましょう。
MongoDB Enterprise s0:SECONDARY> rs.slaveOk() MongoDB Enterprise s0:SECONDARY> db.users.find() { "_id" : ObjectId("597530c5a400db8f5b4dfc17"), "name" : "hoge" }
先ほど書き込んだデータが、再起動後にも残っていることが確認できました。
まとめ
以上でIn-Memoryストレージエンジンのレプリカセットが構築できました。今後、In-Memoryのパフォーマンスについても検証してみたいと思います。