Auroraクラスターのリードレプリカとエンドポイントを確認する構成
AWS SAAの出題範囲の1つでもある、高性能アーキテクチャの設計に関する内容です。
Auroraリードレプリカを作成し、デフォルトで用意されるAuroraエンドポイントの挙動を確認します。
アクセスするエンドポイントを使い分けることによって、書き込み先と読み込み先のインスタンスを分離することができるようになります。
構築する環境
2つのAZに合計3つのプライベートサブネットを作成します。
AuroraクラスターをAZが異なる2つのプライベートサブネットにまたがるように配置します。クラスター内に2つのDBインスタンスを作成します。一方はプライマリサーバ、もう一方はリードレプリカとして動作します。AuroraクラスターはMySQLタイプとします。
プライベートサブネットの1つに、EC2インスタンスを配置します。このEC2インスタンスはAuroraクラスターへアクセスするクライアントとして使用します。EC2インスタンスは、最新版のAmazon Linux2のAMIをベースにします。
S3用VPCエンドポイントを作成します。Auroraクラスターに接続するためのクライアントを、EC2インスタンスにインストールするためです。
環境構築用のCloudFormationテンプレートファイル
上記の構成をCloudFormationで構築します。
以下のURLにCloudFormationテンプレートを配置してます。
https://github.com/awstut-an-r/awstut-saa/tree/main/02/006
テンプレートファイルのポイント解説
今回のアーキテクチャを構成するための、各テンプレートファイルのポイントを取り上げます。
Auroraクラスターにリードレプリカを作成する
Auroraクラスターを確認します。
Resources:
DBCluster:
Type: AWS::RDS::DBCluster
Properties:
DatabaseName: !Ref DBName
DBClusterIdentifier: !Sub ${Prefix}-DBCluster
DBSubnetGroupName: !Ref DBSubnetGroup
Engine: !Ref DBEngine
EngineVersion: !Ref DBEngineVersion
MasterUsername: !Ref DBUser # cannot use "-".
MasterUserPassword: !Ref DBPassword # cannot use "/@'"
StorageEncrypted: true
VpcSecurityGroupIds:
- !Ref DBSecurityGroup
DBSubnetGroup:
Type: AWS::RDS::DBSubnetGroup
Properties:
DBSubnetGroupName: !Sub ${Prefix}-dbsubnetgroup # must be lowercase alphanumeric characters or hyphens.
DBSubnetGroupDescription: Test DBSubnetGroup for Aurora.
SubnetIds:
- !Ref PrivateSubnet2
- !Ref PrivateSubnet3
Code language: YAML (yaml)
Auroraは通常のRDSと異なり、クラスターを形成します。
Amazon Aurora DB クラスターは、1 つ以上の DB インスタンスと、これらの DB インスタンスのデータを管理する 1 つのクラスターボリュームで構成されます。Aurora クラスターボリュームは、複数のアベイラビリティーゾーンにまたがる仮想データベースストレージボリュームです。各アベイラビリティーゾーンには DB クラスターデータのコピーが保存されます。
Amazon Aurora DB クラスター
クラスターでは、データベースエンジンのタイプやバージョン、ユーザ情報、ネットワーク周りの設定を行います。
EngineおよびEngineVersionプロパティで、クラスター内に作成するDBインスタンスのタイプやバージョンを指定します。今回は下記の通り指定することで、MySQL8.0バージョンの最新版(2022年3月時点)のDBインスタンスを作成するように設定します。
- Engineプロパティ:aurora-mysql
- EngineVersionプロパティ:8.0.mysql_aurora.3.01.0
なおEngineプロパティに「aurora」と指定しますと、MySQL5.6バージョンのインスタンスが作成されますのでご注意ください。
Engine
The name of the database engine to be used for this DB cluster.
AWS::RDS::DBCluster
Valid Values: aurora (for MySQL 5.6-compatible Aurora), aurora-mysql (for MySQL 5.7-compatible Aurora), and aurora-postgresql
MySQLユーザーの設定は、MasterUsernameおよびMasterUserPasswordプロパティで行います。今回は両プロパティを下記の通り設定します。
- MasterUsernameプロパティ:testuser
- MasterUserPasswordプロパティ:Passw0rd
DatabaseNameプロパティで、デフォルトで作成するデータベースの名前を指定することができます。今回は「testdb」という名前のデータベースを作成するように指定します。
DBSubnetGroupNameプロパティで、クラスターを展開するサブネットを設定します。今回は2つのプライベートサブネットを指定するようにDBサブネットグループリソースを定義し、これを本プロパティに指定します。
VpcSecurityGroupIdsプロパティで、本クラスターに適用するセキュリティグループを指定します。EC2インスタンスからMySQL標準ポート(3306/tcp)に対する通信を許可するように指定します。
Auroraクラスターにリードレプリカを作成する
Auroraクラスター内に作成するDBインスタンスを確認します。ポイントはリードレプリカの作成方法です。
Resources:
DBInstance1:
Type: AWS::RDS::DBInstance
Properties:
DBClusterIdentifier: !Ref DBCluster
DBSubnetGroupName: !Ref DBSubnetGroup
DBInstanceIdentifier: !Sub ${Prefix}-DBInstance1
DBInstanceClass: !Ref DBInstanceClass
Engine: !Ref DBEngine
AvailabilityZone: !Sub ${AWS::Region}${AvailabilityZone1}
PubliclyAccessible: false
DBInstance2:
Type: AWS::RDS::DBInstance
Properties:
DBClusterIdentifier: !Ref DBCluster
DBSubnetGroupName: !Ref DBSubnetGroup
DBInstanceIdentifier: !Sub ${Prefix}-DBInstance2
DBInstanceClass: !Ref DBInstanceClass
Engine: !Ref DBEngine
AvailabilityZone: !Sub ${AWS::Region}${AvailabilityZone2}
PubliclyAccessible: false
Code language: YAML (yaml)
今回は2つのDBインスタンスを作成するため、同様の設定のインスタンスを2つ定義します。
Auroraクラスター内に、2台目以降のインスタンスを作成すると、自動的にそのインスタンスはリードレプリカとして動作します。
一方はプライマリインスタンスとして動作し、もう一方はリードレプリカとして動作することになります。実際にどちらの役割で動作するかは、起動後に確認する必要があります。
ユーザーデータでMySQLクライアントをインストールする
EC2インスタンスを確認します。ポイントはユーザーデータによるインスタンスの初期化処理です。
Resources:
Instance:
Type: AWS::EC2::Instance
Properties:
IamInstanceProfile: !Ref InstanceProfile
ImageId: !Ref ImageId
InstanceType: !Ref InstanceType
NetworkInterfaces:
- DeviceIndex: 0
SubnetId: !Ref PrivateSubnet
GroupSet:
- !Ref InstanceSecurityGroup
UserData: !Base64 |
#!/bin/bash -xe
yum update -y
yum install -y mariadb
Code language: YAML (yaml)
今回のEC2インスタンスの役目は、MySQLタイプのRDSインスタンスにアクセスするクライアントとしての働きです。ですからMySQLクライアントをインストールする必要があります。
Amazon Linux 2の場合、MySQLクライアントはmariadbパッケージからインストールできます。同パッケージはS3バケット上に構築されているAmazon Linuxリポジトリから取得可能です。今回はS3用VPCエンドポイント経由で、同リポジトリにアクセスします。
RDSインスタンスのクライアントツールおよび接続方法については、以下のページをご確認ください。
EC2インスタンスの初期化処理はいくつかありますが、今回はユーザーデータを使用します。
ユーザーデータはUserDataプロパティで設定します。今回はMySQLクライアントを含むリポジトリをインストール後、同クライアントをインストールする処理を記載します。先述のmariadbパッケージのインストール処理を記載します。
ユーザーデータを含むインスタンスの初期化処理に関する詳細は、以下のページもご確認ください。
環境構築
CloudFormationを使用して、本環境を構築し、実際の挙動を確認します。
CloudFormationスタックを作成し、スタック内のリソースを確認する
CloudFormationスタックを作成します。
スタックの作成および各スタックの確認方法については、以下のページをご確認ください。
各スタックのリソースを確認した結果、今回作成された主要リソースの情報は以下の通りです。
- Auroraクラスター:saa-02-006-dbcluster
- DBインスタンス1:saa-02-006-dbinstance1
- DBインスタンス2:saa-02-006-dbinstance2
- EC2インスタンス:i-0a58e05aa21df2ea8
AWS Management Consoleからも、リソースの作成状況を確認します。まずRDS全体のリソースを確認します。
確かにAuroraクラスターが作成され、その中に、2つのDBインスタンスが作成されていることがわかります。
クラスターに、以下の2つのエンドポイントが作成されていることもわかります。
- クラスターエンドポイント:saa-02-006-dbcluster.cluster-cl50iikpthxs.ap-northeast-1.rds.amazonaws.com
- リーダーエンドポイント:saa-02-006-dbcluster.cluster-ro-cl50iikpthxs.ap-northeast-1.rds.amazonaws.com
加えて2つのインスタンスの役割もわかります。
DBインスタンス1は「Writer instance」とありますので、プライマリインスタンスです。
DBインスタンス2は「Reader instance」とありますので、リードレプリカです。
各インスタンスの状況も確認します。
各インスタンスにも個別のエンドポイント(インスタンスエンドポイント)が作成されています。
- DBインスタンス1のインスタンスエンドポイント:saa-02-006-dbinstance1.cl50iikpthxs.ap-northeast-1.rds.amazonaws.com
- DBインスタンス2のインスタンスエンドポイント:saa-02-006-dbinstance2.cl50iikpthxs.ap-northeast-1.rds.amazonaws.com
MySQLクライアントを確認する
準備が整いましたので、Auroraの挙動を確認します。
確認はEC2インスタンスにアクセスした上で、実施します。
EC2インスタンスへのアクセスは、SSM Session Managerを使用します。詳細は以下のページをご確認ください。
% aws ssm start-session --target i-04eaedaa85d35cb48
Starting session with SessionId: root-0ab3667141ef0d68d
sh-4.2$
Code language: Bash (bash)
ユーザーデータで設定したパッケージのインストール状況を確認します。
sh-4.2$ sudo yum list installed | grep mariadb
mariadb.aarch64 1:5.5.68-1.amzn2 @amzn2-core
mariadb-libs.aarch64 1:5.5.68-1.amzn2 installed
Code language: Bash (bash)
確かにmariadbパッケージがインストールされています。
mysqlクライアントのバージョンを確認します。
sh-4.2$ mysql -V
mysql Ver 15.1 Distrib 5.5.68-MariaDB, for Linux (aarch64) using readline 5.1
Code language: Bash (bash)
バージョンが表示され、正常にクライアントが動作しました。
Auroraクラスターのエンドポイントを名前解決
先ほど確認したクラスターのエンドポイントを名前解決してみます。
sh-4.2$ nslookup saa-02-006-dbcluster.cluster-cl50iikpthxs.ap-northeast-1.rds.amazonaws.com
Server: 10.0.0.2
Address: 10.0.0.2#53
Non-authoritative answer:
saa-02-006-dbcluster.cluster-cl50iikpthxs.ap-northeast-1.rds.amazonaws.com canonical name = saa-02-006-dbinstance1.cl50iikpthxs.ap-northeast-1.rds.amazonaws.com.
Name: saa-02-006-dbinstance1.cl50iikpthxs.ap-northeast-1.rds.amazonaws.com
Address: 10.0.2.40
Code language: Bash (bash)
sh-4.2$ nslookup saa-02-006-dbcluster.cluster-ro-cl50iikpthxs.ap-northeast-1.rds.amazonaws.com
Server: 10.0.0.2
Address: 10.0.0.2#53
Non-authoritative answer:
saa-02-006-dbcluster.cluster-ro-cl50iikpthxs.ap-northeast-1.rds.amazonaws.com canonical name = saa-02-006-dbinstance2.cl50iikpthxs.ap-northeast-1.rds.amazonaws.com.
Name: saa-02-006-dbinstance2.cl50iikpthxs.ap-northeast-1.rds.amazonaws.com
Address: 10.0.3.206
Code language: Bash (bash)
2つのエンドポイントにCNAMEで設定されていることがわかります。
クラスターエンドポイントにアクセスすると、プライマリインスタンスであるDBインスタンス1にアクセスすることになります。
リーダーエンドポイントにアクセスすると、リードレプリカであるDBインスタンス2にアクセスすることになります。
クラスターエンドポイントにアクセスする
いよいよAuroraクラスターにアクセスします。
まずクラスターエンドポイントにアクセスします。
sh-4.2$ mysql -h saa-02-006-dbcluster.cluster-cl50iikpthxs.ap-northeast-1.rds.amazonaws.com -P 3306 -u testuser -p testdb
Enter password:
Welcome to the MariaDB monitor. Commands end with ; or \g.
Your MySQL connection id is 24
Server version: 8.0.23 Source distribution
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 [testdb]>
Code language: Bash (bash)
正常にAuroraクラスターのtestdbにアクセスすることができました。
検証用のテーブルを作成します。
テーブルに作成するカラムですが、現在日時を保存することを目的として、datetime型のdatetimeを定義します。
MySQL [testdb]> create table testtable (datetime datetime);
Query OK, 0 rows affected (0.03 sec)
MySQL [testdb]> show tables;
+------------------+
| Tables_in_testdb |
+------------------+
| testtable |
+------------------+
1 row in set (0.00 sec)
Code language: Bash (bash)
テーブルの準備が整いました。
実際に現在日時を書き込み、テーブルの中身を読み込みます。
MySQL [testdb]> insert into testtable (datetime) values (now());
Query OK, 1 row affected (0.01 sec)
MySQL [testdb]> select * from testtable;
+---------------------+
| datetime |
+---------------------+
| 2022-03-23 08:28:46 |
+---------------------+
1 row in set (0.00 sec)
Code language: Bash (bash)
正常に書き込むことができました。
以上のことから、クラスターエンドポイントにアクセスすると、データーベースに対して、読み書きができることがわかりました。
リーダーエンドポイントにアクセスする
リーダーエンドポイントにアクセスして、挙動を確認します。
sh-4.2$ mysql -h saa-02-006-dbcluster.cluster-ro-cl50iikpthxs.ap-northeast-1.rds.amazonaws.com -P 3306 -u testuser -p testdb
Enter password:
...
MySQL [testdb]>
Code language: Bash (bash)
testtableに対して読み込み処理を実行します。
MySQL [testdb]> show tables;
+------------------+
| Tables_in_testdb |
+------------------+
| testtable |
+------------------+
1 row in set (0.00 sec)
MySQL [testdb]> select * from testtable;
+---------------------+
| datetime |
+---------------------+
| 2022-03-23 08:28:46 |
+---------------------+
1 row in set (0.01 sec)
Code language: Bash (bash)
確かに読み込むことができます。
試しに書き込みを試みます。
MySQL [testdb]> insert into testtable (datetime) values (now());
ERROR 1836 (HY000): Running in read-only mode
Code language: Bash (bash)
エラーが発生しました。
読み込み専用でアクセスしているため、書き込み処理が実行できない旨のメッセージが出力されます。
以上のことから、リーダーエンドポイントにアクセスすると、データーベースに対して、読み込みだけができることがわかりました。
インススタンスエンドポイントにアクセスする1
インスタンスに用意されたエンドポイントにもアクセスし、挙動を確認します。
まずプライマリインスタンスにアクセスします。
sh-4.2$ mysql -h saa-02-006-dbinstance1.cl50iikpthxs.ap-northeast-1.rds.amazonaws.com -P 3306 -u testuser -p testdb
Enter password:
...
MySQL [testdb]>
Code language: Bash (bash)
正常にアクセスできました。
読み書きを実行します。
MySQL [testdb]> select * from testtable;
+---------------------+
| datetime |
+---------------------+
| 2022-03-23 08:28:46 |
+---------------------+
1 row in set (0.00 sec)
Code language: Bash (bash)
MySQL [testdb]> insert into testtable (datetime) values (now());
Query OK, 1 row affected (0.01 sec)
MySQL [testdb]> select * from testtable;
+---------------------+
| datetime |
+---------------------+
| 2022-03-23 08:28:46 |
| 2022-03-23 08:33:02 |
+---------------------+
2 rows in set (0.00 sec)
Code language: Bash (bash)
以上のことから、書き込み用であるプライマリインスタンスのエンドポイントにアクセスすると、データーベースに対して、読み書きができることがわかりました。
インススタンスエンドポイントにアクセスする2
続いてリードレプリカインスタンスにアクセスします。
sh-4.2$ mysql -h saa-02-006-dbinstance2.cl50iikpthxs.ap-northeast-1.rds.amazonaws.com -P 3306 -u testuser -p testdb
Enter password:
...
MySQL [testdb]>
Code language: Bash (bash)
正常にアクセスできました。
読み書きを実行します。
MySQL [testdb]> select * from testtable;
+---------------------+
| datetime |
+---------------------+
| 2022-03-23 08:28:46 |
| 2022-03-23 08:33:02 |
+---------------------+
2 rows in set (0.00 sec)
Code language: Bash (bash)
MySQL [testdb]> insert into testtable (datetime) values (now());
ERROR 1836 (HY000): Running in read-only mode
Code language: Bash (bash)
読み込みはできましたが、書き込みには失敗しました。
以上のことから、リードレプリカインスタンスのエンドポイントにアクセスすると、データーベースに対して、読み込みだけができることがわかりました。
まとめ
検証結果をまとめます。
エンドポイント | 読み込み | 書き込み |
クラスターエンドポイント | ● | ● |
リーダーエンドポイント | ● | × |
インスタンスエンドポイント(プライマリインスタンス) | ● | ● |
インスタンスエンドポイント(リードレプリカインスタンス) | ● | × |