1. 概述
測試目標
測試redis主從模式和redis集群模式下,寫入master,從slave是否能夠立即get到最新結果?如果get是舊的,從set之后多長時間可以get到新數據?
測試條件
- 主從模式:master和slave分別部署在兩臺獨立的vm,配置都是4c8g
- 集群模式:3主3從,部署在一臺機器,配置是4c8g
- 測試資源:redis client采用pyredis和redis-py-cluster,通過locust做壓力測試,部署到另外兩臺機器,分別是8c16g和4c8g
2. Test Results in Master-slave Mode
2.1. test case 1
load value
- duration 10m
- 10 Users
- master cpu 11%
- slave cpu 10%
- rps 361
- median response time 2ms
result
- no errors
- report for details
2.2. test case 2
load value
- duration 10m
- 100 Users
- master cpu 50%
- slave cpu 41%
- rps 3907
- median response time 4ms
result
- max 58ms, min 2ms, average ~15ms
- probability 240/2298306=0.01%
- report for details
2.3. test case 3
load value
- duration 10m
- 500 Users
- master cpu 60%
- slave cpu 59%
- rps 7010
- median response time 36ms
result
- max 46ms, min 44ms, average 45ms
- probability 3/4399069=0.00007%
- report for details
2.4. test case 4
load value
- duration 15m
- 1000 Users
- master cpu 70%
- slave cpu 69%
- rps 9829
- median response time 75ms
result
- max 141ms, min 69ms, average ~90ms
- probability 7/8667389=0.00008%
- report for details
3. Test Results in Cluster Mode
在redis集群下,做相同的測試,對比結果。
3.1. test case 1
load value
- duration 10m
- 100 Users
- 6 instances's cpu 10-30% master, 10% slave
- rps 3889
- median response time 4ms
result
- no errors
- report for details
3.2. test case 2
load value
- duration 10m
- 500 Users
- 6 instances's cpu 30-50% master, 10% slave
- rps 6957
- median response time 40ms
result
- no errors
- report for details
3.3. test case 3
load value
- duration 10m
- 1000 Users
- 6 instances's cpu 50-60% master, 10% slave
- rps 11996
- median response time 50ms
result
- no errors
- report for details
4. 測試結論
關于讀寫分離
在主從模式下,slave是默認可讀的,但是存在數據延遲,延遲隨著并發用戶數增加,先增加后降低,例如
- 10users時,slave沒有數據延遲
- 100users時,slave有240個數據延遲,發生概率240/2298306=0.01%,最高
- 500和1000users時,slave在高rps的情況下,數據延遲反而分別是3和4個。猜測原因是response time的增加掩蓋了數據延遲的問題,response time分別是36ms和75ms
在集群模式下,slave默認不可讀的,如果要讀slave,需要創建connection之后執行
readonly
命令,告知redis-server允許數據延遲
在集群模式下,直接讀slave,會收到Redirect Error,可以參考redirect機制。采用redis-cluster-client可以避免類似問題,如果采用
redis-cli
,記得加-c
所以,如果不要求數據
強一致性
,隨意。如果要求數據強一致性
:
- 并發量小的話,可以采用主從模式,只讀master,不要讀slave,維護方便,且夠用
- 并發很大的話,可以采用集群模式,可以連接到任一節點,隨意讀寫,
集群維護、代碼開發、單request的響應時間
等都會變差,但是支持高并發,最多支持1w個master節點,每個節點10GB的話,一共1TB內存
關于Redis集群
Redis集群是官方推薦的分布式解決方案,但是,生態還不健全,有待進一步發展,例如
redis cluster proxy
、redis cluster client
、redis cluster monitor/dashboard
等。
所以,各家大廠紛紛自主開發了自己的redis相關項目,以滿足自己的業務需求。如果沒有迫切需求,還是
不建議
用cluster,主從模式很經典,基本可以滿足90%業務需求。
5. 測試趣聞
打鐵還需自身硬
剛開始,采用locust單進程1000users壓測redis,沒有出現slave數據延遲。
后來,單機6個locust進程同時壓測redis,還是出不來。
此時,開始懷疑是不是用戶太少,master與slave同步太快?
于是,還是單機6個locust進程,共計1w個user壓測,已到redis maxclients限制,還是沒達到預期。
調整redis maxclients到10w,壓測1.5w,還是沒有slave數據延遲。
最后,感覺單機8c16g壓測兩個4c8g估計不行,需要采用locust分布式測試方案。
Finally,采用兩臺機器,配置分別是8c16g和4c8g,部署分布式locust壓測達到預期,出現了slave數據延遲。
壓測資源需要足夠穩定
壓縮cluster時候,需要更換pyredis為redis-py-cluster,否則直接報錯,因為pyredis不處理redirect。
在pyredis 1000 users很輕松的情況下,redis-py-cluster居然在100 users情況下,出現locust workder missing
(報錯greenlet.GreenletExit
,感覺這個pip包redis-py-cluster不太穩定)的情況。
曾經一度懷疑是redis-py-cluster的問題,想用它壓測一下redis主從,確認問題是否能復現。(當然,我現在也沒深入看redis-py-cluster,不排查其問題)
后來,4c8g的壓測機卡死了。
重啟之后,再壓縮cluster,500users和1000users都正常。