Amazon Web Services ブログ
オープンソースプラットフォームで ProxySQL を使用して、Amazon Aurora クラスターでの SQL の読み取りと書き込みを分割する方法
ブログ記事Amazon Aurora PostgreSQL で読み書き用に pgpool の単一のエンドポイントを設定する方法では、Amazon Aurora PostgreSQL エンドポイントの読み取りおよび書き込みの分割機能を使用するアーキテクチャを紹介しています。このタイプのアーキテクチャは Aurora PostgreSQL クラスターに最適ですが、データベースに Amazon Aurora MySQL クラスターを使用している場合はどうでしょうか? この記事は、Aurora MySQL エンドポイントで読み取りおよび書き込みの分割を実現するための中間レイヤーとして ProxySQL を紹介することによって、元の記事を補完します。
Amazon Aurora は、プライマリ DB インスタンス (クラスターエンドポイント) と、リードレプリカ (リーダーエンドポイント) のエンドポイントを提供します。Aurora は、クラスタエンドポイントを自動的に更新するので、常にプライマリインスタンスを指し示すようできています。リーダーエンドポイントを使用して、使用可能なすべてのリードレプリカにまたがる読み取り操作のための接続に対して DNS ラウンドロビンを実行します。さらに、Amazon Aurora カスタムエンドポイントを使用して、アプリケーションのトラフィックをさらに分離することができます。
Amazon Aurora Replica では、通常 100 ms 未満のレプリケーションラグが発生します。したがって、アプリケーションで遅延が許容される場合は、以下に示すように、クラスターエンドポイントとリーダーエンドポイントの両方を使用して、水平方向に拡張されたデータベースを利用することができます。
前の図は、使用するエンドポイントを決定するアプリケーションの現在のアーキテクチャを示しています。ただし、読み取り用と書き込み用両方のデータベースエンドポイント管理は、複雑なアプリケーションになります。一部のサードパーティ製ドライバーは、より狭い範囲のユースケースしかサポートしていませんが、この記事のアイデアを読み書きを分割するユースケースにより広く適用することができます。
この記事では、ProxySQL を使って、書き込みトラフィックをクラスターエンドポイントへ、読み取りトラフィックをリーダーエンドポイントに自動的に転送する MySQL 互換の単一 Aurora エンドポイントを構築する方法をご紹介します。以下の図は、ProxySQL ミドルウェアに基づいて提案されるソリューションを示しています。
アーキテクチャ
ProxySQL は、MySQL データベースとデータベースクライアント間に存在する、GNU General Public License (GPL) でライセンスされる MySQL プロキシミドルウェアです。この例では、次の図のアーキテクチャを使用してデプロイします。
この図は、ミドルウェアとして ProxySQL を使用して、MySQL 互換の Aurora クラスターに単一のエンドポイントを提供する方法を示しています。Aurora クラスターは、1 つのプライマリインスタンス、2 つのアベイラビリティゾーンと 2 つのプライベートサブネットにデプロイされた 2 つの Aurora リードレプリカで構成されています。クラスターには、ProxySQL インスタンスからの受信データだけを許可するセキュリティグループがあります。
ProxySQL は、フェイルオーバーの目的で、単一のアクティブインスタンスを持つ Auto Scaling グループ内の Network Load Balancer の背後にデプロイされています (この記事でのデモ目的のため)。以下に示すように、master.yaml
ファイル (Resources.ProxySQLStack.Properties.Parameters
にあります) を更新することで、この設定を変更することができます。
この設定の変更により、通常の負荷用に 2 つの ProxySQL インスタンスがプロビジョニングされ、ピーク負荷時には最大 4 つのインスタンスまで拡張できます。また、ProxySQL ノードの 1 つに障害が発生した場合でも、データベースの可用性が向上します。
ProxySQL は、許可された Classless Inter-Domain Routing (CIDR) ブロックからのアクセスだけを許可するセキュリティグループのプライベートサブネット内でも隔離されています。
アクセスサブネットは、ProxySQL の持続エンドポイントを構築している Network Load Balancer をホストしています。したがって、ProxySQL インスタンスが失敗し、Auto Scaling グループが新しいインスタンスを作成すると、データベースエンドポイントは変更されません
AWS CloudFormation によるデプロイメント
この例で使用されている AWS CloudFormation テンプレートは、この GitHub リポジトリにあります。この例では、複数のネストされた AWS CloudFormation テンプレートを使用して、仮想プライベートクラウド (VPC) のインフラストラクチャ、セキュリティグループ、Aurora クラスター、および ProxySQLミドルウェアをデプロイしています。ネストされたスタックを使用すると、大きなスタックをいくつかの再利用可能なコンポーネントに分割することができますAWS CloudFormation がまだ不得意な方は、AWS CloudFormation のドキュメントを参照してください。
テンプレートのデプロイに関する指示については、GitHub の README ファイルを参照してください。以下のセクションでは、主要部分について説明します
Amazon Aurora クラスタの作成
次の AWS CloudFormation スニペットでは、VPC インフラストラクチャとセキュリティグループの準備後に、3 ノードの Amazon Aurora クラスタを作成する方法を紹介します。Amazon Aurora は 1 つのノードをプライマリとして、他の 2 つのノードをリードレプリカとして設定します。
ProxySQL のデプロイ
ProxySQLをデプロイする AWS CloudFormation テンプレートで、ELB ロードバランサーと Auto Scaling グループを設定します。Auto Scaling グループの起動設定では、AWS CloudFormation cfn-init ツールを使用して ProxySQL をデプロイし、設定します。
このソリューションでは、それぞれの Amazon EC2 インスタンスに Amazon Linux AMI を使用します。Amazon Linux AMI には、AWS とのシームレスな統合を可能にするパッケージと設定が含まれています。リポジトリはすべての AWS リージョンで利用可能であり、yum を使ってアクセスできます。各リージョンでリポジトリをホスティングすることで、データ転送料金なしで更新を迅速にデプロイすることができます。EC2 インスタンスのソフトウェアの更新の詳細については、Amazon Elastic Compute Cloud ユーザーガイドのインスタンスのソフトウェアの更新を参照してください。
まず、MySQL クライアントをインストールする必要があります。
次に、ProxySQL リポジトリをダウンロードします。
そして、リポジトリをインストールします。
最後に、ProxySQL を起動します。
ProxySQL の設定
管理者の認証情報を使用してローカルに接続することで、MySQL クライアントを使用した ProxySQL の設定のほとんどを実行することができます。ProxySQL のデフォルトのユーザー名とパスワードは、
「admin」および「admin」です。
初期設定後にこれらの認証情報を変更することを強くお勧めします。
次のコマンドは、ProxySQL での最初の読み取りと書き込みの分割オプションを設定します。
proxysql.sql
ファイルに含まれているオプションは、読み書きトラフィックを迅速に分割するのに適していますが、より高度なクエリルーティングルールの設定は ProxySQL で行います。以下は、proxysql.sql
ファイルの内容についての説明です。
まず、mysql_servers
テーブルと mysql_replication_hostgroups
テーブルが設定に対してクリーンであることを確認します。mysql_servers
テーブルには、ProxySQL によってプロキシされるすべてのバックエンドエンドポイントのエントリが含まれています。mysql_replication_hostgroups
テーブルには、読み取り専用エンドポイントの自動識別と分離のための設定が含まれています。
バージョン 2 より前では、ProxySQL は「read_only
」変数をチェックして、ライターエンドポイントからリーダーエンドポイントを決定していましたが、Amazon Aurora は、「innodb_read_only
」変数に基づいてリーダーとライターの定義をベースにしています。ProxySQL バージョン 2.0 では、mysql_replication_hotgroups
テーブルの check_type
列を使った変数定義のカスタム仕様のサポートが追加されました。
次に、mysql_servers
テーブルでエンドポイントを設定します。
次に、「innodb_read_only
」の check_type
値を使用して、mysql_replication_hostgroups
テーブルを設定して、ライターホストグループとリーダーホストグループを定義します。
ここで、ProxySQL サービスが再起動されても保持されるように、設定をディスクに書き戻します。
次に、mysql_query_rules
テーブルが設定に対してクリーンであることを確認します。
次に、必要性に合わせてクエリルーティングルールを定義します。シャーディング、ダイジェストベース、読み取り/書き込み分割ベースなど、さまざまなユースケースをサポートするようにルールを定義することができます。この例は、基本的な読み取り/書き込み分割シナリオの設定を示しています。
前の 2 つのルールは、すべての書き込みトラフィックが書き込み側ホストグループに送られ、すべての読み取りトラフィックが読み取り側に送られるように設定します。
この場合も、ProxySQL サービスが再起動されても保持されるように、設定をディスクに書き戻します。
次に、mysql_users
テーブルが設定に対してクリーンであることを確認します。
次に、ProxySQL 設定でバックエンドユーザーを定義します。
この場合も、ProxySQL サービスが再起動されても保持されるように、設定をディスクに書き戻します。
次に、ProxySQL でモニタリングユーザーを設定します。このユーザはバックエンドのモニタリングに使用され、使用およびレプリケーションクライアントの権限が必要です。
次に、バックエンド MySQL のバージョンを設定し、いくつかのモニタリング間隔を微調整します。
この場合も、ProxySQL サービスが再起動されても保持されるように、設定をディスクに書き戻します。
設定用に proxysql.sql
ファイルで、以下の変数を指定する必要があります。
変数 | 値 | 注意 |
ClusterEndpoint | Auora クラスターエンドポイント | これは、ProxySQL のライターホストでもあります。 |
ReaderEndpoint | Aurora リーダーエンドポイント | これは、ProxySQL のリーダーホストでもあります。 |
DatabaseUser | Aurora データベースユーザー | これは、クラスターのモニタリングユーザーとしても使用されます。カスタムユーザーに置き換えることができます。モニタリング用のカスタムユーザを作成する場合は、必ず proxysql.sql 設定ファイルを更新してください。 |
DatabasePassword | Aurora データベースパスワード | これは、クラスターのモニタリングユーザーのパスワードとしても使用されます。モニタリング用のカスタムユーザを作成する場合は、必ず proxysql.sql 設定ファイルの対応するパスワードを更新してください。 |
DatabaseName | Aurora データベース名 | |
BackendMySQLVersion | Amazon Aurora データベース MySQL バージョン | これは、ProxySQL から消費アプリケーションに返されるバージョンです。これが、バックエンドと同じバージョンに設定されていることを確認します。ProxySQL バージョン 2.0 のデフォルト設定は 5.5.30 です。 |
また、ProxySQL がクライアント接続用に提供するデフォルトのポートとインターフェイスは次のとおりです。
そして、以下は ProxySQL の管理のデフォルト設定です。
設定テスト
これで、SQL 命令コマンドを発行し、ProxySQL のトラフィックが期待通りであることを確認できます。
まずテーブルを作成し、いくつかの行を挿入します。
ProxySQL 統計スキーマ
にチェックインすると、これらのステートメントが Amazon Aurora プライマリホストグループ (ホストグループ 10) に送信されていることがわかります。
ホストグループ | スキーマ名 | ユーザー名 | ダイジェスト | digest_text | count_star |
10 | proxysqlexample | proxysqluser | 0xCF52DCD38A9B9942 | CREATE TABLE Persons ( PersonID int, LastName varchar(?), FirstName varchar(?), Address varchar(?), City varchar(?) ) | 1 |
10 | proxysqlexample | proxysqluser | 0xE7B5E8C714313F56 | INSERT INTO Persons (PersonID, LastName, FirstName, Address, City) VALUES (?, ?, ?, ?, ?) | 3 |
次に、クエリを作成します。
ProxySQL 統計スキーマ
にチェックインすると、このステートメントが Amazon Aurora リーダーエンドポイント (ホストグループ 20) に送信されていることがわかります。
ホストグループ | スキーマ名 | ユーザー名 | ダイジェスト | digest_text | count_star |
10 | proxysqlexample | proxysqluser | 0xCF52DCD38A9B9942 | CREATE TABLE Persons ( PersonID int, LastName varchar(?), FirstName varchar(?), Address varchar(?), City varchar(?) ) | 1 |
10 | proxysqlexample | proxysqluser | 0xE7B5E8C714313F56 | INSERT INTO Persons (PersonID, LastName, FirstName, Address, City) VALUES (?, ?, ?, ?, ?) | 3 |
20 | proxysqlexample | proxysqluser | 0xDEB542EDC426A35F | select * from Persons | 1 |
最後のテストとして、ProxySQL が トランザクションに埋め込まれた SELECT ステートメント を処理することを確認します。
埋込み SELECT はトランザクション内に書き込まれている行を照会することから、これらのステートメントはすべて、プライマリノードにヒットするはずです。ログでちゃんと機能しているかを再度確認可能です。
ホストグループ | スキーマ名 | ユーザー名 | ダイジェスト | digest_text | count_star |
10 | proxysqlexample | proxysqluser | 0xCF52DCD38A9B9942 | CREATE TABLE Persons ( PersonID int, LastName varchar(?), FirstName varchar(?), Address varchar(?), City varchar(?) ) | 1 |
10 | proxysqlexample | proxysqluser | 0xE7B5E8C714313F56 | INSERT INTO Persons (PersonID, LastName, FirstName, Address, City) VALUES (?, ?, ?, ?, ?) | 5 |
20 | proxysqlexample | proxysqluser | 0xDEB542EDC426A35F | select * from Persons | 1 |
10 | proxysqlexample | proxysqluser | 0xFAD1519E4760CBDE | BEGIN | 1 |
10 | proxysqlexample | proxysqluser | 0x379FAD0823D3FF7B | SELECT * from Persons where PersonID > ? | 1 |
この設定を本番で使用する前に、個人のデータベースクライアントで必ず完全な回帰テストを行うことをお勧めします。ProxySQL ミドルウェアの拡張性に懸念がある場合、Auto Scaling グループが負荷に基づいて複数のインスタンスと拡張を許可している、クラスター化された ProxySQL インスタンスを使用することを検討してください。
まとめ: 簡素化に向けた努力
この記事では、ProxySQL 使って読み込みトラフィックを読み込みエンドポイントに自動的に転送する Amazon Aurora クラスターの単一エンドポイントを構築する方法を学びました。この方法を使用すると、アプリケーションと Amazon Aurora の接続処理簡素化が可能です。
カスタムロジックに基づいてデータベース接続をルーティングするなど、より高度なルーティングオプションが必要な場合は、ProxySQL のクエリルーティング機能をさらに詳しく調べることができます。カスタムロジックを使用すると、カナリアテストやウェイトベースルーティングのために新しいスキーマに小さな割合のクエリを送信するなど、より高度なルーティング処理が可能です
将来的には、レプリカの設定を必要とせずにデータベースのバックエンドを自動的に拡張できる Amazon Aurora Serverless を視野に入れておいてください。
著者について
Tulsi Garg は、AWS ワールドワイドパブリックセクターカナダチームのシニアソリューションアーキテクトです。彼は、カナダの公共部門の顧客 (政府機関、非営利団体、スタートアップ企業および教育機関) と協力して、クラウドへの過程を加速させています。彼は IoT に情熱を注いでおり、テクノロジー玩具を買うための言い訳として彼の娘を使っているようです。
Diego Magalhães は、ワールドワイドパブリックセクターで働いている AWS シニアソリューションアーキテクトであり、カナダ全土の教育機関の顧客と仕事をしています。常に新たな課題を探しており、最新の課題はトロントの寒い冬とブラジルの晴天を交換することでした。 ☃️