mongodb on aws
DESCRIPTION
本資料中の内容は、発表者個人の作成物であり、所属する会社の見解等を反映したものではありません、と一応定型句を付けておきます。TRANSCRIPT
MongoDB
on
AWS
~インフラを操る楽しさ体験~
Sky株式会社
玉川竜司
まずは自己紹介 •開発やってます(最近ちょっとビミョー)
•翻訳やってます
•憲さんとは親戚じゃないっす
@tamagawa_ryuji
今日のテーマ
題材:MongoDB
•NoSQL系データベース
•ドキュメントデータベース
•レプリカセットによるフェイルオーバー
•シャーディングによるスケーラビリティ
•Web系で求められる機能多数
•ログの扱いに特化した機能あり
•豊富なクライアントライブラリ
•日本のコミュニティ
( 「mongodb-jp」で検索を! )
レ プ リ カ セ ッ ト
作ってみたシステム: MongoDBをバックエンドとする高可用性Webアプリ
カスタムAMI
Japan Ireland USA
MongoDB
WebApp (読取)
カスタムAMI
MongoDB
WebApp (読取)
カスタムAMI
MongoDB
http://webapp.techlabo.me:5000
Python (書込)
MongoDBのレプリカセット
•複数ノードで高可用性を実現
•設定簡単
•書き込みはプライマリのみ
• 書き込みの負荷分散はシャードで行う
•セカンダリで読み取り負荷を分散できる
•設定が柔軟
• バックアップ目的のセカンダリは、インデックスなしで負荷低減
• セカンダリへのレプリケーションにタイムラグを持たせてオペミス対策
•過半数のノードが生きていて相互通信可能なら、書き込み可能
rsconf ={_id: "santo",members:
[{_id: 0,
host: "japan-mongo.techlabo.me"}]}
rs.initiate(rsconf)
rs.add(‘us-mongo.techlabo.me’)
rs.add(‘ireland-mongo.techlabo.me’)
レプリカセットの動作(正常時)
カスタムAMI
Japan Ireland USA
プライマリ
カスタムAMI カスタムAMI
セカンダリ セカンダリ
レプリケーション
ハートビート
レプリカセットの動作 (セカンダリの障害と回復)
カスタムAMI
Japan Ireland USA
プライマリ
カスタムAMI カスタムAMI
セカンダリ セカンダリ
レプリケーション
ハートビート
レプリカセットの動作 (セカンダリの障害と回復)
カスタムAMI
Japan Ireland USA
プライマリ
カスタムAMI カスタムAMI
セカンダリ セカンダリ
レプリケーション
ハートビート
追い付くまでフルコピー
レプリカセットの動作 (マスターの障害と回復)
カスタムAMI
Japan Ireland USA
プライマリ
カスタムAMI カスタムAMI
セカンダリ セカンダリ
レプリケーション
ハートビート
レプリカセットの動作 (マスターの障害と回復)
カスタムAMI
Japan Ireland USA
プライマリ
カスタムAMI カスタムAMI
セカンダリ セカンダリ
レプリケーション
ハートビート
プライマリ
レプリカセットの動作 (マスターの障害と回復)
カスタムAMI
Japan Ireland USA
セカンダリ
カスタムAMI カスタムAMI
セカンダリ
レプリケーション
ハートビート
プライマリ
レプリカセットの動作 (マスターの障害と回復)
カスタムAMI
Japan Ireland USA
セカンダリ
カスタムAMI カスタムAMI
セカンダリ
レプリケーション
ハートビート
プライマリ
追い付くまでフルコピー
ap-northeast-1a
ap-northeast-1b
名前解決と通信コスト
カスタムAMI
Japan
USA
j1.techlabo.me
カスタムAMI カスタムAMI
j2.techlabo.me us.techlabo.me
CNAME j2-mongo.techlabo.me ec2-x-x-x-x.ap-northeast-1.compute.amazonaws.com
CNAME ius-mongo.techlabo.me ec2-x-x-x-x.eu-west-1.compute.amazonaws.com
ec2-x-x-x-x…. ip-x-x-x-x
•同一リージョン内へ、内部IPアドレス
で通信すればコストは発生しない。
•他リージョンへは、パブリックIPで通
信せざるを得ない。コストも発生する。
•パブリックDNS名を使えば、自動的
にうまくresolveしてくれる。
障害回復(インスタンスの交換)時の課題
• インスタンスを入れ替えると、IPアドレスやパブリックDNS名が変わってしまう
• レプリカセットの設定(DNS名もしくはIPアドレスでホスト指定)を変更したくない
• Elastic IPだと、同一リージョン内の通信でも費用が掛かる
そこでRoute 53ですよ!
• レプリカセットの設定にはFQDNを使う
• FQDNからインスタンスのPublic DNS NameへのCNAMEエン
トリを、インスタンスの起動時に自動的にRoute 53へ登録する
• インスタンスのFQDNは、インスタンスのLaunchの時点でイン
スタンスに書き込む
CNAME j2-mongo.techlabo.me ec2-x-x-x-x.ap-northeast-1.compute.amazonaws.com
CNAME ius-mongo.techlabo.me ec2-x-x-x-x.eu-west-1.compute.amazonaws.com
Route 53への
CNAMEの自動登録
FQDN="FDQN_HERE"
export AWS_ACCESS_ID="AWS_ACCESS_ID_HERE"
export AWS_SECRET_KEY="AWS_SECRET_KEY_HERE"
ec2_hostname=`curl -s http://169.254.169.254/latest/meta-data/public-hostname`.
update_host.py $FQDN -c $ec2_hostname -t 60
ec2-mongo-init(抜粋) - 起動時にサービスとして実行 赤字の部分はuser dataの スクリプトで 置き換える
botoベースのRoute 53用ライブラリhttps://github.com/tkuhlman/cirrus
から借用
USER DATAによる
設定の埋め込み
#!/bin/sh
yum -y update python-boto
sed -i "s/FQDN_HERE/<your instance's FQDN here>/" /etc/rc.d/init.d/ec2-mongo-init
sed -i "s/AWS_ACCESS_ID_HERE/<your AWS access id here>/" /etc/rc.d/init.d/ec2-mongo-init
sed -i "s/AWS_SECRET_KEY_HERE/<your AWS secret key here>/" /etc/rc.d/init.d/ec2-mongo-init
sed -i "s/#replSet=replicaSetName/<your replica set name>/" /etc/mongod.conf
これをやっておかないとRoute 53のエントリ 更新がエラーになる
このインスタンスが参加する レプリカセット名
ここにシェルスクリプトを書いて、
起動時に実行させることができます
Security Groupも自動設定 •リージョン間のMongoDBインスタンス同士の通信を許可する
•IPアドレス直指定で、インスタンスの起動時に設定を更新
•nameタグにmongoという文字列が入っているインスタンスが対象
•各リージョンのMongoInstancesというセキュリティグループのポート27017のルールを設定
for aRegion in regions:
conn = boto.ec2.connect_to_region(aRegion,
aws_access_key_id = access_id,
aws_secret_access_key = secret_key)
connections.append(conn)
rs = conn.get_all_instances()
mongoInstances = [r.instances[0] for r in rs if u'mongo' in r.instances[0].tags[u'Name']]
for mi in mongoInstances:
ip_addresses.append(mi.ip_address)
for conn in connections:
mongoInstanceSGs = [sg for sg in conn.get_all_security_groups() if sg.name == securityGroupName]
if mongoInstanceSGs != []:
mongoInstanceSG = mongoInstanceSGs[0]
for aRule in mongoInstanceSG.rules:
if aRule.from_port == u'27017':
for aGrant in aRule.grants:
if aGrant.cidr_ip != None:
mongoInstanceSG.revoke('tcp', 27017, 27017, cidr_ip = aGrant.cidr_ip)
for anIp in ip_addresses:
if anIp != None:
mongoInstanceSG.authorize('tcp', 27017, 27017, anIp + u'/32')
クライアントの動作(接続設定)
Japan
Ireland USA
Conn=MongoClient([ “japan-mongo.techlabo.me”,
“us-mongo.techlabo.me”,
“ireland-mongo.techlabo.me”])
プライマリ セカンダリ セカンダリ
クライアント
• 普通に接続すれば、論理的にはレプリカセット全体
に接続したことになる
• ただし、物理的なセッションは特定のノードに対して
張られている。
ap-northeast-1a
ap-northeast-1b
クライアントの動作(接続設定)
Japan
USA
プライマリ セカンダリ セカンダリ
クライアント
• 特定条件を満たす(例えば同一リージョン内)セカンダリに読
み取りを持っていき、通信コストを抑えつつ負荷分散するよ
う設定可能。
• バックアップとしてus-east-1にレプリカセットのノードを用
意しながら、平常時のクライアントのアクセスはap-
northeast-1のアベイラビリティゾーンのノード群に限定して
負荷分散できる
ap-northeast-1a
ap-northeast-1b
クライアントの動作(障害発生時)
Japan
USA
プライマリ セカンダリ セカンダリ
クライアント
• 障害発生時、一旦は例外が生じる(必要ならリカバリ
処理を行う)。
• もう一度リクエストを実行すれば、フェイルーバーした
プライマリへ自動的に接続し直して処理を続行できる。
AutoConnect
Exception
プライマリ
DNSフェイルオーバー:正常時
Japan Ireland USA
MongoDB
WebApp
MongoDB
WebApp
MongoDB
Elastic IP
x.x.x.x
Elastic IP
y.y.y.y
A mongo-webapp.techlabo.me y.y.y.y
A mongo-webapp.techlabo.me ALIAS x.x.x.x 死活監視
A mongo-webapp.techlabo.me y.y.y.y
A mongo-webapp.techlabo.me ALIAS x.x.x.x
DNSフェイルオーバー:障害発生時
Japan Ireland USA
MongoDB
WebApp
MongoDB
WebApp
MongoDB
Elastic IP
x.x.x.x
Elastic IP
y.y.y.y
死活監視
参考資料
MongoDB公式サイト
http://www.mongodb.org/
MongoDB公式サイトのAWS関連ドキュメント
http://docs.mongodb.org/ecosystem/platforms/amazon-ec2/
MongoDB on AWSホワイトペーパー
http://aws.amazon.com/jp/whitepapers/mongodb-on-aws/
AWS Market Place : MongoDB from 10gen
ご清聴
ありがとうございました!