この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。
こんにちは、菊池です。9月も半分が過ぎ、そろそろ涼しい日も多くなってきました。
はじめに
AWSでは Microsoft や SAP 、Trend Microなどのエンタープライズソフトウェアを簡単にデプロイすることができる、AWSクイックスタートを公開しています。
それぞれのソフトウェアをAWS上で構築するにあったってのベストプラクティスに従った、CloudFormationのテンプレートが用意されております。つまり、公開されているテンプレート使ってスタックを構築するだけで、可用性やセキュリティを考慮した環境を構築することが可能です。
今回はその中から、ドキュメント指向のNOSQLデータベースであるMongoDBのテンプレートを試してみました。
MongoDB
MongoDBはドキュメント指向のDBで、レプリカセットやシャーディングによるクラスタを組むことで可用性とスケーラビリティを実現します。
クラスターアーキテクチャ
MongoDBのクラスターは以下のような構成をとります。
- DB node:データが格納されるサーバノード
- ConfigServer:シャーディングの設定情報を保持
- mongos:ConfigServerからシャーディングの設定を読み込み、適切なDBノードにアクセスをルーティング
本テンプレートではシャーディング構成でデプロイすることで、上記サーバの設定含めて構築されます。
CloudFormationスタックの作成
それでは、テンプレートを使ってCloudFormationでスタックを作成します。
MongoDBのテンプレートにはVPCも含めて丸ごと作成するテンプレートと、既存のVPC上に作成するテンプレートの2種類があります。
今回はVPC含めて東京リージョンに新規作成します。
Paramaters
スタック作成時に以下の入力パラメータを求められます。
Parameter | 説明 |
---|---|
VPCCIDR | 作成するVPCのCIDR |
RemoteAccessCIDR | 外部接続元のCIDR(SecurityGroupで許可される) |
ClusterReplicaSetCount | レプリカセットの数(1 or 3) |
ClusterShardCount | シャーディングする場合のシャード数 |
MongoDBVersion | MongoDBのバージョン(2.6 or 3.0) |
ShardsPerNode | 1つのDBノード内でのシャード数 |
BuildBucket | インストールスクリプトなどの配置場所(変更不可) |
PublicSubnet | NATインスタンスを配置するサブネットのCIDR |
PrimaryReplicaSubnet | PrimaryDBを配置するサブネットのCIDR |
SecondaryReplicaSubnet0 | SecondaryDB 0を配置するサブネットのCIDR |
SecondaryReplicaSubnet1 | SecondaryDB 1を配置するサブネットのCIDR |
KeyName | EC2のキーペア |
NATInstanceType | NATインスタンスのインスタンスタイプ |
VolumeSize | DBのデータ領域にアタッチするEBSのサイズ |
VolumeType | DBのデータ領域にアタッチするEBSの種類(GP2 or PIOPS) |
Iops | EBSをPIOPSに設定した場合のIOPS |
ConfigServerInstanceType | mongod(config)を稼働するノードのインスタンスタイプ |
NodeInstanceType | mongodを稼働するノードのインスタンスタイプ |
AvailabilityZone0 | PrimaryDBを配置するAZ |
AvailabilityZone1 | SecondaryDB 0を配置するAZ |
AvailabilityZone2 | SecondaryDB 1を配置する |
3ノードのレプリカセット、1シャードの構成として以下のように入力し作成しました。
構成イメージ
起動・配置されるインスタンスのイメージは下図のようになります。
本来、3ノードのレプリケーション構成では3つのAZに分散するのが望ましいですが、東京リージョンではアカウントによってAZ-a/AZ-cの2つしか使えないため、AZ-aに2つのノードを寄せています。
構成確認
10分程度でスタックの構築が完了しComplete状態になりました。
7台のインスタンスが稼働しています。
まずはNATサーバ経由でPrimaryDBにログインし、DBの状態を確認します。MongoDB関連のプロセスを見ると
$ ps aux | grep mongo
mongod 9248 0.2 1.4 42749424 57312 ? Sl 00:50 0:00 /usr/bin/mongod -f /etc/mongod0.conf
mongod 9511 0.1 0.3 252304 12020 ? Sl 00:50 0:00 /usr/bin/mongos -f /etc/mongos.conf
ec2-user 9933 0.0 0.0 110472 2244 pts/0 S+ 00:55 0:00 grep --color=auto mongo
MongoDBのサーバ本体のmongodとシャード間のルーティングを行うmongosが起動しています。
mongodの起動設定/etc/mongod0.conf
を確認します。
$ cat /etc/mongod0.conf
net:
port: 27018
systemLog:
destination: file
logAppend: true
path: /log/mongod0.log
storage:
dbPath: /data/s0-rs0
journal:
enabled: true
processManagement:
fork: true
pidFilePath: /var/run/mongod/mongod0.pid
replication:
replSetName: s0-rs0
port:27018でリッスンしてますので、シェルで接続してみます。
$ mongo localhost:27018
MongoDB shell version: 3.0.12
connecting to: localhost:27018/test
Welcome to the MongoDB shell.
For interactive help, type "help".
For more comprehensive documentation, see
http://docs.mongodb.org/
Questions? Try the support group
http://groups.google.com/group/mongodb-user
Server has startup warnings:
2016-09-15T00:50:03.580+0000 I CONTROL [initandlisten]
2016-09-15T00:50:03.580+0000 I CONTROL [initandlisten] ** WARNING: /sys/kernel/mm/transparent_hugepage/defrag is 'always'.
2016-09-15T00:50:03.580+0000 I CONTROL [initandlisten] ** We suggest setting it to 'never'
2016-09-15T00:50:03.580+0000 I CONTROL [initandlisten]
s0-rs0:PRIMARY>
接続できました。 いろいろとエラーみたいなメッセージが出ていますが、ここについては以下の記事を参照ください。
rs.conf()
でレプリケーションの設定を、rs.status()
でレプリケーションの状態を確認できます。
レプリカセットの設定確認:
s0-rs0:PRIMARY> rs.conf()
{
"_id" : "s0-rs0",
"version" : 1,
"members" : [
{
"_id" : 1,
"host" : "10.0.2.85:27018",
"arbiterOnly" : false,
"buildIndexes" : true,
"hidden" : false,
"priority" : 10,
"tags" : {
},
"slaveDelay" : 0,
"votes" : 1
},
{
"_id" : 2,
"host" : "10.0.4.25:27018",
"arbiterOnly" : false,
"buildIndexes" : true,
"hidden" : false,
"priority" : 5,
"tags" : {
},
"slaveDelay" : 0,
"votes" : 1
},
{
"_id" : 3,
"host" : "10.0.3.73:27018",
"arbiterOnly" : false,
"buildIndexes" : true,
"hidden" : false,
"priority" : 5,
"tags" : {
},
"slaveDelay" : 0,
"votes" : 1
}
],
"settings" : {
"chainingAllowed" : true,
"heartbeatTimeoutSecs" : 10,
"getLastErrorModes" : {
},
"getLastErrorDefaults" : {
"w" : 1,
"wtimeout" : 0
}
}
}
レプリカセットの状態確認:
s0-rs0:PRIMARY> rs.status()
{
"set" : "s0-rs0",
"date" : ISODate("2016-09-15T00:57:55.249Z"),
"myState" : 1,
"members" : [
{
"_id" : 1,
"name" : "10.0.2.85:27018",
"health" : 1,
"state" : 1,
"stateStr" : "PRIMARY",
"uptime" : 472,
"optime" : Timestamp(1473900614, 1),
"optimeDate" : ISODate("2016-09-15T00:50:14Z"),
"electionTime" : Timestamp(1473900618, 1),
"electionDate" : ISODate("2016-09-15T00:50:18Z"),
"configVersion" : 1,
"self" : true
},
{
"_id" : 2,
"name" : "10.0.4.25:27018",
"health" : 1,
"state" : 2,
"stateStr" : "SECONDARY",
"uptime" : 461,
"optime" : Timestamp(1473900614, 1),
"optimeDate" : ISODate("2016-09-15T00:50:14Z"),
"lastHeartbeat" : ISODate("2016-09-15T00:57:54.850Z"),
"lastHeartbeatRecv" : ISODate("2016-09-15T00:57:54.877Z"),
"pingMs" : 2,
"configVersion" : 1
},
{
"_id" : 3,
"name" : "10.0.3.73:27018",
"health" : 1,
"state" : 2,
"stateStr" : "SECONDARY",
"uptime" : 461,
"optime" : Timestamp(1473900614, 1),
"optimeDate" : ISODate("2016-09-15T00:50:14Z"),
"lastHeartbeat" : ISODate("2016-09-15T00:57:54.380Z"),
"lastHeartbeatRecv" : ISODate("2016-09-15T00:57:54.416Z"),
"pingMs" : 0,
"lastHeartbeatMessage" : "could not find member to sync from",
"configVersion" : 1
}
],
"ok" : 1
}
3ノードのレプリカセットで稼働していることが確認できました。
次に、シャーディングを確認します。シャーディングはmongosに接続して確認する必要がありますので、まずはmongosの設定/etc/mongos.conf
を見てみます。
$ cat /etc/mongos.conf
net:
port: 27017
systemLog:
destination: file
logAppend: true
path: /log/mongos.log
#
#
#
#
processManagement:
fork: true
pidFilePath: /var/run/mongod/mongos.pid
sharding:
configDB: 10.0.4.242:27030,10.0.3.27:27030,10.0.2.5:27030
mongosはport:27017でリッスンしてますので、シェルで接続。
$ mongo localhost:27017
MongoDB shell version: 3.0.12
connecting to: localhost:27017/test
mongos>
シャーディングの状態はsh.status()
で確認します。
シャーディングの状態確認:
mongos> sh.status()
--- Sharding Status ---
sharding version: {
"_id" : 1,
"minCompatibleVersion" : 5,
"currentVersion" : 6,
"clusterId" : ObjectId("57d9f05f13d999e4005018ba")
}
shards:
{ "_id" : "s0-rs0", "host" : "s0-rs0/10.0.2.85:27018,10.0.3.73:27018,10.0.4.25:27018" }
balancer:
Currently enabled: yes
Currently running: no
Failed balancer rounds in last 5 attempts: 0
Migration Results for the last 24 hours:
No recent migrations
databases:
{ "_id" : "admin", "partitioned" : false, "primary" : "config" }
mongos>
レプリカセット s0-rs0 による1シャード構成となっています。
まとめ
以上のようにクイックスタートのテンプレートを使用することで、レプリカセット/シャーディング構成のMongoDBクラスタが非常に簡単に構築できました。
専門的知識がなくても、可用性・スケーラビリティを考慮したMongoDBをすぐに利用開始できる素晴らしいテンプレートだと思います。
注意事項
このテンプレートが公開されてすでに1年以上経ってますので、それ以降にアプデートされたAWS/MongoDBの機能が使用されていません。例えば、現在であれば以下のような改善ポイントがあります。
- NAT インスタンスではなくNAT Gatewayを使用する
- MongoDBのストレージエンジンをWiredTigerにする
- MongoDB 3.0 からストレージエンジンとしてWiredTigerが使用可能になっていますが、デフォルトではMMAPv1となります。WiredTigerを使うことで、データ圧縮や、書き込み性能の大幅向上などのメリットがあります。
- MongoDBを最新バージョンにする
- テンプレートで選択可能なバージョンは 2.6 または 3.0 で、それぞれ最新のマイナーバージョンがインストールされますが、最新メジャーバージョン3.2系となります。WiredTigerがデフォルトとなった他、Configサーバでレプリカセット構成が可能になるなど、いくつかの機能追加がされています。
スタック作成後に上記の対応をすることでも、一から構築するのに比べれば十分簡単に構築することができるのではないでしょうか。