介紹
redis作為一款優秀的NoSQL代表軟件,正變得越來越流行,雖然Redis很容易就可以啟動并使用,但是要想在線上用好它卻也并非易事。redis的高可用和可擴展無論是自帶的Redis Sentinel還是Redis Cluster都要求客戶端進行額外的支持,而目前基本上沒有合適的客戶端能夠做這些事情,實際上客戶端來做這些事情也并不合適,它會讓維護變得特別困難。因此在客戶端和redis服務端之間加一層代理成了一種理想的方案,代理屏蔽后端Redis實現細節向客戶端提供redis服務,可以完美的解決Redis的高可用和擴展性問題,同時代理的引入也使得Redis維護變得更加簡單。在本文所要介紹的代理predixy之前,已經有幾款流行的redis代理,它們各具特色。接下來,我們就來比較以下代理:
代理 | 簡介 |
---|---|
predixy | 高性能全特征redis代理,支持Redis Sentinel和Redis Cluster |
twemproxy | 快速、輕量級memcached和redis代理 |
codis | redis集群代理解決方案 |
redis-cerberus | Redis Cluster代理 |
詳細功能對比
特性 | predixy | twemproxy | codis | redis-cerberus |
---|---|---|---|---|
高可用 | Redis Sentinel或Redis Cluster | 一致性哈希 | Redis Sentinel | Redis Cluster |
可擴展 | Key哈希分布或Redis Cluster | Key哈希分布 | Key哈希分布 | Redis Cluster |
開發語言 | C++ | C | GO | C++ |
多線程 | 是 | 否 | 是 | 是 |
事務 | Redis Sentinel模式單Redis組下支持 | 不支持 | 不支持 | 不支持 |
BLPOP/BRPOP/BLPOPRPUSH | 支持 | 不支持 | 不支持 | 支持 |
Pub/Sub | 支持 | 不支持 | 不支持 | 支持 |
Script | 支持load | 不支持 | 不支持 | 不支持 |
Scan | 支持 | 不支持 | 不支持 | 不支持 |
Select DB | 支持 | 不支持 | 支持 | Redis Cluster只有一個DB |
Auth | 支持定義多個密碼,給予不同讀寫及管理權限和Key訪問空間 | 不支持 | 同redis | 不支持 |
讀從節點 | 支持,可定義豐富規則讀指定的從節點 | 不支持 | 支持,簡單規則 | 支持,簡單規則 |
多機房支持 | 支持,可定義豐富規則調度流量 | 不支持 | 有限支持 | 有限支持 |
統計信息 | 豐富 | 豐富 | 豐富 | 簡單 |
簡單來說,predixy既支持Redis Sentinel也支持Redis Cluster
- 后端為Redis Sentinel監控的一組Redis,功能完全等同于原始Redis
- 后端為Redis Sentinel監控的多組Redis,則有部分功能受限
- 后端為Redis Cluster,功能完全等同于Redis Cluster
性能
作為redis代理,高性能是硬性要求,為了測試上面四款代理的性能接下來我們就來做個簡單的評測,測試平臺及各代理具體的版本信息如下:
名稱 | 內容 |
---|---|
CPU | AMD Ryzen 7 1700X Eight-Core Processor 3.775GHz |
內存 | 16GB DDR4 3000 |
系統 | x86_64 GNU/Linux 4.10.0-27-generic #30~16.04.2-Ubuntu |
predixy | 版本1.0.1,源碼默認參數編譯 |
twemproxy | 版本0.4.1,源碼默認參數編譯 |
codis | 二進制發布版本codis3.2.0-go1.8.1-linux.tar.gz |
cerberus | github遷出8d68a5d源碼默認參數編譯 |
redis-server、各代理、redis-benchmark均在這一臺機器上運行。
redis部署:
代理 | redis后端部署 |
---|---|
predixy | redis cluster模式部署三個redis主節點, slots平分 |
twemproxy | 三個redis主節點,采用crc16哈希,modula分布 |
codis | 三個redis主節點,slots平分 |
cerberus | redis cluster模式部署三個redis主節點, slots平分 |
以下測試的結果中,橫坐標為數據大小、縱坐標為qps或者毫秒。
單線程SET/GET測試
這里單線程是指四款代理都運行在單線程下(下同),redis-benchmark默認并發50個客戶端連接,每個連接每次發送一個命令收到響應后再發下一個命令。這是很多線上實際的場景。
測試命令:
$ redis-benchmark -p xxx -t set,get -r 3000 -n 1000000 -d xxx
測試結果:
結果說明:
在吞吐上,四款代理的性能排列的整齊有序,predixy大幅領先于另外三款代理,而twemproxy又以較大優勢領先另外兩個,剩下的兩個codis在數據量小于512的時候稍稍領先cerberus,而當數據量大于512的時候,codis對cerberus的領先越來越大。整體上在數據量達到16KB時,由于redis-benchmark本身成為瓶頸,predixy和twemproxy的SET成績差不多了。
在延時上,codis由于語言的問題,一直都大于另外三款代理,后續測試也一樣。
單線程PIPELINE SET/GET測試
在有些場景下,客戶端可能在處理一個請求時可能需要發起多次redis請求,這時如果把多個redis請求pipeline一起請求的話,會大幅改善性能。本輪測試就來看看當客戶端一次發送多個請求時我們各代理表現如何?Redis-benchmark依舊是并發50個連接,但是一次發送20個命令。
測試命令:
$ redis-benchmark -p xxx -t set,get -r 3000 -n 5000000 -P 20 -d xxx
測試結果:
結果說明:
在吞吐上,redis-benchmark一次pipeline 20個命令后,各代理的吞吐量全都猛增。predixy更是一騎絕塵,遙遙領先另外三個,而最后看到在GET 4K數量據的時候predixy表現和其它代理差不多是因為對predixy來說,當數據量大于2K時redis-benchmark自身已經成為瓶頸。另外三款代理,在上輪測試中落后的cerberus在本輪測試一開始表現遠好過twemproxy和codis,但cerberus還是存在隨著數據量變大性能迅速降低的問題。twemproxy和codis在本輪測試中表現基本相當。
在時延上,codis固有的問題表現較差,另外三款在數據量較小時差別較小,而當數據量超過512時,predixy則表現出較明顯的優勢。
雙線程PIPELINE SET/GET測試
測完了單線程,現在我們開始多線程測試,由于twemproxy不支持多線程,因此twemproxy不參與多線程的測試。考慮到redis-benchmark本身是個單線程程序,在多線程代理下如果我們再測單個命令的性能,那redis-benchmark很可能就是瓶頸,則無法更明確的看出各代理的性能差異,因此我們直接測試pipeline,還跟上輪一樣,50個并發連接,一次發送20個命令。
測試命令:
$ redis-benchmark -p xxx -t set,get -r 3000 -n 10000000 -P 20 -d xxx
測試結果:
結果說明:
總體趨勢和第二輪單線程pipeline測試一致,predixy在本輪測試中依舊取得了領先,不過在開始階段cerberus和predixy遙遙領先于codis,cerberus和predixy差距不大。但是隨著數據量的變大,cerberus再次顯示出了性能急劇降低的問題,到1K以后甚至就比codis差了。
結論
在功能的對比上,predixy相比另外三款代理更為全面,基本可以完全適用原生redis的使用場景。在性能上,predixy在各輪測試中都以較大優勢領先。對各代理的總結如下:
- predixy:功能全面,既可以使用單個主從redis,也可使用Redis Cluster;性能優異。
- twemproxy:高可用依賴一致性哈希,僅在緩存場景下適用,不適用存儲使用;性能中等。
- codis:適用redis集群使用;性能一般。
- cerberus:適用使用Redis Cluster;在數據量較小且pipeline使用情況下性能尚可,否則性能較差。