CFNでRDSリードレプリカを作成する

CloudFormationを使用して、RDSリードレプリカを作成する

以下のページで、マルチAZ配置を取り上げました。

あわせて読みたい
CFNでマルチAZ配置のRDSを作成する 【CloudFormationを使用して、マルチAZ配置のRDSを作成する】 RDSが提供する機能の1つにマルチAZ配置があります。 Amazon RDS マルチ AZ 配置では、Amazon RDS はプライ...

RDSが提供する機能の1つにリードレプリカがあります。

プライマリ DB インスタンスに対して行った更新は、リードレプリカに非同期的にコピーされます。読み込みクエリをアプリケーションからリードレプリカにルーティングすることにより、プライマリ DB インスタンスの負荷を軽減できます。リードレプリカを使うと、単一 DB インスタンスのキャパシティ制約にとらわれることなく伸縮自在にスケールアウトし、読み込み負荷の高いデータベースワークロードに対応できます。

リードレプリカの使用

今回はCloudFormationを使用して、リードレプリカを作成します。
加えてリードレプリカの昇格方法についても確認します。

構築する環境

Diagram of RDS Read Replica using CloudFormation

RDS DBインスタンスを2つ作成します。
1つはプライマリインスタンス、もう1つはリードレプリカインスタンスです。
DBインスタンスのタイプはMySQLとします。

EC2インスタンスも作成します。
DBインスタンスに接続するクライアントとして使用します。
インスタンスは最新版のAmazon Linux 2です。

2種類のVPCエンドポイントを作成します。

1つ目はSSM用です。
SSM Session Managerを使用して、プライベートサブネット内のEC2インスタンスに接続するためです。

2つ目はS3用です。
S3バケット上に構築されたyumリポジトリにアクセスするためです。

CloudFormationテンプレートファイル

上記の構成をCloudFormationで構築します。
以下のURLにCloudFormationテンプレートを配置しています。

https://github.com/awstut-an-r/awstut-fa/tree/main/111

テンプレートファイルのポイント解説

RDS

Resources:
  PrimaryInstance:
    Type: AWS::RDS::DBInstance
    DeletionPolicy: Delete
    Properties:
      AllocatedStorage: !Ref DBAllocatedStorage
      DBInstanceClass: !Ref DBInstanceClass
      DBInstanceIdentifier: dbinstance
      DBSubnetGroupName: !Ref DBSubnetGroup
      Engine: !Ref DBEngine
      EngineVersion: !Ref DBEngineVersion
      MasterUsername: !Ref DBMasterUsername
      MasterUserPassword: !Ref DBMasterUserPassword
      VPCSecurityGroups:
        - !Ref DBSecurityGroup

  ReadReplicaInstance:
    Type: AWS::RDS::DBInstance
    DeletionPolicy: Delete
    Properties:
      DBInstanceClass: !Ref DBInstanceClass
      SourceDBInstanceIdentifier: !Ref PrimaryInstance
Code language: YAML (yaml)

1つ目のリソースがプライマリインスタンスです。
リードレプリカを作成する上で、特別な設定は不要です。

2つ目のリソースがリードレプリカインスタンスです。
SourceDBInstanceIdentifierプロパティでプライマリインスタンスを指定します。

(参考) EC2インスタンス

Resources:
  Instance:
    Type: AWS::EC2::Instance
    Properties:
      IamInstanceProfile: !Ref InstanceProfile
      ImageId: !Ref ImageId
      InstanceType: !Ref InstanceType
      NetworkInterfaces:
        - DeviceIndex: 0
          SubnetId: !Ref InstanceSubnet
          GroupSet:
            - !Ref InstanceSecurityGroup
      UserData: !Base64 |
        #!/bin/bash -xe
        yum update -y
        yum install -y mariadb
Code language: YAML (yaml)

EC2インスタンスからDBインスタンスにアクセスするために、クライアントパッケージを準備する必要があります。
今回はユーザデータを使用して、パッケージをインストールします。

ユーザデータに関する詳細については、以下のページをご確認ください。

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

Amazon Linux 2から各種RDSに接続するためのクライアントパッケージについては、以下のページをご確認ください。

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

環境構築

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

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

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

あわせて読みたい
CloudFormationのネストされたスタックで環境を構築する 【CloudFormationのネストされたスタックで環境を構築する方法】 CloudFormationにおけるネストされたスタックを検証します。 CloudFormationでは、スタックをネストす...

各スタックのリソースを確認した結果、今回作成された主要リソースの情報は以下の通りです。

  • EC2インスタンス:i-08ac3e2191dbd318d
  • プライマリDBインスタンス:dbinstance
  • プライマリDBインスタンスのエンドポイントDNS名:dbinstance.cl50iikpthxs.ap-northeast-1.rds.amazonaws.com
  • リードレプリカDBインスタンス:fa-111-rdsstack-1lrqk70uga1zi-readreplicainstance-whcb2xnwbhfb
  • リードレプリカDBインスタンスのエンドポイントDNS名:fa-111-rdsstack-1lrqk70uga1zi-readreplicainstance-whcb2xnwbhfb.cl50iikpthxs.ap-northeast-1.rds.amazonaws.com

AWS Management Consoleから各リソースを確認します。

RDSを確認します。

Detail of RDS 1.

2つのインスタンスが作成されています。
Roleを見ると、一方はプライマリ、もう一方はリードレプリカです。

それぞれの詳細を確認します。

Detail of RDS 2.
Detail of RDS 3.

2つのDBインスタンスが異なるAZ上のサブネットに配置されていることがわかります。

動作確認

プライマリインスタンスにアクセス

EC2インスタンスからプライマリインスタンスに接続します。
EC2インスタンスへのアクセスはSSM Session Managerを使用します。

% aws ssm start-session --target i-08ac3e2191dbd318d
...
sh-4.2$
Code language: Bash (bash)

SSM Session Managerの詳細につきましては、以下のページをご確認ください。

あわせて読みたい
LinuxインスタンスにSSM Session Manager経由でアクセスする 【LinuxインスタンスにSSM Session Manager経由でアクセスする】 EC2インスタンスにSSM Session Manager経由でアクセスする構成を確認します。 Session Manager は完全...

ユーザーデータによるEC2インスタンスの初期化処理の実行状況を確認します。

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

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)

正常にMySQLクライアントパッケージがインストールされていることがわかります。

このクライアントパッケージを使用して、DBインスタンスに接続します。

sh-4.2$ mysql -h dbinstance.cl50iikpthxs.ap-northeast-1.rds.amazonaws.com  -P 3306 -u testuser -p
Enter password:
Welcome to the MariaDB monitor.  Commands end with ; or \g.
Your MySQL connection id is 21
Server version: 8.0.28 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 [(none)]> 
Code language: Bash (bash)

接続できました。

試しにテスト用データベースおよびテーブルを作成し、テストデータを保存します。

MySQL [(none)]> CREATE database test;

MySQL [(none)]> use test;

MySQL [test]> CREATE TABLE planet (id INT UNSIGNED AUTO_INCREMENT, name VARCHAR(30), PRIMARY KEY(id));

MySQL [test]> INSERT INTO planet (name) VALUES ("Mercury");

MySQL [test]> select * from planet;
+----+---------+
| id | name    |
+----+---------+
|  1 | Mercury |
+----+---------+
Code language: Bash (bash)

正常に動作しました。

リードレプリカインスタンスにアクセス

続いてリードレプリカインスタンスに接続します。

sh-4.2$ mysql -h fa-111-rdsstack-1lrqk70uga1zi-readreplicainstance-whcb2xnwbhfb.cl50iikpthxs.ap-northeast-1.rds.amazonaws.com  -P 3306 -u testuser -p
Enter password:
Welcome to the MariaDB monitor.  Commands end with ; or \g.
Your MySQL connection id is 19
Server version: 8.0.28 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)

こちらも正常に接続できました。

試しに読み込み/書き込み時の動作を確認します。

MySQL [(none)]> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| mysql              |
| performance_schema |
| sys                |
| test               |
+--------------------+

MySQL [(none)]> use test;

MySQL [test]> select * from planet;
+----+---------+
| id | name    |
+----+---------+
|  1 | Mercury |
+----+---------+

MySQL [test]> INSERT INTO planet (name) VALUES ("Venus");
ERROR 1290 (HY000): The MySQL server is running with the --read-only option so it cannot execute this statement
Code language: Bash (bash)

読み込みは成功しました。
プライマリインスタンスで書き込んだ内容が、リードレプリカにも反映されています。

一方で、書き込みには失敗しました。
これはこのインスタンスが読み込み専用であるためです。

リードレプリカの昇格

リードレプリカは昇格させることができます。

リードレプリカを新しい DB インスタンスに昇格させると、他の DB インスタンスと同等になります。

昇格した DB インスタンスはリードレプリカではなくなったため、レプリケーションターゲットとしては使用できません。

リードレプリカをスタンドアロン DB インスタンスに昇格させる

今回はAWS CLIを使用して、リードレプリカを昇格させます。

$ aws rds promote-read-replica \
--db-instance-identifier fa-111-rdsstack-1lrqk70uga1zi-readreplicainstance-whcb2xnwbhfb
Code language: Bash (bash)

改めてリードレプリカ側の状況を確認します。

Detail of RDS 4.

Roleが「Instance」とありますので、リードレプリカから通常のインスタンスに昇格したことがわかります。

Detail of RDS 5.

イベントログを見ても、通常のインスタンスに昇格後、再起動を実施したことが読み取れます。

改めてこのインスタンスに接続します。

sh-4.2$ mysql -h fa-111-rdsstack-1lrqk70uga1zi-readreplicainstance-whcb2xnwbhfb.cl50iikpthxs.ap-northeast-1.rds.amazonaws.com  -P 3306 -u

MySQL [(none)]> use test;

MySQL [test]> INSERT INTO planet (name) VALUES ("Venus");

MySQL [test]> select * from planet;
+----+---------+
| id | name    |
+----+---------+
|  1 | Mercury |
|  2 | Venus   |
+----+---------+
Code language: Bash (bash)

今回は書き込み処理が成功しました。
リードレプリカから通常のインスタンスに昇格したため、書き込み処理が可能となりました。

まとめ

CloudFormationを使用して、リードレプリカを作成しました。
加えてリードレプリカの昇格方法についても確認しました。