雲計算

DRDS和RDS只讀實例性能對比測試

作者:回雁

我們都知道,對於數據庫中基礎信息表來說,它的數據變化頻率低,數據量小,但由於基礎數據本身的特點,大多數相關係統都會對頻繁地讀取它。即便我們通過對數據調取服務進行服務化包裝,通過HSF服務的方式對外暴露,以減少多個系統直接操作數據庫帶來的問題,但數據本身的讀取頻率和併發度都非常高,QPS可以輕易達到10萬以上。通常,使用普通的關係型數據庫,比如RDS很難滿足這樣的場景,業內普遍的做法是在數據庫前加一層數據庫緩存服務,比如redis或memcache來存放基礎信息,以此承載海量的高併發訪問請求。但是也會存在問題,當緩存服務發生故障,或者由於某種異常被擊穿,大量的訪問請求迅速會打到後端的數據庫上,數據庫能不能在關鍵時候扛住壓力,為運維人員爭取時間,快速修復緩存服務,顯得至關重要。

是的,這個時候,阿里雲RDS和DRDS都提供了只讀實例,從原理上來說,RDS只讀實例使用的 MySQL主備複製,一個主庫最多支持5個備庫,備庫提供只讀訪問,用戶程序訪問備庫時使用與主庫不同的地址。而DRDS只讀實例(讀寫分離)其實底層依賴的就是RDS的只讀實例,但是DRDS作為數據庫中間件,為1個主實例和多個只讀實例提供了統一的訪問入口,當DRDS設置了讀寫分離時,對用戶程序是透明的,用戶只需要在DRDS控制檯上自由調整隻讀實例的讀比例即可。在比較新的版本中,RDS也支持了讀寫分離,但是在專有云v2版本中暫時還沒有支持。

那麼,RDS的只讀實例和DRDS的讀寫分離在性能上是否存在差異,我們在阿里雲專有云的環境做一個測試,來驗證這個問題。

一.準備環境

1.1 資源清單

資源類型 規格 數量
RDS主實例 48G內存,磁盤100GB 1
RDS只讀實例 48G內存,磁盤100GB 5
DRDS實例 8節點,64Core CPU,128GB內存 1
測試壓力機ECS 16Core CPU,64GB內存 3

1.2 創建測試表

在DRDS建立非分庫分表的測試表:

IMG_20200403_152200.jpg

1.3 在DRDS中導入測試數據

mysql -u用戶名 -p密碼 -hDRDSIP -P3306 DRDS庫名< bic_base_org_insert.sql

1.4 查看錶大小

mysql> select count(*) from bic_base_org;

+----------+

| count(*) |

+----------+

|   191087 |

+----------+

1 row in set (0.03 sec)

1.5 執行計劃

mysql> explain select id,inst_id,code,name_cn,aic_register_name,postcode,administrative_division,province_code,city_code,status,business_unit,org_level,org_category,manage_level,parent_org_code,erp_parent_org_code   from bic_base_org where id=170000;

+------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+--------+

| GROUP_NAME                                                       | SQL                                                                                                                                                                                                                                        | PARAMS |

+------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+--------+

| DRDS_XNCS_BIC_CS_1513840820139DMOXDRDS_XNCS_BIC_CS_CJWT_0000_RDS | select id,inst_id,code,name_cn,aic_register_name,postcode,administrative_division,province_code,city_code,status,business_unit,org_level,org_category,manage_level,parent_org_code,erp_parent_org_code   from bic_base_org where id=170000 | {}     |

+------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+--------+

1 row in set (0.00 sec)

 

mysql> explain execute  select id,inst_id,code,name_cn,aic_register_name,postcode,administrative_division,province_code,city_code,status,business_unit,org_level,org_category,manage_level,parent_org_code,erp_parent_org_code   from bic_base_org where id=170000;

+----+-------------+--------------+-------+---------------+---------+---------+-------+------+-------+

| id | select_type | table        | type  | possible_keys | key     | key_len | ref   | rows | Extra |

+----+-------------+--------------+-------+---------------+---------+---------+-------+------+-------+

|  1 | SIMPLE      | bic_base_org | const | PRIMARY       | PRIMARY | 8       | const |    1 | NULL  |

+----+-------------+--------------+-------+---------------+---------+---------+-------+------+-------+

1 row in set (0.01 sec)

可以看到 ,SQL在DRDS0號分庫上執行,並且執行計劃是主鍵查詢,這是最快的方式。

二.測試語句

2.1 測試語句:

vi select.sql

 

select id,inst_id,code,name_cn,aic_register_name,postcode,administrative_division,province_code,city_code,status,business_unit,org_level,org_category,manage_level,parent_org_code,erp_parent_org_code   from bic_base_org where id=170000;

這個語句非常簡單,只是針對單表基於索引字段id查詢一條記錄的某些字段,我們重點考察的是大併發下只讀實例的性能表現。

2.2 測試工具:

mysqlslap

三.測試過程

測試分為兩大組:

第一組併發100,對比RDS,RDS只讀實例,DRDS 1個只讀實例和DRDS 5個只讀實例的性能表現。3.1-3.4是第一組測試數據。

第二組將增加併發,進行摸高測試,觀察資源的瓶頸和系統的極限。3.5-3.9是第二組測試數據。

3.1 RDS主實例測試(100併發)

測試說明:100併發,總共跑1千萬條相同的主鍵查詢:

mysqlslap  --query=/select.sql --concurrency=100 --number-of-queries=10000000  --iterations=1 --create-schema=drds_xncs_bic_cs_trou_0000 --engine=innodb  -hRDSIP地址 -u用戶名 -p密碼

 

Benchmark

         Running for engine innodb

         Average number of seconds to run all queries: 154.738 seconds

         Minimum number of seconds to run all queries: 154.738 seconds

         Maximum number of seconds to run all queries: 154.738 seconds

         Number of clients running queries: 100

         Average number of queries per client: 100000

QPS=10000000/154.738=64625,該場景下,資源沒有瓶頸。

注:後面每個測試案例的命令與本案例相似,所以略去測試命令,只展示測試結果。

3.2 RDS只讀實例測試(100併發)

測試說明:100併發,總共跑 1千萬條相同的主鍵查詢:

Benchmark

         Running for engine innodb

         Average number of seconds to run all queries: 150.370 seconds

         Minimum number of seconds to run all queries: 150.370 seconds

         Maximum number of seconds to run all queries: 150.370 seconds

         Number of clients running queries: 100

         Average number of queries per client: 100000

QPS=10000000/150.370=66502,該場景下,資源沒有瓶頸。

3.3 DRDS測試(1個只讀實例,100併發)
測試說明:(把其中一個slave庫讀比例設100% 測drds下一個備庫 ) 100併發,共跑 1千萬條相同的主鍵查詢:

Benchmark

         Running for engine innodb

         Average number of seconds to run all queries: 235.556 seconds

         Minimum number of seconds to run all queries: 235.556 seconds

         Maximum number of seconds to run all queries: 235.556 seconds

         Number of clients running queries: 100

         Average number of queries per client: 100000

QPS=10000000/235.556=42453,該場景下,資源沒有瓶頸。

3.4 DRDS測試(5個只讀實例,100併發)
測試說明:5個只讀每個開20%,100併發,總共跑1千萬條相同的主鍵查詢:

Benchmark

         Running for engine innodb

         Average number of seconds to run all queries: 216.412 seconds

         Minimum number of seconds to run all queries: 216.412 seconds

         Maximum number of seconds to run all queries: 216.412 seconds

         Number of clients running queries: 100

         Average number of queries per client: 100000

QPS=10000000/216.412=46208,該場景下,資源沒有瓶頸。
第一組測試結束,低壓力(100併發)下,RDS主實例和只讀實例性能大致相同,DRDS 1個只讀實例和5個只讀實例的配置對比,性能也基本相似,且不如RDS的性能,這是符合預期的,因為在沒有達到性能極限前,DRDS會比RDS多一層開銷。第二組測試中,數據考慮到單臺ECS性能併發量的侷限性,於是採用多臺ECS併發測試,通過DRDS和RDS控制檯觀察數據,重點關注整體吞吐能力和極限。

3.5 RDS主實例測試(1500併發)
測試說明:共1500併發,兩個ECS執行分別1000,500併發,總共跑 20億條相同的主鍵查詢:

image.png

image.png

RDS連接數:75%(1500),RDS最大連接數為2000

RDSQPS:接近70000

RDS CPU:接近100%,出現瓶頸

SQL的執行時間:幾百-幾萬微秒

3.6 RDS主實例測試(1900併發)

測試說明:共1900併發,三個ECS執行分別1000,500,400 併發,總共跑 30億條相同的主鍵查詢。
image.png

image.png

RDS連接數:1900,達到瓶頸

RDS QPS:接近70000

RDS CPU:接近100%,達到瓶頸

SQL的執行時間:幾百-幾萬微秒

3.7 DRDS(5個只讀實例,1000併發)

測試說明:5個只讀每個開20%,1000併發,總共跑1億條相同的主鍵查詢:

Benchmark

         Running for engine innodb

         Average number of seconds to run all queries: 1790.584 seconds

         Minimum number of seconds to run all queries: 1790.584 seconds

         Maximum number of seconds to run all queries: 1790.584 seconds

         Number of clients running queries: 1000

         Average number of queries per client: 100000

QPS=100000000/1790=55866,該場景下,資源沒有瓶頸。

3.8 DRDS(5個只讀實例,10000併發)

測試說明:(5個只讀每個開20%) 共10000併發,兩個ECS執行分別5000 總共跑 20億條相同的主鍵查詢:
image.png

image.png

image.png

物理RT:1.1ms左右

QPS:大約125000左右

RDS SQL執行時間:100微秒左右

客戶端ECS千兆網卡打滿,出現瓶頸

3.9 DRDS(5個只讀實例,15000併發)

測試說明:(5個只讀每個開20%) 共15000併發,三個ECS執行分別5000 總共跑 30億條相同的主鍵查詢。

image.png

image.png

DRDS QPS:大約210000左右

RDS上SQL的執行時間:100微秒左右

物理RT:2.1ms左右

客戶端ECS網卡被打滿,出現瓶頸

四.測試總結:

數據庫 連接數 QPS RT/SQL執行時間 瓶頸分析
RDS主實例 100 64625 15.4us 沒有瓶頸
RDS只讀實例 100 66502 15.0us 沒有瓶頸
DRDS(1主+1只讀) 100 42453 23.6us 沒有瓶頸
DRDS(1主+5只讀) 100 46208 21.6us 沒有瓶頸
RDS主實例 1500 69980 幾百~幾萬us RDS CPU打滿
RDS主實例 1900 69000 幾百~幾萬us RDS CPU、連接數打滿
DRDS(1主+5只讀) 1000 55866 17.9us 沒有瓶頸
DRDS(1主+5只讀) 10000 125000 1.9ms(DRDS)100us(RDS) 加壓ECS網卡打滿
DRDS(1主+5只讀) 15000 210000 11.2ms(DRDS)100us(DRDS) 加壓ECS網卡打滿

4.1 單臺ECS客戶端低壓力測試

RDS主實例和只讀實例性能基本相同;
只有1個只讀實例的DRDS耗時比單RDS主實例或單RDS只讀實例相差較大,大約損失35%的性能;
開滿5個只讀實例的DRDS耗時比單RDS主實例或者單RDS只讀實例相差較大,大約損失29%的性能;
低壓力下測試場景,平均RT在幾十微秒這個數量級。

4.2 多臺ECS客戶端大壓力極限測試

RDS單個主實例配置2000最大併發數,選用1900併發,QPS達到69000,響應時間在毫秒級。此時連接數和CPU都已經接近極限;
DRDS開滿5個只讀實例,三臺ECS到達15000的併發,DRDS的QPS可以達到210000左右,響應時間達到毫秒級。此時除客戶端ECS達到極限外,RDS和DRDS均有資源剩餘可用;
因為DRDS是數據庫中間件,同時有內置連接池,所以從單個連接的SQL性能來說,DRDS不如RDS,但差異只體現在微秒這個數量級;而正因為DRDS有內置連接池,大規模大量連接高併發場景下,DRDS體現出優勢,且響應時間還保持在毫秒級別,可以接受;
RDS讀寫分離由於專有云還不支持,所以沒有進行測試,預期會比單實例RDS性能稍差。從數據庫連接數來看,也不如DRDS支持得多,需要在應用程序中設置連接池,從而滿足更高的併發需求。

Leave a Reply

Your email address will not be published. Required fields are marked *