Redis
集群方案
Redis
的集群解决方案有社区的,也有官方的,社区的解决方案有 Codis
和 Twemproxy
。
Codis
Codis 由我国的豌豆荚团队开源
Twemproxy
Twemproxy 由 Twitter
团队开源。
Redis Cluster
Redis Cluster 是 Redis3.0 之后,官方的集群解决方案,由 Redis
官方团队来实现。
这大大增强了 Redis 水平扩展的能力。
与 Codis 和 Twemproxy 不同的是:Redis Cluster 并非使用 Porxy 模式来连接集群节点,而是使用无中心节点的模式来组建集群。
Redis Cluster 实现在多个节点之间进行数据共享,即使部分节点失效或者无法进行通讯时,Cluster 仍然可以继续处理请求。若每个主节点都有一个从节点支持,在主节点下线或者无法与集群的大多数节点进行通讯的情况下, 从节点提升为主节点,并提供服务,保证 Cluster 正常运行,Redis Cluster 的节点分片是通过哈希槽(hash slot)实现的,每个键都属于这 16384(0~16383) 个哈希槽的其中一个,每个节点负责处理一部分哈希槽。
Redis Cluster 的概念特点
- 去中心、去中间件,各节点平等,保存各自数据和集群状态,节点间活跃互连。
- 传统用一致性哈希分配数据,集群用哈希槽(hash slot)分配。 算法为 CRC16。
- 默认分配 16384 个 slot, 用 CRC16 算法取模 {CRC16 (key)%16384 } 计算所属 slot。
- 最少 3 个主节点
优点:
- 官方解决方案
- 可以在线水平扩展(Twemproxy 的一大弊端就是不支持在线扩容节点)
- 客户端直连,系统瓶颈更少
- 无中心架构
- 支持数据分片
Redis Cluster 集群现实存在的问题
尽管属于无中心化架构一类的分布式系统,但不同产品的细节实现和代码质量还是有不少差异的,就比如 Redis Cluster 有些地方的设计看起来就有一些 “奇葩” 和简陋:
- 不能自动发现:无 Auto Discovery 功能。集群建立时以及运行中新增结点时,都要通过手动执行 MEET 命令或 redis-trib.rb 脚本添加到集群中
- 不能自动 Resharding:不仅不自动,连 Resharding 算法都没有,要自己计算从哪些结点上迁移多少 Slot,然后还是得通过 redis-trib.rb 操作
- 严重依赖外部 redis-trib:如上所述,像集群健康状况检查、结点加入、Resharding 等等功能全都抽离到一个 Ruby 脚本中了。还不清楚上面提到的缺失功能未来是要继续加到这个脚本里还是会集成到集群结点中?redis-trib 也许要变成 Codis 中 Dashboard 的角色
- 无监控管理 UI:即便未来加了 UI,像迁移进度这种信息在无中心化设计中很难得到
- 只保证最终一致性:写 Master 成功后立即返回,如需强一致性,自行通过 WAIT 命令实现。但对于 “脑裂” 问题,目前 Redis 没提供网络恢复后的 Merge 功能,“脑裂” 期间的更新可能丢失
注意,如果设置 Redis Cluster 的数据冗余是 1 的话,至少要 3 个 Master 和 3 个 Slave。
Compared with Twemproxy and Redis Cluster
Codis | Twemproxy | Redis Cluster | |
---|---|---|---|
resharding without restarting cluster | Yes | No | Yes |
pipeline | Yes | Yes | No |
hash tags for multi-key operations | Yes | Yes | Yes |
multi-key operations while resharding | Yes | - | No(details) |
Redis clients supporting | Any clients | Any clients | Clients have to support cluster protocol |
“Resharding” means migrating the data in one slot from one redis server to another, usually happens while increasing/decreasing the number of redis servers.
Codis 和 Redis Cluster 的区别
Redis Cluster 基于 smart client 和无中心的设计,client 必须按 key 的哈希将请求直接发送到对应的节点。
这意味着:
- 如果使用 Redis Cluster,则必须使用特定编程语言对应的 redis driver(如果你所使用的编程语言对应的 Redis Driver 不完善,)
- client 不能直接像使用 Redis 单机一样,通过使用 pipeline 来提高效性能,因而,如果想同时执行多个请求来提高 performance,则只能在 client 端自行实现异步逻辑。
而因为 Codis 有中心节点(即基于 proxy 的设计),对 client 来说,可以像对单机 redis 一样去操作 proxy(除了一些命令不支持),还可以继续使用 pipeline。
并且如果 proxy 后面有多个 redis node,速度会显著快于单 redis 的 pipeline。同时 Codis 使用 zookeeper 来作为辅助,这意味着单纯对于 redis 集群来说,需要额外的机器搭 zk,不过对于很多已经在其他服务上用了 zk 的公司来说这不是问题。