16

最近、Amazon マルチ AZ RDS インスタンスの読み取り負荷を軽減するために、読み取りレプリカをセットアップしました。Amazon のドキュメントには、「読み取りトラフィックが読み取りレプリカ全体にどのように分散されるかは、アプリケーション次第である」と明確に記載されています。

リードレプリカをスケーリングするための管理しやすい方法を見つけた人はいますか? アプリケーションのさまざまな部分を特定のレプリカから読み取るようにハードコーディングすることは、非常に拡張可能なソリューションとは思えません。EC2 インスタンスをロードバランサーの背後に配置するのと似た、これをセットアップする方法はありますか?

4

4 に答える 4

7

AWS エンジニアは、ここで質問に対する洞察を提供しました。

以下は、彼の応答の抜粋です。

一般に、次の 3 つの論理的な場所でトラフィックを負荷分散できます。

  • アプリケーション層 - 複数の接続プールを作成し、すべての読み取りをリードレプリカに送信します。
  • Web フレームワーク/ミドルウェア - 一部の Web フレームワークには、複数のデータベースに対するサポートが組み込まれています [1]。
  • 外部プロキシ - MySQLproxy [2] のような外部プロキシを使用できます。

[1] - https://docs.djangoproject.com/en/dev/topics/db/multi-db/

[2] - https://launchpad.net/mysql-proxy

于 2012-09-17T08:58:42.143 に答える
6

HAProxyは、複数のリードレプリカ間で負荷を分散するのに適したオプションだと思います。次のような構成を使用できます。

 listen mysql-cluster 0.0.0.0:3306
     mode tcp
     balance roundrobin
     option mysql-check user root

     server db01 x.x.x.x:3306 check
     server db02 x.x.x.x:3306 check
     server db03 x.x.x.x:3306 check

ここで、xxxx はレプリカ エンドポイントです。

于 2012-11-30T11:26:20.527 に答える
3

Route 53 加重 CNAME を使用して、RDS リードレプリカ (およびソース) の負荷を分散することをいじっています。現在、readdb.example.com 用に 3 つの CNAME レコード セットがあります。

1 つ目は、db.example.com のソース データベースを指しています。これは、レプリケーション エラーが発生した場合です。アプリケーションは、読み取りのために元のデータベースにフォールバックできます。または、必要に応じて、重みの設定方法に応じて、読み取り負荷の一部をソースに負担させることができます。ルーティング ポリシーは加重に設定されています。ソースの重みを 1 に設定しているため、読み取り負荷の負担が非常に小さくなっています。TTL は低く設定されています。1 から 10 までの値を試しました。今は 10 のままにしています。また、任意の一意の文字列 (「ソース データベース」) であるセット ID を入力する必要があります。

2 番目のレコード セットは、リードレプリカ (readdb1.blahblah.rds.amazonaws.com) の 1 つを指します。Routing Policy は重み付けされており、TTL は以前と同様に 10 です。また、一意のセット ID も必要です。私はこれに応じて、5〜50の間で重みを設定します. これは、事前に作成する必要があるヘルスチェックに関連しています。おそらく、レプリカを指す単純なヘルスチェックを使用できますが、私は少し違うことをしました。

各アプリケーション サーバーに次のようなファイルを配置します (私は PHP Elastic Beanstalk を使用していますが、他のセットアップ/言語でも同様のことができると思います)。

<?php if($instanceid = $_GET["id"]): ?>
<?php
exec("aws rds describe-db-instances --db-instance-identifier " . escapeshellarg($instanceid), $rdsinfo);
$rdsinfo = implode(' ',$rdsinfo);
$rdsinfo = json_decode($rdsinfo, true);
if($rdsinfo["DBInstances"][0]["StatusInfos"][0]["Normal"] && $rdsinfo["DBInstances"][0]["DBInstanceStatus"] === "available"){
    echo "GOOD!";
    }
else {
    echo "BAD!";
    };
/* Then there's some other stuff in here that is a little unrelated to the question */
?>
<?php endif ?>

このファイルは、Elastic Beanstalk アプリケーションにインストールされている AWS コマンドライン インターフェイスを使用し、AWS_ACCESS_KEY_ID、AWS_DEFAULT_REGION、および AWS_SECRET_KEY の環境変数を事前に指定することのみを必要とします。次に、 http://www.example.com/rdshealthcheck/rdsshealthcheck.php?id=readdb1を指す Route 53 ヘルスチェックを作成します。検索文字列を「GOOD!」に設定します。検索文字列のコストは 1 か月あたり 1 ドル/ヘルス チェックで、妥当だと思います。

2 番目の読み取りレプリカがある場合は、http://www.example.com/rdshealthcheck/rdsshealthcheck.php? id=readdb2などを指す別のヘルスチェックを作成できます。

現時点では、実際には 1 つのリード レプリカしか使用していませんが、ソース データベースよりもかなり大きいです。私のソース DB はマルチ az であるため、私にとってはより経済的でした。最初のレプリカで問題が発生した場合に備えて、3 番目のレコード セットと 2 番目のヘルス チェックを保持しています。そうすれば、再起動する前に最初のものが削除されるのを待つ必要がありません。代わりに、最初のレコードセットをすぐに削除し、3 番目のレコードセット (および 2 番目のヘルス チェック) で指定された名前を使用して 2 番目のレコードを起動します。

于 2014-08-31T19:37:59.310 に答える