mongodb on aws

Post on 14-May-2015

4.029 Views

Category:

Documents

2 Downloads

Preview:

Click to see full reader

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

死活監視

ご清聴

ありがとうございました!

top related