Amazon Auroraでクロスリージョンレプリカを作ってみた。
こんにちは、最近は少し涼しめの気候でいい感じですね、ねの城内です。
今回もAmazon Auroraネタでいってみたいと思います。
はじめに
Auroraは、最大15台ものレプリカが作成可能です。MySQLでもレプリカが最大5台まで作成可能でした。 ここには台数の違いがありますが、もう一つ、クロスリージョンレプリカの作成ができる、できないという点で違いがあります。
ちなみに、「MySQLではできるが、Auroraではできない」です。 上の図がMySQLのレプリカ設定画面で、下がAuroraです。MySQLには[送信先リージョン]という項目がありますが、Auroraにはリージョンを指定する項目はありません。
MySQL
Aurora
構成図
今回は、以下のような構成を作ってみたいと思います。 使用するリージョンは東京とオレゴンで、東京側にマスターを、オレゴン側にレプリカを作成します。
あくまで検証用の構成ですので、ご参考程度に参照ください。
レプリケーションがリージョンを跨ぐためには、マスターとなるインスタンスにパブリックアクセスができる必要があります。 ただ、データベースが外向けに全開放というのはあまりにもなので、オレゴンリージョン側にNATインスタンスを立て、EIPを使って開放する口をIPで絞れるようにしました。 (東京リージョンのVPCで、Route TableのIGWへの送信先をEIPにし、RDSに紐付けるSecurity GroupのInboundでEIPからの3306ポートを許可します)
本来であれば、これではデータがインターネットに平文で流れてしまうため、さらにVPNなりでセキュアなネットワークを経由する構成にした方がいいことは言うまでもありませんが、今回はあくまで動作検証目的ということでそこまではやりませんでした。
試してみる
では、早速試してようと思うのですが、上記で記載した通り、通常の方法ではAuroraはレプリカを別リージョンに作成することができません。 そのため、今回は、以前弊社のブログ記事でご紹介した、binlogを使用した以下の方法を参考にしたいと思います。
Auroraの作成(マスター)
まずは、東京リージョンにAuroraを作成するのですが、事前にbinlogを有効化するためのパラメータグループを作成します。 タイプはDB Cluster Parameter Groupで、binlog_formatパラメータの値をMIXEDにします。
Auroraを作成する際に、[パブリックアクセス可能]をはいにし、[DBクラスターのパラメータグループ]に上記で作成したパラメータグループを指定します。 Auroraの作成手順は、以下の記事を参考にしてください。
レプリカ用のダンプ取得
次に、レプリカのベースとなるダンプを取得します。 その際に、レプリケーションの設定をするために、binlogの情報が必要になるため、それも併せて取得しておきます。 (ちなみに、RDSではSUPER権限をもらえないため、FLUSH TABLES WITH READ LOCKコマンドは実行できません)
$ mysql -u dbadmin -h tokyo-aurora-cluster.cluster-abcdef123456.ap-northeast-1.rds.amazonaws.com -p Enter password: Welcome to the MySQL monitor. Commands end with ; or \g. Your MySQL connection id is 7 Server version: 5.6.10-log MySQL Community Server (GPL) Copyright (c) 2000, 2015, Oracle and/or its affiliates. All rights reserved. Oracle is a registered trademark of Oracle Corporation and/or its affiliates. Other names may be trademarks of their respective owners. Type 'help;' or '\h' for help. Type '\c' to clear the current input statement. mysql> show master status; +----------------------------+----------+--------------+------------------+-------------------+ | File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set | +----------------------------+----------+--------------+------------------+-------------------+ | mysql-bin-changelog.000001 | 53556 | | | | +----------------------------+----------+--------------+------------------+-------------------+ 1 row in set (0.00 sec) mysql> exit Bye $ mysqldump -u dbadmin -p -h tokyo-aurora-cluster.cluster-abcdef123456.ap-northeast-1.rds.amazonaws.com --databases testdb --single-transaction --order-by-primary -r backup.sql Enter password: $ ll total 176380 -rw-rw-r-- 1 ec2-user ec2-user 180607569 Oct 13 07:21 backup.sql $
Auroraの作成(レプリカ)
オレゴンリージョンでAuroraを作成し、上記で取得したダンプをインポートします。 (レプリカ側はパブリックアクセス不要です)
$ ll total 176384 -rw-rw-r-- 1 ec2-user ec2-user 180607569 Oct 13 07:21 backup.sql -rw-r--r-- 1 root root 8 Oct 13 07:58 httpd_lua_shm.2361 $ mysql -h oregon-aurora-cluster.cluster-abcdef123456.us-west-2.rds.amazonaws.com -u dbadmin -p testdb < backup.sql Enter password: $ $ mysql -u dbadmin -h oregon-aurora-cluster.cluster-abcdef123456.us-west-2.rds.amazonaws.com -p Enter password: Welcome to the MySQL monitor. Commands end with ; or \g. Your MySQL connection id is 115 Server version: 5.6.10 MySQL Community Server (GPL) Copyright (c) 2000, 2015, Oracle and/or its affiliates. All rights reserved. Oracle is a registered trademark of Oracle Corporation and/or its affiliates. Other names may be trademarks of their respective owners. Type 'help;' or '\h' for help. Type '\c' to clear the current input statement. mysql> use testdb Reading table information for completion of table and column names You can turn off this feature to get a quicker startup with -A Database changed mysql> select * from sample where id between '1' and '10'; +----+----------+--------------------------------+-------+---------------------+ | id | name | description | price | created_at | +----+----------+--------------------------------+-------+---------------------+ | 1 | product1 | 36fad9b847baff1e6f71e4bb6aebcc | 5177 | 2014-04-13 07:02:06 | | 2 | product2 | ae894317ec7484c0c1c600e2a1159a | 6870 | 2014-04-01 10:24:20 | | 3 | product3 | d899f84d362ec59848489d233648c3 | 553 | 2014-02-17 03:32:41 | | 4 | product4 | 43328ca2ff593895a04ffa642e9ff5 | 3091 | 2014-05-06 13:01:56 | | 6 | product6 | 391314984430f929e9e40cac153009 | 5356 | 2014-05-21 06:55:28 | | 7 | product7 | c63f9ef07b1cf909aa3124ac1d926c | 6619 | 2014-06-29 23:28:39 | | 8 | product8 | 63b09a7e54b97f6cdcb44aa3176d53 | 6298 | 2014-03-16 03:52:38 | | 9 | product9 | 7ba7518e69e438eeb4fc8ea40c725a | 4016 | 2014-02-20 04:13:03 | +----+----------+--------------------------------+-------+---------------------+ 8 rows in set (0.00 sec) mysql>
ちなみに、ダンプしたデータは、EC2ごとAMIイメージでバックアップし、リージョン間コピーで移行しました。
レプリケーション設定
最後に、レプリケーションの設定を行います。
まずは、東京リージョンのマスター側に専用ユーザを作成します。
$ mysql -u dbadmin -h tokyo-aurora-cluster-1.cluster-abcdef123456.ap-northeast-1.rds.amazonaws.com -p Enter password: Welcome to the MySQL monitor. Commands end with ; or \g. Your MySQL connection id is 114 Server version: 5.6.10-log MySQL Community Server (GPL) Copyright (c) 2000, 2015, Oracle and/or its affiliates. All rights reserved. Oracle is a registered trademark of Oracle Corporation and/or its affiliates. Other names may be trademarks of their respective owners. Type 'help;' or '\h' for help. Type '\c' to clear the current input statement. mysql> use testdb Reading table information for completion of table and column names You can turn off this feature to get a quicker startup with -A Database changed mysql> CREATE USER 'repl_user'@'%' IDENTIFIED BY 'password'; Query OK, 0 rows affected (0.01 sec) mysql> GRANT REPLICATION CLIENT, REPLICATION SLAVE ON *.* TO 'repl_user'@'%' IDENTIFIED BY 'password'; Query OK, 0 rows affected (0.02 sec) mysql> select Host, User from mysql.user; +-----------+-----------+ | Host | User | +-----------+-----------+ | % | dbadmin | | % | repl_user | | localhost | dbadmin | | localhost | rdsadmin | +-----------+-----------+ 4 rows in set (0.00 sec) mysql>
次に、オレゴンリージョンのレプリカでレプリケーションの設定をします。
$ mysql -u dbadmin -h oregon-aurora-cluster.cluster-cc1iyznyna5w.us-west-2.rds.amazonaws.com -p Enter password: Welcome to the MySQL monitor. Commands end with ; or \g. Your MySQL connection id is 115 Server version: 5.6.10 MySQL Community Server (GPL) Copyright (c) 2000, 2015, Oracle and/or its affiliates. All rights reserved. Oracle is a registered trademark of Oracle Corporation and/or its affiliates. Other names may be trademarks of their respective owners. Type 'help;' or '\h' for help. Type '\c' to clear the current input statement. mysql> use testdb Reading table information for completion of table and column names You can turn off this feature to get a quicker startup with -A Database changed mysql> CALL mysql.rds_set_external_master ('tokyo-aurora-cluster.cluster-abcdef123456.ap-northeast-1.rds.amazonaws.com', 3306,'repl_user', 'password', 'mysql-bin-changelog.000001', 53556, 0); Query OK, 0 rows affected (0.02 sec) mysql> CALL mysql.rds_start_replication; +-------------------------+ | Message | +-------------------------+ | Slave running normally. | +-------------------------+ 1 row in set (1.01 sec) Query OK, 0 rows affected (1.01 sec) mysql>
動作確認をして、問題なければ、レプリカを読み取り専用にします。
mysql> select * from sample where id = '1'; +----+----------+--------------------------------+-------+---------------------+ | id | name | description | price | created_at | +----+----------+--------------------------------+-------+---------------------+ | 1 | product1 | c1e9ed5dce495cae2f094b164721b3 | 8180 | 2014-02-20 22:28:07 | +----+----------+--------------------------------+-------+---------------------+ 1 row in set (0.00 sec) mysql> UPDATE sample SET -> name = CONCAT('product', id), -> description = SUBSTRING(MD5(RAND()), 1, 30), -> price = CEIL(RAND() * 10000), -> created_at = ADDTIME(CONCAT_WS(' ','2014-01-01' + INTERVAL RAND() * 180 DAY, '00:00:00'), SEC_TO_TIME(FLOOR(0 + (RAND() * 86401)))) -> where id = '1'; Query OK, 1 row affected (0.01 sec) Rows matched: 1 Changed: 1 Warnings: 0 mysql> select * from sample where id = '1'; +----+----------+--------------------------------+-------+---------------------+ | id | name | description | price | created_at | +----+----------+--------------------------------+-------+---------------------+ | 1 | product1 | 1fafcd01bd59a8326d5d0d325ecca7 | 4259 | 2014-04-17 15:57:45 | +----+----------+--------------------------------+-------+---------------------+ 1 row in set (0.02 sec) mysql>
mysql> select * from sample where id = '1'; +----+----------+--------------------------------+-------+---------------------+ | id | name | description | price | created_at | +----+----------+--------------------------------+-------+---------------------+ | 1 | product1 | c1e9ed5dce495cae2f094b164721b3 | 8180 | 2014-02-20 22:28:07 | +----+----------+--------------------------------+-------+---------------------+ 1 row in set (0.00 sec) mysql> mysql> select * from sample where id = '1'; +----+----------+--------------------------------+-------+---------------------+ | id | name | description | price | created_at | +----+----------+--------------------------------+-------+---------------------+ | 1 | product1 | 1fafcd01bd59a8326d5d0d325ecca7 | 4259 | 2014-04-17 15:57:45 | +----+----------+--------------------------------+-------+---------------------+ 1 row in set (0.00 sec) mysql>
レプリカを読み取り専用にするために、パラメータグループを作成します。 タイプはDB Parameter Groupで、read_onlyパラメータの値を1にします。
作成したパラメータグループを設定し、反映のためにインスタンスを再起動します。
以上で完成です。
さいごに
今回は、Auroraの動作確認をしている中で、クロスリージョンレプリカが作成できないことに気づき、少し工夫を加えて実現してみました。 そこまで需要のある構成ではないと思いますが、もし何かで検討される機会があれば参考にして頂けると幸いです。