AWSクイックスタート:MongoDB on the AWS Cloudを試してみた

2016.09.16

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

こんにちは、菊池です。9月も半分が過ぎ、そろそろ涼しい日も多くなってきました。

はじめに

AWSでは Microsoft や SAP 、Trend Microなどのエンタープライズソフトウェアを簡単にデプロイすることができる、AWSクイックスタートを公開しています。

AWS クイックスタートリファレンスデプロイ

それぞれのソフトウェアをAWS上で構築するにあったってのベストプラクティスに従った、CloudFormationのテンプレートが用意されております。つまり、公開されているテンプレート使ってスタックを構築するだけで、可用性やセキュリティを考慮した環境を構築することが可能です。

今回はその中から、ドキュメント指向のNOSQLデータベースであるMongoDBのテンプレートを試してみました。

MongoDB on the AWS Cloud

MongoDB

MongoDBはドキュメント指向のDBで、レプリカセットやシャーディングによるクラスタを組むことで可用性とスケーラビリティを実現します。

クラスターアーキテクチャ

MongoDBのクラスターは以下のような構成をとります。

mongodb-cluster

  • 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シャードの構成として以下のように入力し作成しました。

starting-mongo-aws-00

 

構成イメージ

起動・配置されるインスタンスのイメージは下図のようになります。

本来、3ノードのレプリケーション構成では3つのAZに分散するのが望ましいですが、東京リージョンではアカウントによってAZ-a/AZ-cの2つしか使えないため、AZ-aに2つのノードを寄せています。

starting-mongo-aws-01

 

構成確認

10分程度でスタックの構築が完了しComplete状態になりました。

7台のインスタンスが稼働しています。

starting-mongo-aws-02

 

まずは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>

接続できました。 いろいろとエラーみたいなメッセージが出ていますが、ここについては以下の記事を参照ください。

MongoDB On EC2を試してみる

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サーバでレプリカセット構成が可能になるなど、いくつかの機能追加がされています。

スタック作成後に上記の対応をすることでも、一から構築するのに比べれば十分簡単に構築することができるのではないでしょうか。