16

我最近设置了一个只读副本,以减轻我的 Amazon 多可用区 RDS 实例的一些读取负载。亚马逊文档明确指出,“由您的应用程序决定读取流量如何在您的只读副本中分布”。

有没有人想出一种可管理的方式来扩展只读副本?将我的应用程序的不同部分硬编码以从特定副本读取,这似乎不是一个非常可扩展的解决方案。有没有一种类似于将 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 记录集。

第一个指向 db.example.com 上的源数据库。这是为了防止出现复制错误。应用程序可以回退到原始数据库进行读取。或者,如果您愿意,您可以让源承担一定比例的读取负载,具体取决于您设置权重的方式。路由策略设置为加权。我将源的权重设置为 1,因此读取负载的负担非常小。TTL 设置为低。我尝试了从 1 到 10 的值。我现在将其保留为 10。您还必须输入任何唯一字符串(“源数据库”)的集合 ID。

第二个记录集指向其中一个只读副本 (readdb1.blahblah.rds.amazonaws.com)。路由策略是加权的,TTL 和以前一样是 10。它还需要一个唯一的 Set 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 美元/月/健康检查,这似乎是合理的。

如果您有第二个只读副本,您可以创建另一个指向http://www.example.com/rdshealthcheck/rdsshealthcheck.php?id=readdb2或其他名称的运行状况检查。

我实际上此时只使用了一个只读副本,但它比我的源数据库大得多。这对我来说更经济,因为我的源数据库是多可用的。我保留第三个记录集和第二个健康检查,以防第一个副本给我带来问题。这样,我不必等待第一个删除再重新启动它。相反,我立即删除第一个并使用第三个记录集中指定的名称(和第二个健康检查)启动第二个。

于 2014-08-31T19:37:59.310 回答
0

我想建议更方便的方法。
即,使用Amazon Route 53进行DNS 循环

正如您在本文中看到的,
Amazon Route 53可以使用多个 CNAME 进行循环。

那么你需要做的就是

  1. 在 Route 53 的“创建记录集”。
  2. 更新应用程序的配置文件。

就我而言,这种方法效果很好。

于 2014-11-19T11:09:31.633 回答