Amazon Web Services ブログ

Amazon Aurora PostgreSQL で読み書き用に pgpool の単一のエンドポイント設定する方法

Amazon Aurora は、プライマリ DB インスタンス (クラスタエンドポイント) と、リードレプリカ (リーダーエンドポイント) のエンドポイントを提供します。Aurora は、クラスタエンドポイントを自動的に更新するので、常にプライマリインスタンスを指し示すようできています。リーダーエンドポイントの読み取り機能は、使用可能なすべてのリードレプリカの読み取り操作の負荷を分散します。

Amazon Aurora Replica では、通常 100 ms 未満のレプリケーションラグが発生します。したがって、アプリケーションで遅延が許容される場合は、クラスタエンドポイントとリーダーエンドポイントの両方を使用して、水平方向に拡張されたデータベースを利用できます (図 1)。

図 1: 使用するエンドポイントを決定するアプリケーションのアーキテクチャ

図 1: 使用するエンドポイントを決定するアプリケーションのアーキテクチャ

ただし、読み取り用と書き込み用両方のデータベースエンドポイント管理は、複雑なアプリケーションになります。この記事では、pgpool を使った、書き込みデータ量を自動的にクラスタエンドポイントへ、また読み込みデータ量を読み込みエンドポイントに転送する PostgreSQL-Amazon Aurora 互換の単一エンドポイントの構築方法をご紹介します (図 2)。

図 2: pgpool ミドルウェアに基づいたソリューション提案

図 2: pgpool ミドルウェアに基づいたソリューション提案

アーキテクチャ

Pgpool は PostgreSQL データベースとデータベースクライアントの間に位置する BSD ライセンスのミドルウェアですこの例では、図 3 のアーキテクチャを使用します。

図 3: PostgreSQL-Amazon Aurora 互換クラスタ用の単一エンドポイントを構築するミドルウェアとしての pgpool の使用

図 3: PostgreSQL-Amazon Aurora 互換クラスタ用の単一エンドポイントを構築するミドルウェアとしての pgpool の使用

Amazon Aurora クラスタは、1 つのプライマリインスタンス、2 つのアベイラビリティゾーンと 2 つのプライベートサブネットに配置された 2 つの Aurora Read Replicas で構成されています。クラスタには、pgpool インスタンスからの入力のみを許可するセキュリティグループがあります

Pgpool は、障害迂回目的でアクティブインスタンスを持つ Auto Scaling グループに導入されていますまた、許可された Classless Inter-Domain Routing (CIDR) ブロックからのアクセスのみを許可するセキュリティグループのプライベートサブネット内でも隔離されています。

アクセスサブネットは、pgpool の持続エンドポイントを構築している Network Load Balancer をホストしています。したがって、pgpool インスタンスが失敗し、Auto Scaling グループが新しいインスタンスを作成すると、データベースエンドポイントは変更されません

AWS CloudFormation によるデプロイメント

この例で使用されている AWS CloudFormation テンプレートは、この GitHub リポジトリにあります。この例では、複数の AWS CloudFormation テンプレートを使用して、仮想プライベートクラウド (VPC) のインフラストラクチャ、セキュリティグループ、Aurora クラスタ、および pgpool ミドルウェアを構築していますネストされたスタックを使用すると、大きなスタックをいくつかの再利用可能なコンポーネントに分割することができますAWS CloudFormation がまだ不得意な方は、AWS CloudFormation のドキュメントを参照してください

テンプレート配置の詳細については、GitHub の README ファイルを参照してください以下のセクションでは、主要部分について説明します

Amazon Aurora クラスタの作成

次の AWS CloudFormation スニペットでは、VPC インフラストラクチャとセキュリティグループの準備後に、3 ノードの Amazon Aurora クラスタを作成する方法を紹介します。Amazon Aurora は、3 つのノードのうちの 1 つをプライマリとして、他の 2 つを Read Replicas として使用します。

DBAuroraCluster:
    Type: "AWS::RDS::DBCluster"
    Properties:
      DatabaseName: !Ref DatabaseName
      Engine: aurora-postgresql
      MasterUsername: !Ref DatabaseUser
      MasterUserPassword: !Ref DatabasePassword
      VpcSecurityGroupIds: 
        - !Ref DBFirewall
      Tags:
        - Key: Project
          Value: !Ref ProjectTag
  DBAuroraOne:
    Type : "AWS::RDS::DBInstance"
    Properties:
      DBClusterIdentifier: !Ref DBAuroraCluster
      Engine: aurora-postgresql
      DBInstanceClass: !Ref DbInstanceSize
      Tags:
        - Key: Project
          Value: !Ref ProjectTag
  DBAuroraTwo:
    Type : "AWS::RDS::DBInstance"    
    Properties:
      DBClusterIdentifier: !Ref DBAuroraCluster
      Engine: aurora-postgresql
      DBInstanceClass: !Ref DbInstanceSize
      Tags:
        - Key: Project
          Value: !Ref ProjectTag
  DBAuroraThree:
    Type : "AWS::RDS::DBInstance"    
    Properties:
      DBClusterIdentifier: !Ref DBAuroraCluster
      Engine: aurora-postgresql
      DBInstanceClass: !Ref DbInstanceSize     
      Tags:
        - Key: Project
          Value: !Ref ProjectTag

pgpool のデプロイメント

ブログ記事の pgpool と Amazon ElastiCache を Amazon Redshift でのクエリキャッシュで使用する方法は、AWS に pgpool を導入する際、参考になります。さらに、pgpool ドキュメントには Amazon Aurora のセクションが含まれています。

pgpool をデプロイする AWS CloudFormation テンプレートでは、ELB 負荷分散装置と Auto Scaling グループを設定します。Auto Scaling グループの起動設定では、AWS CloudFormation cfn-init ツールを使用して pgpool をデプロイし、設定します。

パッケージをインストールし、pgpool インストールファイルを展開する:

yum groupinstall -y "Development Tools" && yum install -y postgresql-devel
wget www.pgpool.net/download.php?f=pgpool-II-3.7.2.tar.gz -O /tmp/pgpool-II-3.7.2.tar.gz
tar zxf /tmp/pgpool-II-3.7.2.tar.gz

pgpool を構築し、ログディレクトリと PID ディレクトリを作成:

cd /opt/pgpool-II-3.7.2
./configure && make && make install
mkdir -p /var/run/pgpool && mkdir -p /var/log/pgpool && chmod -R 777 /var/run/pgpool && chmod -R 777 /var/log/pgpool

Amazon Aurora は MD5 認証システムを使用するため、ローカル認証ファイルにマスターデータベースユーザー入力が必要になります。

/usr/local/bin/pg_md5 -m -u ${DatabaseUser} ${DatabasePassword}

MD5 認証設定も /usr/local/etc/pool_hba.conf でしてください。

host    all         all         0.0.0.0/0               md5

最後に pgpool をサービス登録した後、起動し chkconfig を使って自動起動するようにします。

pgpool の設定

ほとんどの pgpool 設定は /usr/local/etc/pgpool.conf で行われます。重要な設定について

設定 注意
listen_addresses ‘*’ すべてのインターフェイスで着信接続を許可します。
backend_hostname0 Amazon Auora クラスターエンドポイント
backend_port0 3306 Amazon Aurora の PostgreSQL モードはポート 3306 を使用します
backend_flag0 ALWAYS_MASTER pgpool が障害迂回しないようしてください
backend_hostname1 Amazon Auora 読み込みエンドポイント
backend_port1 3306 Amazon Aurora の PostgreSQL モードはポート 3306 を使用します
enable_pool_hba On Amazon Aurora の認証に必要です
pool_passwd ‘pool_passwd’ 認証ファイルの場所を設定
Ssl On Amazon Aurora は Secure Sockets Layer (SSL) 接続を使用します。
replication_mode Off
load_balance_mode On
master_slave_mode On
master_slave_sub_mode Stream
sr_check_period 0
health_check_* マスターアカウントの資格情報で設定します
fail_over_on_backend_error Off

設定テスト

これで、SQL 命令コマンドを発令し、pgpool のデータ転送が期待値であることが確認できます。まずテーブルを作成し、いくつかの行を挿入します。

CREATE TABLE distributors (
    did     integer PRIMARY KEY,
    name    varchar(40)
);

INSERT INTO distributors (did, name) VALUES (5, 'XYZ Widgets')
INSERT INTO distributors (did, name) VALUES (6, 'ABC Widgets')
INSERT INTO distributors (did, name) VALUES (7, 'QRS Widgets')

/var/log/pgpool.log を確認すると、これらのコマンド指示は Amazon Aurora primary (node 0) にあてられていることがわかります。

DB node id: 0 backend pid: 18703 statement: INSERT INTO distributors (did, name) VALUES (7, 'QRS Widgets')

次に、クエリを作成します。

select * from distributors;

/var/log/pgpool.log にチェックインして、Amazon Aurora リーダーエンドポイント (node 1) にあてられていることがわかります。

DB node id: 1 backend pid: 19793 statement: select * from distributors

最後のテストとして、pgpool が トランザクションに埋め込まれた SELECT ステートメント を処理することを確認します。

BEGIN;
    INSERT INTO distributors (did, name) VALUES (10, '10');
    INSERT INTO distributors (did, name) VALUES (11, '11');
    SELECT * from distributors where did > 9;
COMMIT;

埋込み SELECT はトランザクション内の行にクエリの実行を行うことから、これらのコマンドはすべて、プライマリノードにヒットする必要があります。ログでちゃんと機能しているかを再度確認可能です。

DB node id: 0 backend pid: 22614 statement: INSERT INTO distributors (did, name) VALUES (10, '10')
DB node id: 0 backend pid: 22614 statement: INSERT INTO distributors (did, name) VALUES (11, '11')
DB node id: 0 backend pid: 22614 statement: SELECT * from distributors where did > 9

本番で使用する前に、個人のデータベースクライアントで必ず回帰テストを行ってください。もし pgpool ミドルウェアの拡張性に懸念がある場合、Auto Scaling グループが負荷に基づいて複数のインスタンスと拡張を許可している、クラスタ化された pgpool インスタンスを使用することを検討をおすすめします。

簡素化に努めましょう

この記事では、どのように pgpool を使って読み込みデータ量を読み込みエンドポイントに転送する Amazon Aurora クラスタの単一エンドポイント構築方法をご紹介しましたこの方法を使用すると、アプリケーションと Amazon Aurora の接続処理簡素化が可能です。

カスタムロジックに基づいてデータベース接続をルーティングするなど、より高度なルーティングオプションが必要な場合は、pgbouncer-rr を参照してください。カスタムロジックを使用すると、カナリアテストのために新しいスキーマに小さな割合のクエリを送信するなど、より高度なルーティング処理が可能です

将来的には、レプリカの設定を必要とせずにデータベースのバックエンドを自動的に拡張できる Amazon Aurora Serverless を視野に入れておいてください。このオプションはまだ試験中で、 PostgreSQL との互換性はまだサポートされていません


著者について

Randy DeFauw は、 Amazon Web Services のソリューションアーキテクト主任です。 AWS ユーザーのソリューション価値向上のため、ユーザーにデータベースプロジェクト上の指導や技術支援を行っています。