ECS上自建Redis服務壓測報告
背景說明
最近處理的企業大客戶問題中,出現好幾例都是客戶通過購買ECS進行自建Redis服務,並且在使用過程中碰到一些因雲環境的內部限製等原因導致客戶使用中碰到服務異常或者產品性能上無法滿足業務需求的情況。每次處理過程都費時費力,TAM同學一直不辭辛苦的跟進,也拉動了ECS/Redis 研發,網絡,存儲等同學進去排查,又是抓包又是電話會議,最終可能排查下來都是因為場景使用上的不合理,導致客戶在該過程用的不爽,我們支持得也累。
這裏根據目前客戶通常采用的Redis主備Sentinel架構模式,在ECS 上構建Redis環境進行性能壓測,提煉出一些客戶自建Redis可能潛在的一些注意事項。原則上我們建議客戶都采用阿裏雲KVStore服務,但客戶非要通過自建Redis服務,我們則需要把一些注意事項說明清楚,也盡量讓客戶去規避這些問題。
後麵我再專門寫一篇文章,綜合對比阿裏雲KVStore圍繞性能、價格、維護成本、可靠性幾方麵進行“性價比”,以便更好踐行“客戶第一”。
壓測主機規格情況
ECS 實例 | 主機IP | 規格名稱 | CPU | 內存 | 磁盤 | 區域 |
---|---|---|---|---|---|---|
i-2ze29lbqp06cfaxebxur | 192.168.1.130 | ecs.i1.xlarge | 4核 | 16 GB | 高I/O型本地盤 104GB | 華北 2 可用區 A |
i-2ze7ut58w9lsgtn5icbm | 192.168.1.123 | ecs.gn4-c4g1.xlarge | 4核 | 30 GB | SSD雲盤 20GB | 華北 2 可用區 A |
i-2ze7ut58w9lsgtn5icbn | 192.168.1.125 | ecs.gn4-c4g1.xlarge | 4核 | 30 GB | SSD雲盤 20GB | 華北 2 可用區 A |
Redis主備Sentinel集群架構
關於Sentinel 在Redis 高可用的實現上可以參閱:https://redis.io/topics/sentinel
Redis讀寫性能壓測方法
Redis自帶了可一個時間點模擬大量客戶發起大量讀寫請求的工具
redis-benchmark(類似於Apache的ab Tool),下麵為此次壓測過程使用到的執行參數:
./redis-benchmark [-h <hostname>] [-a <passwrod>] [-t <tests>] [-c <clients>] [-d <size>] [-n <requests>] [-P <numreq>]
-h <hostname> Server hostname (default 127.0.0.1)
-p <port> Server port (default 6379)
-a <password> Password for Redis Auth
-t <tests> Only run the comma separated list of tests. The test
names are the same as the ones produced as output.
-c <clients> Number of parallel connections (default 50)
-d <size> Data size of SET/GET value in bytes (default 2)
-n <requests> Total number of requests (default 100000)
-r <keyspacelen> Use random keys for SET/GET/INCR, random values for SADD
Using this option the benchmark will expand the string __rand_int__
inside an argument with a 12 digits number in the specified range
from 0 to keyspacelen-1. The substitution changes every time a command
is executed. Default tests use this to hit random keys in the
specified range.
-P <numreq> Pipeline <numreq> requests. Default 1 (no pipeline).
e.g:
./redis-benchmark -h 192.168.1.123 -a Redis123 -t set -c 100 -d 1024 -n 1000000 -P 100
壓測結果分析
開啟pipeline對QPS性能的影響
從上圖可看出不同規格主機在寫入value size隻有一字節的情況下,不會出現Asynchronous AOF fsync is taking too long這樣慢盤的情況。這種場景下,我們可暫時忽略ECS 存儲盤性能影響。
在不開啟Pipeline的情況下,本地盤SSD和雲盤SSD都在小value讀寫下QPS相差無幾,並且CPU、內存使用率都不高。但是在開啟Pipeline的情況下,本地盤SSD比雲盤SSD的讀寫性能要高出很多。
從Redis官網的介紹來看,Pipeline即對request做隊列化,Redis Server 也對相應結果做隊列化後再response,詳細介紹可以參閱文檔裏頭介紹的一個Request/Response Demo:
https://redis.io/topics/pipelining
哨兵sentinel down-after-milliseconds 參數設置對大value讀寫影響
從上麵2個圖對比可看出無論是本地盤SSD和雲盤SSD,在redis寫入value大於1024字節的情況下都會出現Disk Slow的情況,並且在哨兵配置sentinel down-after-milliseconds 計時5秒的情況下,寫入value大於2048字節情況下會觸發主備切換。
在發生主備切換的時候,主機CPU和內存利用率都不算高,因此在自建redis並且寫入value過大的場景下,慢盤看起來貌似是一個無法規避的問題(這一塊還在調研中,還在谘詢存儲的專家,可能因係統參數設置不合理導致?!)。
假設上麵的問題無法規避,因此這裏down-after-milliseconds 參數設置就很關鍵,如果設置時間過長,會導致寫入失敗切換時間過長,這中間相當於服務不可用。如果設置時間過短,會導致主備切換後節點狀態不一致,可能造成頻繁做主備切換,甚至導致整個集群不可用。
Redis官方建議的配置時間為30秒,如果並發寫入量較高,建議該時間可適當設置長一點。
同等規格寫入的value大小和讀寫QPS的關係
上圖我把down-after-milliseconds 參數設置為官方建議的等待30秒,我們可以看到雖然觸發了多次哨兵的aof_depayed_fsync計數,但是並未觸發Sentinel主備切換,那麼實際應用中則需要通過應用端的重試機製保證寫入成功率。
我們再看看本地盤寫入流量和IO情況:
可以看到寫入量BPS峰值達到87Mbit/s,峰值寫IOPS達到181Count/s
而今年首推的高I/O型本地盤在512KB順序讀寫應用,可提供高達300MB/s的吞吐量能力,16KB隨機讀寫應用,可提供高達12000的隨機IOPS能力;可見對磁盤壓測上遠遠還達不到上限。
排除磁盤性能影響,可見伴隨寫入value的增長,相對來說讀的QPS差別不是很大,但是寫入的QPS會有所下降。那高I/O型本地盤怎麼發揮最大性能呢?答案上麵已經說了,開啟pipeline。
本地連接與遠程連接的QPS性能差異
上圖可以看出在同等規格寫入大小一致value以及不開啟pipeline的情況下,通過本地壓測和遠程壓測的讀寫QPS性能差異很大,明顯本地壓測效果會更好點,那麼遠程壓測的性能瓶頸在哪呢?
從訪問途徑上差異基本可以定位是虛擬網絡的限製,其中主要關注虛擬網絡內網的帶寬限製和收發包數限製,我們查詢了下這個規格ecs.i1.xlarge對應的限製,發現該規格的限製:
內網帶寬(bit/s)為0.8G,內網收發包(PPS)為10萬
因此在不開pipeline,寫入value為512字節的遠程寫入情況下,收發包已經達到上限,故QPS就上不去了。
如果開啟pipeline做隊列化讀寫,可以大幅提供讀寫QPS,但內網帶寬達到上限,如QPS依舊達不到本地寫入的效果。
但是在實際使用場景中,基本上客戶自建Redis都是通過遠程寫入,所以我們建議客戶開啟pipeline並且合理控製好虛擬內網帶寬和收發包數量的限製(配置雲監控),已獲取一個較高的讀寫性能。
其他所有實例規格限製官方文檔查詢:
https://help.aliyun.com/document_detail/25378.html?spm=5176.doc52559.2.1.rZvgXZ
總結
客戶購買ECS自建Redis Sentinel集群的情況下,推薦客戶購買的ECS單獨掛載使用高I/O型本地數據盤,並且對於高並發大量寫入的情況下,建議設置哨兵down-after-milliseconds 大於15秒;如果寫入value過大,需要留意ECS 實例規格對內網帶寬和內網收發包數量的限製,建議開啟pipeline實現更高的讀寫性能。
最後更新:2017-08-24 12:03:27