简体   繁体   English

有没有人想出如何扩展亚马逊RDS阅读副本?

[英]Has anyone figured out how to scale Amazon RDS read replicas?

I've recently set up a read replica to take some of the read load off of my Amazon multi-AZ RDS instance. 我最近设置了一个只读副本,以便从我的Amazon多可用区RDS实例中获取一些读取负载。 The Amazon documentation clearly states that it is "up to your application to determine how read traffic is distributed across your read replicas". 亚马逊文档明确指出,“由您的应用程序决定如何在您的只读副本中分配读取流量”。

Has anyone figured out a manageable way to scale read replicas? 有没有人想出一种可管理的方式来扩展只读副本? It doesn't seem like a very extensible solution to have different parts of my application hard-coded to read from specific replicas. 将我的应用程序的不同部分硬编码为从特定副本读取,似乎不是一个非常可扩展的解决方案。 Is there a way to set this up that is analogous to putting EC2 instances behind a load balancer? 有没有办法设置它类似于将EC2实例放在负载均衡器后面?

An AWS engineer provided some insight into the question here . 一个AWS工程师提供一些深入的问题在这里

Here is a snippet of his response: 以下是他回复的片段:

in general you can load-balance traffic at the following 3 logical places: 通常,您可以在以下3个逻辑位置对流量进行负载平衡:

  • Application layer - create multiple connection pools and send all reads to the read-replicas. 应用程序层 - 创建多个连接池并将所有读取发送到只读副本。
  • Web framework/middleware - some web frameworks have in-built support for multiple databases [1]. Web框架/中间件 - 一些Web框架内置了对多个数据库的支持[1]。
  • External proxy - You can use an external proxy like MySQLproxy [2]. 外部代理 - 您可以使用像MySQLproxy [2]这样的外部代理。

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

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

I think HAProxy would be a good option to load balance among multiple read replicas. 我认为HAProxy是在多个只读副本之间加载平衡的好选择。 You can have a config something like this: 你可以有这样的配置:

 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

where xxxx is the replica endpoint. 其中xxxx是副本端点。

I've been messing with using Route 53 weighted CNAME to load balance RDS read replicas (and the source). 我一直在使用Route 53加权CNAME来加载平衡RDS读取副本(和源代码)。 I currently have 3 CNAME record sets for readdb.example.com. 我目前为readdb.example.com提供了3个CNAME记录集。

The first points to the source db at db.example.com. 第一个指向db.example.com上的源数据库。 This is in case there's a replication error. 这是因为存在复制错误。 The application can fallback to the original database for reads. 应用程序可以回退到原始数据库以进行读取。 Or if you want, you can have the source carry some proportion of the read load, depending on how you set the weight. 或者如果您愿意,您可以让源携带一定比例的读取负载,具体取决于您设置重量的方式。 The Routing Policy is set to Weighted. 路由策略设置为加权。 I have the weight for the source set to 1, so it takes on a very small burden of the read load. 我将源的权重设置为1,因此读取负载的负担非常小。 The TTL is set low. TTL设置为低。 I've tried values from 1 to 10. I've left it at 10 for now. 我已经尝试过从1到10的值。我现在已经把它保留在10。 You also have to enter a Set ID which is any unique string ("Source Database"). 您还必须输入Set ID,它是任何唯一的字符串(“Source Database”)。

The second record set points to one of the read replicas (readdb1.blahblah.rds.amazonaws.com). 第二个记录集指向其中一个只读副本(readdb1.blahblah.rds.amazonaws.com)。 Routing Policy is weighted, and TTL is 10 like before. 路由策略是加权的,TTL与之前一样是10。 It also needs a unique Set ID. 它还需要一个唯一的Set ID。 I set the weight for this one between 5-50, depending. 我将这个重量设置在5-50之间,具体取决于。 This one, I do associate with a health check, which you have to create ahead of time. 这个,我确实与健康检查相关联,您必须提前创建健康检查。 You can probably use a simple healthcheck that points to the replica, but I did something a little different. 您可以使用指向副本的简单健康检查,但我做了一些不同的事情。

I put a file like this on each of my application servers (I'm using PHP Elastic Beanstalk, but you could do something similar in other setups/languages I assume): 我在每个应用程序服务器上放了这样的文件(我使用的是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 ?>

This file uses the AWS command line interface which is installed on Elastic Beanstalk applications and only requires that the environmental variables for AWS_ACCESS_KEY_ID, AWS_DEFAULT_REGION, and AWS_SECRET_KEY be specified ahead of time. 此文件使用安装在Elastic Beanstalk应用程序上的AWS命令行界面,并且只要求提前指定AWS_ACCESS_KEY_ID,AWS_DEFAULT_REGION和AWS_SECRET_KEY的环境变量。 So then you make a Route 53 health check that points to http://www.example.com/rdshealthcheck/rdsshealthcheck.php?id=readdb1 . 然后,您进行Route 53运行状况检查,指向http://www.example.com/rdshealthcheck/rdsshealthcheck.php?id=readdb1 You set the search string to "GOOD!" 您将搜索字符串设置为“GOOD!” I think a search string costs $1/month/health check, which seems reasonable. 我认为搜索字符串每月花费1美元/健康检查,这似乎是合理的。

If you have a second read replica, you can create another healthcheck that points to http://www.example.com/rdshealthcheck/rdsshealthcheck.php?id=readdb2 or whatever it's called. 如果您有第二个只读副本,则可以创建另一个指向http://www.example.com/rdshealthcheck/rdsshealthcheck.php?id=readdb2或其所谓的健康检查。

I actually only use one read replica at this time, but it is significantly larger than my source db. 实际上我此时只使用一个只读副本,但它比我的源数据库大得多。 It was more economical for me, because my source DB is multi-az. 这对我来说更经济,因为我的源数据库是多重的。 I keep the third record set and second health check around in case the first replica is giving me problems. 我保留了第三个记录集和第二个健康检查,以防第一个副本给我带来问题。 That way, I don't have to wait for the first one to delete before relaunching it. 这样,在重新启动它之前,我不必等待第一个删除。 Instead, I immediately delete the first one and launch the second one using the name specified in the third recordset (and second health check). 相反,我立即删除第一个,并使用第三个记录集中指定的名称(和第二个健康检查)启动第二个。

I'd like to suggest more convience approach. 我想建议更多的方便。
Which is, DNS Round-robin with Amazon Route 53 . 这是使用Amazon Route 53的 DNS循环法

As you can see in the this article , 正如您在本文中所看到的,
Amazon Route 53 can do Round-robin with multiple CNAMEs. Amazon Route 53可以使用多个CNAME进行循环。

Then all you need to do is 那么你需要做的就是

  1. "Creating Record Sets" at Route 53. 53号公路的“创建记录集”。
  2. Update your config file of your application. 更新应用程序的配置文件。

In my case, this approach works fine. 就我而言,这种方法很好。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM