前から気になっていた Amazon RDS を触ってみた。gumiは自前でインスタンスにMySQLをセットアップせずにRDS使っているし、read replicaも出てスケーリングに関してどの程度カバーできるのか興味もあった。やっぱりMySQLの構築や運用は任せられたほうが楽なので。
作り方はとても簡単。AWS Management Console上ではいくつかのパラメータをいれてクリックしていければ作れる。最初にインスタンスタイプとストレージ容量などを決める必要があるが、これは後から変更も可能。
ここで特徴的なのは Multi-AZ だと思う。これはおそらくレプリケーションしていて、Masterとは異なるAvailability Zoneにあるインスタンスでホットスタンバイ機が設けられる。万が一、Masterのデータセンターごと落ちちゃった時やメンテナンス時にこのスタンバイ機にフェールオーバーされるらしい。やはりDBはシングルポイントで落ちては困るので、Multi-AZ は付けておきたいが、料金も倍かかるので注意。
変更画面はこんな感じでいろいろ変えることができる。インスタンスタイプとストレージ容量が途中で変えられるのは、予測しづらい中で運用する際には嬉しいと思う。
最初のMasterの起動自体は5分くらいかかっている。裏でEBSマウントして、MySQL立ち上げてユーザ設定してとかやっているのだろう。
Slaveにあたる read replica を作るのもAWS Management Consoleから行える。Masterより設定項目が少ないので、簡単にレプリケーションを張ったSlaveが作れる。read replica は最大5台まで立ち上げられる。
read replica が立ち上げ中の時はManagement Console上のMasterのstatusはmodifyingになるので、レプリケーションをはるためにMySQLは止まってしまうのだろう。上は新規で立ち上げた read replica のstatus。
ここから色々探ってみる。
ホスト名を引くとec2のホスト名にCNAMEされていた。
$ host testidentifier.cstgtbgikb7y.us-east-1.rds.amazonaws.com testidentifier.cstgtbgikb7y.us-east-1.rds.amazonaws.com is an alias for ec2-184-73-82-152.compute-1.amazonaws.com. ec2-184-73-82-152.compute-1.amazonaws.com has address 184.73.82.152
内部的にはEC2のインスタンスを起動、EBSマウント、レプリケーションをはる動作を行なっているようだ。起動スクリプトやれないことはないけれども、手間なのでワンクリックだけですむのは非常に楽に構築できる。ちなみに Snapshotもクリックひとつで簡単に取れる。
Masterにmysqlログインして見てみる。
dsea-MacBook:~ hironobu$ mysql -u testrep -p**** -h testidentifier.cstgtbgikb7y.us-east-1.rds.amazonaws.com (snip) mysql> show databases; +--------------------+ | Database | +--------------------+ | information_schema | | innodb | | mysql | | testrds | +--------------------+ 4 rows in set (0.18 sec)
testrdsは自分が作ったDB。
mysql> select user,host from mysql.user; +--------------+-----------+ | user | host | +--------------+-----------+ | rdsrepladmin | % | | testrep | % | | rdsadmin | localhost | +--------------+-----------+ 3 rows in set (0.19 sec) mysql> show grants for rdsadmin@localhostG *************************** 1. row *************************** Grants for rdsadmin@localhost: GRANT ALL PRIVILEGES ON *.* TO 'rdsadmin'@'localhost' IDENTIFIED BY PASSWORD '*403D726C7C5F4E71D5790A7C0BCEA79CE3BEB17C' WITH GRANT OPTION 1 row in set (0.20 sec) mysql> show grants for rdsrepladminG *************************** 1. row *************************** Grants for rdsrepladmin@%: GRANT REPLICATION SLAVE ON *.* TO 'rdsrepladmin'@'%' IDENTIFIED BY PASSWORD '*132499B6DBF70C249F6262DB94789088E3B76B92' 1 row in set (0.20 sec) mysql> show grants for testrepG *************************** 1. row *************************** Grants for testrep@%: GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, DROP, RELOAD, PROCESS, REFERENCES, INDEX, ALTER, SHOW DATABASES, CREATE TEMPORARY TABLES, LOCK TABLES, EXECUTE, REPLICATION CLIENT, CREATE VIEW, SHOW VIEW, CREATE ROUTINE, ALTER ROUTINE, CREATE USER, EVENT, TRIGGER ON *.* TO 'testrep'@'%' IDENTIFIED BY PASSWORD '*39247272E1DEB1E4B93144EAB61B2F00A752CABC' WITH GRANT OPTION 1 row in set (0.20 sec)
testrepは自分が起動時に設定したユーザなので、rdsrepladminとrdsadminというのがあらかじめ設定されてるユーザで、rootにあたるのがrdsadmin、read replicaからのレプリケーションを受け付けるためにrdsrepladminがあることが分かる。自分で作ったユーザには管理系のコマンドは実行できないようになっている。
mysql> show master status; +----------------------------+----------+--------------+------------------+ | File | Position | Binlog_Do_DB | Binlog_Ignore_DB | +----------------------------+----------+--------------+------------------+ | mysql-bin-changelog.000013 | 106 | | | +----------------------------+----------+--------------+------------------+ 1 row in set (0.18 sec)
確かにMasterとして動いている。
次に read replicaにmysqlログインしてみる。
$ mysql -u testrep -p**** -h replica01testidentifier.cstgtbgikb7y.us-east-1.rds.amazonaws.com (snip) mysql> select user,host from mysql.user; +--------------+-----------+ | user | host | +--------------+-----------+ | rdsrepladmin | % | | testrep | % | | rdsadmin | localhost | +--------------+-----------+ 3 rows in set (0.19 sec) mysql> show databases; +--------------------+ | Database | +--------------------+ | information_schema | | innodb | | mysql | | testopenx | +--------------------+
あたりまえだけどMasterと同じ。
mysql> show slave statusG *************************** 1. row *************************** Slave_IO_State: Waiting for master to send event Master_Host: testidentifier.cstgtbgikb7y.us-east-1.rds.amazonaws.com Master_User: rdsrepladmin Master_Port: 3306 Connect_Retry: 60 Master_Log_File: mysql-bin-changelog.000013 Read_Master_Log_Pos: 106 Relay_Log_File: relaylog.000018 Relay_Log_Pos: 261 Relay_Master_Log_File: mysql-bin-changelog.000013 Slave_IO_Running: Yes Slave_SQL_Running: Yes Replicate_Do_DB: Replicate_Ignore_DB: Replicate_Do_Table: Replicate_Ignore_Table: Replicate_Wild_Do_Table: Replicate_Wild_Ignore_Table: Last_Errno: 0 Last_Error: Skip_Counter: 0 Exec_Master_Log_Pos: 106 Relay_Log_Space: 462 Until_Condition: None Until_Log_File: Until_Log_Pos: 0 Master_SSL_Allowed: No Master_SSL_CA_File: Master_SSL_CA_Path: Master_SSL_Cert: Master_SSL_Cipher: Master_SSL_Key: Seconds_Behind_Master: 0 Master_SSL_Verify_Server_Cert: No Last_IO_Errno: 0 Last_IO_Error: Last_SQL_Errno: 0 Last_SQL_Error: 1 row in set (0.19 sec)
Masterのホスト名宛にrdsrepladminユーザでレプリケーションがはれていることが分かる。
中身を見てしまえば、MySQLのレプリケーションの構成。確かに簡単にレプリケーション環境をクリックだけで作れるのは新しい感覚。
ここまで作れているのは嬉しいが、やっぱりEC2をベースにしているとはっきり分かるスタンスがユーザビリティに影響している部分がある。せっかく read replica で簡単に増やせても、その把握とクエリを投げる先に加える仕組みはユーザ側で用意しなければならないから、実運用上はサービスを止めてメンテナンスで更新をかけたり、クエリの分散先をスムーズに更新する自動化された仕組みを頑張って用意するのだろう。
そこら辺を踏まえ、せっかくスケーラブルなベースが出来ているのだから、以下の機能も提供してもらえたら素晴らしくなるのにと思った。
-
read replicaのオートスケーリングへの対応</p>
- 結局中身はEC2なのだし
-
増えた read replica用のELB提供
- Slaveが増やせても複数台それぞれにアクセスするための仕組みはユーザで用意しなくては行けない
- アプリケーション側で工夫するとかDNSラウンドロビンにするとか。それを一元化するための仕組みは用意してあげたほうがいい
-
出来ればクエリを見てMaster/read replicaに振る
- アプリケーションから見るとたった1つのホストにアクセスすればいい
上2つはそれほどハードルは高くないと思うので、多分もうAmazonは準備していると思うけど、あとはいつ出てくるかだけかな。