2012-08-06 61 views
16

我最近設置了一個只讀副本,以從我的Amazon多可用區RDS實例中讀取一些讀取負載。亞馬遜文檔清楚地表明,它「取決於您的應用程序來確定讀取流量如何分佈在您的只讀副本中」。有沒有人想過如何擴展Amazon RDS只讀副本?

有沒有人想出了一種可管理的方式來擴展只讀副本?它似乎不是一個非常可擴展的解決方案,可以將我的應用程序的不同部分硬編碼爲從特定副本讀取。有沒有類似於將EC2實例放在負載均衡器後面的方法?

回答

7

AWS工程師提供了有關here問題的一些見解。

這裏是他響應的一個片段:

一般

可以負載均衡流量在以下3個邏輯地方:

  • 應用層 - 創建多個連接池和發送所有讀取到讀取副本。
  • Web框架/中間件 - 一些Web框架內置了對多個數據庫的支持[1]。
  • 外部代理 - 您可以使用外部代理,如MySQLproxy [2]。

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

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

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是複製端點。

3

我一直在使用Route 53加權CNAME來負載均衡RDS只讀副本(和源)。我目前有3個用於readdb.example.com的CNAME記錄集。

第一次指向db.example.com處的源數據庫。這是萬一有複製錯誤。應用程序可以回退到原始數據庫進行讀取。或者如果你願意,你可以讓源代碼讀取一定比例的讀取負載,具體取決於你如何設置權重。路由策略設置爲加權。我將源設置爲1,所以讀取負載的負擔非常小。 TTL設置爲低。我試過從1到10的值。現在我已經把它留在了10。您還必須輸入任何唯一字符串(「源數據庫」)的設置ID。

第二個記錄集指向其中一個只讀副本(readdb1.blahblah.rds.amazonaws.com)。路由策略是加權的,和以前一樣TTL是10。它還需要一個唯一的設置ID。我在5-50之間設置了這個重量,具體取決於。這一個,我確實與一個健康檢查聯繫在一起,你必須提前創建健康檢查。您可能可以使用指向副本的簡單健康檢查,但我做了一些不同的事情。

我把這樣的文件上我的每一個應用服務器(我使用PHP彈性魔豆,但你可以做其他設置/語言類似我承擔的東西):

<?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的健康檢查或任何它的調用。

我現在實際上只使用一個只讀副本,但它比我的源數據庫大得多。這對我來說更經濟,因爲我的源數據庫是多個az。我保留第三個記錄集和第二次健康檢查,以防第一個副本給我帶來問題。這樣,在重新啓動它之前,我不必等待第一個刪除。相反,我立即刪除第一個,並使用第三個記錄集(和第二個健康檢查)中指定的名稱啓動第二個。

0

我想建議更多的易用方法。
這是,DNS Round-robinAmazon Route 53

正如你可以在這個article看到,
Amazon Route 53可以做循環賽多個CNAME記錄。

然後,所有你需要做的是

  1. 在路線53
  2. 更新您的應用程序的配置文件「創建記錄集」。

在我的情況下,這種方法工作正常。

+0

這種方法關注我的一件事是,像Java這樣的一些語言會緩存DNS解析以提高性能,這可能會導致我的流量不能很好地與我的所有隻讀副本保持平衡,如http://docs.aws。 amazon.com/AWSSdkDocsJava/latest/DeveloperGuide/java-dg-jvm-ttl.html – 2016-02-25 21:34:27

+0

除非你有多個後端實例會緩存不同的地址。 – 2016-02-25 21:35:31

+0

@PauloMiguelAlmeida感謝您的信息! – turutosiya 2016-03-02 00:38:28