介绍
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使用情况下性能尚可,否则性能较差。