ちょっと話題の記事

【新サービス】Amazon Aurora Multi-Masterが一般公開になりました

re:Invent 2017でアナウンスされていたAmazon Auroraのマルチマスタ機能が一般公開されましたのでレポートします。RDBMSに極めて高い可用性が必要な場合に有用だと思われます。

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

大栗です。

re:Invent 2017でアナウンスされていたAmazon Auroraのマルチマスタ機能が一般公開されましたのでレポートします。

Amazon Aurora Multi-Master

Aurora Multi-Masterはre:Invent 2017に発表された機能で、複数ノードに書き込みが行える高可用性なクラスタ構成です。現在は1つのリージョン内で複数のAZに跨って構成できます。そもそもAmazon Auroraはシングルマスタ・クラスタでもSLAが99.99%を誇りますが、更に高い可用性を期待できる構成となります。

【速報】Amazon Auroraのマルチマスタ機能が発表されました! #reinvent

このようにストレージを3AZに分散して持ち複数のデータベースノード上で書き込みが可能で、DBインスタンス間で書き込み後の読み込み整合性を持ちます。

https://aws.amazon.com/jp/blogs/database/building-highly-available-mysql-applications-using-amazon-aurora-mmsr/

Aurora Multi-Masterはマスタ間の整合性がシングルマスタと異なる場合があるので、利用時に十分に注意する必要があります。マスチマスタ・クラスタは、セッションレベルで構成できるグローバル書き込み後読み取り(GRAW)モデルをサポートしています。Aurora Multi-Masterの整合性モデルについては別途まとめてブログを書きたいと思います。

特に重要な点としては、以下のような点が考えられるのでご注意ください。

  • SERIALIZABLEトランザクション分離レベルをサポートしていないなど、Auroraシングルマスタを使用した既存のアプリケーションはそのままでは対応できない可能性があります。
  • DDL、DML、DCLステートメントでは、エンドポイントやコネクションルーティングにラウンドロビンやランダムの方式を使用しないでください。
  • マルチマスタ・クラスタでロックがサポートされますが、ロックのスコープはコマンドが実行されたノード内です。

リージョン

現在は以下のリージョンでAurora Multi-Masterが利用できます。残念ながらファーストリリースには東京が入っていませんでした。

  • 米国東部 (バージニア北部)
  • 米国東部 (オハイオ)
  • 米国西部 (オレゴン)
  • EU (アイルランド)

制限や考慮事項

まだまだ発展中のサービスなので制限事項が色々あります。

AWSとAuroraの制限

マルチマスタ・クラスタにはAWSとAuroraの機能に以下の制限があります。個人的には『このような場合、マルチマスタークラスタの利点は、パフォーマンスよりも高可用性にあります。』の内容が要注意です。

  • 現在、マルチマスタ・クラスタに最大2つのDBインスタンスを持てます。
  • 現在、マルチマスタ・クラスタのすべてのDBインスタンスは同じAWSリージョンになければなりません。
  • マルチマスタ・クラスタから、リージョン間レプリケーションを有効にできません。
  • 停止操作は、マルチマスタ・クラスタでは使用できません。
  • Auroraの存続できるキャッシュは、マルチマスタ・クラスタではサポートされていません。
  • マルチマスタ・クラスタでは、コネクションの負荷分散はされません。アプリケーションには、複数のDBインスタンスエンドポイント間で読取りと書込み操作を分散する独自のコネクション管理ロジックを実装する必要があります。通常、bring-your-own-shard(BYOS)アプリケーションには、各シャードを特定のコネクションに割り当てるロジックが既にあります。アプリケーションのコネクション管理ロジックを調整する方法については、 Connection Management for Multi-Master Clustersを参照してください。
  • マルチマスタ・クラスタには、DBインスタンス間の調整のためのプロセスとネットワークのオーバーヘッドがあります。このオーバーヘッドは、書き込み集中や読み取り集中のアプリケーションに次のような影響を与えます。
  • スループットのメリットが最も顕著なのは、複数の書き込み操作が同時に実行される忙しいクラスタです。多くの場合、単一のプライマリインスタンスを持つ従来のAuroraクラスタでは、クラスタの書き込みトラフィックを処理できます。このような場合、マルチマスタークラスタの利点は、パフォーマンスよりも高可用性にあります。
  • 単一問合せの性能は、通常、同等のシングルマスタ・クラスタよりも低くなります。
  • シングルマスタ・クラスタで作成したスナップショットを、マルチマスタ・クラスタでリストアできません。その代わり、ある種類のクラスタから別の種類のクラスタにすべてのデータを転送するには、AWS Database Migration Service (AWS DMS) やmysqldumpコマンドなどのツールで作成した論理ダンプを使用します。
  • マルチマスタ・クラスタでは、並列クエリ、Serverless、またはGlobal Databases機能を使用できません。マルチマスタは、クラスタの恒久的な選択肢です。マルチマスタ・クラスターとServerlessクエリや並列クエリなどの別の種類との間で既存を切り替えることはできません。
  • マルチマスタ・クラスタでは、ダウンタイム無しパッチ(ZDP)とダウンタイム無し再起動(ZDR)機能を使用できません。
  • マルチマスタ・クラスタでは、AWS LambdaやAmazon S3、AWS Identity and Access Managementといった他のAWSサービスとの統合は利用できません。
  • Performance Insights機能は、マルチマスタ・クラスタでは使用できません。
  • マルチマスタ・クラスタはクローンできません。
  • マルチマスタ・クラスタではバックトラック機能を有効にできません。

DBエンジンの制限

マルチマスタ・クラスタで使用できるデータベース・エンジン機能には、次の制限が適用されます。

  • マルチマスタ・クラスタとの間でバイナリログ(binlog)レプリケーションを実行できません。この制限は、マルチマスタークラスタではグローバルトランザクションID(GTID)レプリケーションも使用できないことを意味します。
  • イベントスケジューラは、マルチマスタ・クラスタでは使用できません。
  • ハッシュジョイン最適化は、マルチマスタ・クラスタでは有効になりません。
  • マルチマスタ・クラスタではクエリキャッシュを使用できません。
  • マルチマスタ・クラスタでは、特定のSQL言語機能を使用できません。SQLの違いの完全なリストとこれらの制限に対処するためにSQLコードを適合させる方法については、

SQL Considerations for Multi-Master Clusters を参照してください。

やってみた

ここでは米国西部 (オレゴン)リージョンでコンソールから試してみます。

クラスタの起動

RDSのコンソールからデータベースの作成をクリックします。

以下の内容を選択します。なお、コンソールのインターフェイスが古い場合には新しいものに切り替えて下さい。

項目 内容
エンジンのタイプ Amazon Aurora
エディション MySQL との互換性を持つ Amazon Aurora
バージョン Aurora (MySQL)-5.6.10a
データベースロケーション リージョン別

データベースの機能で複数のライターを選択します。これがAurora Multi-Masterの選択になります。

各々の項目に任意の内容を設定します。

DBインスタンスサイズは、以下の3種類から選択できます。

  • db.r4.2xlarge
  • db.r4.4xlarge
  • db.r4.8xlarge

マルチ AZ 配置で別の AZ で Aurora レプリカ/リーダーノードを作成するを選択してデータベースの作成をクリックします。

しばらく経つとAuroraクラスタが起動します。

基本動作の確認

EC2を起動してログインします。ここではAmazon Linux 2で起動しています。

MySQLクライアントをインストールします。(Amazon Linux 2なので実態はMariaDBですが)

$ sudo yum install mysql -y

まずは、各々のエンドポイントの状況を確認しています。クラスタエンドポイントの名前解決をしてみます。以下のようになり、何度確認しても解決されるIPアドレスは変わらないようです。

$ dig +short aurora-multi-master.cluster-abcdefghijkl.us-west-2.rds.amazonaws.com
aurora-multi-master.cluster-abcdefghijkl.us-west-2.rds.amazonaws.com
172.31.12.215

1台目のインスタンスにログインしてみます。ごく普通にログインできます。

$ mysql -uadmin -pmypassword -h aurora-multi-master-instance-1.abcdefghijkl.us-west-2.rds.amazonaws.com
Welcome to the MariaDB monitor.  Commands end with ; or \g.
Your MySQL connection id is 206
Server version: 5.6.10 MySQL Community Server (GPL)

Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

MySQL [(none)]>

2台目のインスタンスにもログインしてみます。こちらもごく普通にログインできます。

$ mysql -uadmin -pmypassword -h aurora-multi-master-instance-1-us-west-2b.abcdefghijkl.us-west-2.rds.amazonaws.com
Welcome to the MariaDB monitor.  Commands end with ; or \g.
Your MySQL connection id is 178
Server version: 5.6.10 MySQL Community Server (GPL)

Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

MySQL [(none)]>

1台目でデータベースをテーブルを作成して、データを挿入してみます。

$ mysql -uadmin -pmypassword -h aurora-multi-master-instance-1.abcdefghijkl.us-west-2.rds.amazonaws.com
Welcome to the MariaDB monitor.  Commands end with ; or \g.
Your MySQL connection id is 206
Server version: 5.6.10 MySQL Community Server (GPL)

Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

MySQL [(none)]> create database mydb;
Query OK, 1 row affected (0.32 sec)

MySQL [(none)]> use mydb;
Database changed
MySQL [mydb]> create table sample_table (
    -> col1 int not null primary key,
    -> col2 varchar(1024),
    -> col3 date);
Query OK, 0 rows affected (0.72 sec)

MySQL [mydb]> insert into sample_table (col1, col2, col3)
    ->  values (1, 'ABCDEFGH', now());
Query OK, 1 row affected, 1 warning (0.02 sec)

MySQL [mydb]> commit;
Query OK, 0 rows affected (0.00 sec)

普通にデータが見えます。

MySQL [mydb]> select * from sample_table;
+------+----------+------------+
| col1 | col2     | col3       |
+------+----------+------------+
|    1 | ABCDEFGH | 2019-08-09 |
+------+----------+------------+
1 row in set (0.00 sec)

今度は2台目のインスタンスでログインしてデータを挿入します。別のノードからでも挿入可能です。

$ mysql -uadmin -pmypassword -h aurora-multi-master-instance-1-us-west-2b.abcdefghijkl.us-west-2.rds.amazonaws.com
Welcome to the MariaDB monitor.  Commands end with ; or \g.
Your MySQL connection id is 178
Server version: 5.6.10 MySQL Community Server (GPL)

Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

MySQL [(none)]> use mydb
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 [mydb]> insert into sample_table (col1, col2, col3)
    ->  values (2, 'IJKLMNOP', now());
Query OK, 1 row affected, 1 warning (0.01 sec)

MySQL [mydb]> commit;
Query OK, 0 rows affected (0.00 sec)

MySQL [mydb]> select * from sample_table;
+------+----------+------------+
| col1 | col2     | col3       |
+------+----------+------------+
|    1 | ABCDEFGH | 2019-08-09 |
|    2 | IJKLMNOP | 2019-08-09 |
+------+----------+------------+
2 rows in set (0.00 sec)

インスタンス間のトランザクションの確認

次にトランザクションを試します。

1台目でトランザクションを開始して、挿入をします。そのままコミットせずに待ちます。

1台目

MySQL [mydb]> START TRANSACTION;
Query OK, 0 rows affected (0.00 sec)

MySQL [mydb]> insert into sample_table (col1, col2, col3)
    ->  values (3, 'ABCDEFGH', now());
Query OK, 1 row affected, 1 warning (0.00 sec)

2台目でトランザクションを開始して、同じキーで挿入します。するとデッドロックが発生します。1台目で挿入中のデータは見えない状態です。

2台目

MySQL [mydb]> insert into sample_table (col1, col2, col3)
    ->  values (3, 'IJKLMNOP', now());
ERROR 1213 (40001): Deadlock found when trying to get lock; try restarting transaction
MySQL [mydb]> select * from sample_table;
+------+----------+------------+
| col1 | col2     | col3       |
+------+----------+------------+
|    1 | ABCDEFGH | 2019-08-09 |
|    2 | IJKLMNOP | 2019-08-09 |
+------+----------+------------+
2 rows in set (0.00 sec)

1台目に戻ってコミットします。

1台目

MySQL [mydb]> commit;
Query OK, 0 rows affected (0.01 sec)

MySQL [mydb]> select * from sample_table;
+------+----------+------------+
| col1 | col2     | col3       |
+------+----------+------------+
|    1 | ABCDEFGH | 2019-08-09 |
|    2 | IJKLMNOP | 2019-08-09 |
|    3 | ABCDEFGH | 2019-08-09 |
+------+----------+------------+
3 rows in set (0.00 sec)

2台目でもう一度同じキーで挿入を試してみます。すると今度は主キー重複エラーとなります。

2台目

MySQL [mydb]> insert into sample_table (col1, col2, col3)
    ->  values (3, 'IJKLMNOP', now());
ERROR 1062 (23000): Duplicate entry '3' for key 'PRIMARY'

インスタンス間の操作の時間が十分に離れていると、問題無くトランザクション制御されるようです。

さいごに

Aurora Multi-Masterは極めて高いDBの可用性を求める場合に有用なサービスだと考えられます。しかし、トランザクションや一部機能で、既存アプリケーションではそのまま対応できない場合があるので注意しましょう。

既存のシングルマスタ・クラスタでも、アプリケーションを変更せずに高速にフェイルオーバーさせて、可用性を高めることも可能なので十分に検証した上で使用する構成を選択しましょう。

専用ドライバ無しでAuroraの高速フェイルオーバーに対応してみる