Multi AZでのMongoDB ReplSet 〜 MongoDB編 | アドカレ2013 : CFn #17

2013.12.17

渡辺です。

『アドベントカレンダー2013:AWS CloudFormationビッグバンテンプレート』の17日目のエントリーになります。今日はMongoDBクラスタをAWSに構築するためのテンプレートを紹介したいと思います。昨日はすもけさんのお手軽ログ解析 〜 Kibana編でした。

MongoDBとは?

MongoDBは、スケーラブルなドキュメント指向のデータベースです。データをBSON(Binary JSON)というフォーマットで保存されるため、JSONフォーマットを扱う場合に非常に相性がよいデータベースです。他のNoSQLと呼ばれるデータベースに比べ、柔軟で高速なクエリを扱うことが出来る点が特徴でしょう *1

また、データベースのレプリケーションやスケーリングのためのシャーディングといった機能も豊富です。やや運用が難しいという点はありますが、使い所を間違えなければ強力な選択肢のひとつとなるでしょう。

AWS上にMongoDB環境を構築する

MongoDBは単体でインストールして利用することも可能です。しかし、折角、AWS上にMongoDB環境を構築するならば単体で構築しても面白くありません。それに単体でインストールするのであれば、MongoDB用のイメージが配布されているのでそれを利用する方が良いでしょう。

そこで、CloudFormationを使って次のような構成でMongoDBを組んでみました。

mongo-cfn

4台構成のReplicaSet

MongoDBのReplicaSetを4台のEC2インスタンスで構成します。2台はArbiterとして動作させ、残りの2台はPrimaryとSecondaryに割り当てられます。

Multi AZ

VPCにそれぞれ異なるAZに割り当てた2つのPrivate Subnetを作成しました。異なるAZにPrimaryノードとSecondaryノードが分散することでより可用性を高くすることができます。

また、Arbiterノードも各AZに配置しました。これはArbiterが片方のAZにしかない状況では、ArbiterのあるAZ全体に影響する障害が発生した場合に、障害の発生していないAZのMongoDBが孤立してしまうことを避けるためです。 *2

Bastion(踏み台)

MongoDBのノードが配置される2つのprivate subnetに加え、public subnetを用意し、メンテナンス用のBastion(踏み台)を配置します。このインスタンスはメンテナンス時のみ起動させても良いでしょう。MongoDBのクライアントもインストールされます。

公開テンプレート

VPCなどもまるっと構築する「お手軽VPC入りテンプレート(デモ用)」を用意しました。

MongoDB(デモ用)を起動

本番用のテンプレートは2つのPrivate subnetを構築してある前提で、Mongoのインスタンスのみを作成します。

MongoDB(本番用)を起動

スタックパラメータ

KeyName
EC2にログインするためのキーペア名
InstanceType
Primary/SecondaryノードとなるEC2のインスンスタイプ(初期値:t1.micro)
ArbiterInstanceType
ArbiterノードとなるEC2のインスンスタイプ(初期値:t1.micro)
PrimaryArbiterMongoIpAddress
Primary SubnetのArbiterノードのプライベートIPアドレス(初期値:10.0.1.10)
SecondaryArbiterMongoIpAddress
Secondary SubnetのArbiterノードのプライベートIPアドレス(初期値:10.0.2.10)
PrimaryMongoIpAddress
Primary SubnetのPrimary/SecondaryノードのプライベートIPアドレス(初期値:10.0.1.11)
SecondaryMongoIpAddress
Secondary SubnetのPrimary/SecondaryノードのプライベートIPアドレス(初期値:10.0.2.11)
replSet
レプリカセットの名前(初期値:rs0)
VpcId
EC2を起動するVPCのID(本番用テンプレートのみ)
PrimarySubnetId
Primary側のサブネットのID(本番用テンプレートのみ)
SecondarySubnetId
Secondary側のサブネットのID(本番用テンプレートのみ)
NatSecurityGroupId
PrivateSubnetに属するインスタンスがNAT経由でアクセス許可を与えるセキュリティグループのID(本番用テンプレートのみ)

構築後のセットアップ

CloudFormationで環境が構築できたならば、レプリカセットをMongoDBに設定します。早速、踏み台サーバにSSH接続しましょう。踏み台サーバはElastic IPが割り当てられており、CloudFormationのOutputに表示されています。

mongo-cfn-outputs-4

踏み台サーバにもMongoDBクライアントはインストールされています。Arbiterノードではないノードのどちらか(ここでは10.0.1.11)に接続してレプリケーションの設定を行います。

$ mongo 10.0.1.11
MongoDB shell version: 2.4.8
connecting to: 10.0.1.11/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


> var config = {
   "_id" : "rs0",
   "version" : 1,
   "members" : [
      {"_id" : 0, "host" : "10.0.1.10", arbiterOnly : true},
      {"_id" : 1, "host" : "10.0.2.10", arbiterOnly : true},
      {"_id" : 2, "host" : "10.0.1.11"},
      {"_id" : 3, "host" : "10.0.2.11"}
   ]
};
> rs.initiate(config);
{
	"info" : "Config now saved locally.  Should come online in about a minute.",
	"ok" : 1
}

後は自由に実験してみてください!

まとめ

AWS CloudFormationビッグバンテンプレート、17日目はMongoDBでした。AWS上にMongoDBのEC2インスタンスを作るだけならば簡単ですが、レプリカセットまで作るとなると時間もかかります。必要な時に実験できるようにテンプレート化しておくと便利ですね、

なお、テンプレートファイルはGitHubで公開しております。PRもあればどんどん送ってください。

それでは、明日もご期待ください。

脚注

  1. ただし、適切にインデックスを作る必要があります
  2. Arbiterノードとはそれ自体はレプリカセットのPrimaryにもSecondaryにもならず、Primaryノードに障害が起きたとき、次のPrimaryノードを決める投票権を持つノードです。Arbiterノードが存在しないと2台構成でPrimaryノードに障害が起きた場合、SecondaryノードがPrimaryノードに昇格できないことになります。