Auroraクラスターのリードレプリカとエンドポイント

目次

Auroraクラスターのリードレプリカとエンドポイントを確認する構成

AWS SAAの出題範囲の1つでもある、高性能アーキテクチャの設計に関する内容です。
Auroraリードレプリカを作成し、デフォルトで用意されるAuroraエンドポイントの挙動を確認します。
アクセスするエンドポイントを使い分けることによって、書き込み先と読み込み先のインスタンスを分離することができるようになります。

構築する環境

Diagram of Read Replica and Endpoints of Aurora Cluster.

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.
Valid Values: aurora (for MySQL 5.6-compatible Aurora), aurora-mysql (for MySQL 5.7-compatible Aurora), and aurora-postgresql

AWS::RDS::DBCluster

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インスタンスのクライアントツールおよび接続方法については、以下のページをご確認ください。

あわせて読みたい
AL2で全RDSに接続する方法まとめ 【Amazon Linux 2からRDSの全DBエンジンに接続する方法】 2022年現在、RDSは以下の7種類のDBエンジンを提供しています。 Aurora(PostgreSQL) Aurora(MySQL) PostgreSQL ...

EC2インスタンスの初期化処理はいくつかありますが、今回はユーザーデータを使用します。
ユーザーデータはUserDataプロパティで設定します。今回はMySQLクライアントを含むリポジトリをインストール後、同クライアントをインストールする処理を記載します。先述のmariadbパッケージのインストール処理を記載します。
ユーザーデータを含むインスタンスの初期化処理に関する詳細は、以下のページもご確認ください。

あわせて読みたい
Linuxインスタンスの初期化方法4選 【Linuxインスタンスを初期化する4つの方法】 EC2インスタンスの起動時に初期化処理を実行する方法を考えます。 EC2インスタンスを構築時に初期化する以下の4つの手法を...

環境構築

CloudFormationを使用して、本環境を構築し、実際の挙動を確認します。

CloudFormationスタックを作成し、スタック内のリソースを確認する

CloudFormationスタックを作成します。
スタックの作成および各スタックの確認方法については、以下のページをご確認ください。

あわせて読みたい
CloudFormationのネストされたスタックで環境を構築する 【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全体のリソースを確認します。

Endpoints of the Aurora cluster.

確かに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」とありますので、リードレプリカです。

各インスタンスの状況も確認します。

Instance endpoint of DB instance 2
Instance endpoint of DB instance 1

各インスタンスにも個別のエンドポイント(インスタンスエンドポイント)が作成されています。

  • 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を使用します。詳細は以下のページをご確認ください。

あわせて読みたい
LinuxインスタンスにSSM Session Manager経由でアクセスする 【LinuxインスタンスにSSM Session Manager経由でアクセスする】 EC2インスタンスにSSM Session Manager経由でアクセスする構成を確認します。 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.1Code 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)

読み込みはできましたが、書き込みには失敗しました。

以上のことから、リードレプリカインスタンスのエンドポイントにアクセスすると、データーベースに対して、読み込みだけができることがわかりました。

まとめ

検証結果をまとめます。

エンドポイント読み込み書き込み
クラスターエンドポイント
リーダーエンドポイント×
インスタンスエンドポイント(プライマリインスタンス)
インスタンスエンドポイント(リードレプリカインスタンス)×
目次