我最近设置了一个只读副本来从我的Amazon多可用区RDS实例中获取一些读取负载。亚马逊文档明确指出,“由您的应用程序决定如何在您的只读副本中分配读取流量”。
有没有人想出一种可管理的方式来扩展只读副本?将我的应用程序的不同部分硬编码为从特定副本读取,似乎不是一个非常可扩展的解决方案。有没有办法设置它类似于将EC2实例放在负载均衡器后面?
答案 0 :(得分:7)
AWS工程师提供了对问题here的一些见解。
以下是他回复的片段:
通常,您可以在以下3个逻辑位置对流量进行负载均衡:
- 应用程序层 - 创建多个连接池并将所有读取发送到只读副本。
- Web框架/中间件 - 一些Web框架内置了对多个数据库的支持[1]。
- 外部代理 - 您可以使用MySQLproxy [2]等外部代理。
[1] - https://docs.djangoproject.com/en/dev/topics/db/multi-db/
答案 1 :(得分: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
其中x.x.x.x是副本端点。
答案 2 :(得分:3)
我一直在使用Route 53加权CNAME来加载平衡RDS读取副本(和源代码)。我目前为readdb.example.com提供了3个CNAME记录集。
第一个指向db.example.com上的源数据库。这是因为存在复制错误。应用程序可以回退到原始数据库以进行读取。或者如果您愿意,您可以让源携带一定比例的读取负载,具体取决于您设置重量的方式。路由策略设置为加权。我将源的权重设置为1,因此读取负载的负担非常小。 TTL设置为低。我已经尝试过从1到10的值。我现在已经把它保留在10。您还必须输入一个Set ID,它是任何唯一的字符串(“Source Database”)。
第二个记录集指向其中一个只读副本(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的环境变量。然后,您进行Route 53运行状况检查,指向http://www.example.com/rdshealthcheck/rdsshealthcheck.php?id=readdb1。您将搜索字符串设置为“GOOD!”我认为搜索字符串每月花费1美元/健康检查,这似乎是合理的。
如果您有第二个只读副本,则可以创建另一个指向http://www.example.com/rdshealthcheck/rdsshealthcheck.php?id=readdb2或其所谓的健康检查。
我实际上此时只使用一个只读副本,但它比我的源数据库大得多。这对我来说更经济,因为我的源数据库是多重的。我保留了第三个记录集和第二个健康检查,以防第一个副本给我带来问题。这样,在重新启动它之前,我不必等待第一个删除。相反,我立即删除第一个,并使用第三个记录集中指定的名称(和第二个健康检查)启动第二个。
答案 3 :(得分:0)
我想建议更多的方便。
这是DNS Round-robin与Amazon Route 53。
正如您在article中看到的那样, Amazon Route 53可以使用多个CNAME进行循环播放。
然后您需要做的就是
在我的情况下,这种方法很好。