> 文章列表 > Redis高可用之3种集群方案对比

Redis高可用之3种集群方案对比

Redis高可用之3种集群方案对比

Redis集群方案使用建议:

  • Redis cluster:除非是1000个节点以上的超大规模集群,优先考虑使用Redis cluster
  • codis:旧项目如果仍在使用codis,可继续使用,但也推荐迁移到Redis cluster
  • twemproxy:不建议使用,与codis同为proxy方案,但不如codis(twemproxy不能平滑地扩容)
  • 客户端分片:应当禁止使用,因为扩容复杂,如果2个服务同时读写,其中一个修改了路由,另一个不修改会有问题

其中客户端分片、Redis Cluster属于无中心化的集群方案,Codis属于中心化的集群方案。

是否中心化是指客户端访问多个Redis节点时:是直接访问还是通过一个中间层Proxy来进行操作,直接访问的就属于无中心化的方案,通过中间层Proxy访问的就属于中心化的方案,它们有各自的优劣。

一、客户端分片

我们只需要部署多个Redis节点,具体如何使用这些节点,主要工作在客户端。

客户端通过固定的Hash算法,针对不同的key计算对应的Hash值,然后对不同的Redis节点进行读写。

 

 

客户端分片需要业务开发人员事先评估业务的请求量和数据量,然后让DBA部署足够的节点交给开发人员使用即可。

1、优点

部署非常方便,业务需要多少个节点DBA直接部署交付即可,剩下的事情就需要业务开发人员根据节点数量来编写key的请求路由逻辑,制定一个规则,一般采用固定的Hash算法,把不同的key写入到不同的节点上,然后再根据这个规则进行数据读取。

2、缺点

是业务开发人员使用Redis的成本较高,需要编写路由规则的代码来使用多个节点,

如果事先对业务的数据量评估不准确,后期的扩容和迁移成本非常高,因为节点数量发生变更后,Hash算法对应的节点也就不再是之前的节点了。

3、一致性哈希

所以后来又衍生出了一致性哈希算法,就是为了解决当节点数量变更时,尽量减少数据的迁移和性能问题。

这种客户端分片的方案一般用于业务数据量比较稳定,后期不会有大幅度增长的业务场景下使用,只需要前期评估好业务数据量即可。

二、Redis Cluster方式

Redis cluster是官方支持的Redis集群方案:

 

  • 去中心化架构,不依赖外部存储,每个节点都有槽位信息、以及一部分数据,各节点之间使用gossip协议交互信息
  • 划分为16384个slot槽位,每个key按照分片规则,对key做crc16 % 16384得到slot id
  • 每个Redis节点存储了一部分槽位数据,各个Redis节点共同分担16384个slot槽位
  • 客户端需遵守Redis cluster规范读写数据,客户端连接集群时,会得到一份集群的槽位配置信息,客户端本地缓存了slot到node的映射关系,以便直接定位到对应的Redis节点

1、用key计算出slot

  • 通过本地缓存的slot到node映射关系(某个slot范围映射到某个node),用slot得出node
  • 请求对应的node节点,如果key对应的槽位在Redis节点存储的各槽位中,则查询结果
  • 如果key对应的槽位不在Redis节点存储的各槽位中(即key所在的槽位不归该节点管理),则返回moved <节点> 提示客户端再次请求指定的节点,并更新本地映射关系
  • 如果请求的key对应槽位正在迁移,则返回ask <节点> 提示客户端再次请求指定的节点
  • 主库读写,从库用于高可用备份、一般不用来承担读请求:主从同步通过指令流、环形数组来做增量同步,通过RDB来做全量同步

2、优缺点

优点:

  • 官方支持的集群方案,能使用最新feature
  • 性能好,无多余网络开销
  • 无一致性问题,读写请求都走主节点
  • 槽位更精细,16384(2^14)相比于codis的1024

缺点:

  • 如果是从旧版不支持集群的Redis升级而来,需做较大改造,把传统的Jedis client需替换成智能客户端来维护key到slot的映射关系,如lettuce
  • 官方是最小使用原则,没有易用的扩容、迁移工具,需要寻找社区提供的易用界面,或自行研发
  • 迁移过程中性能可能受影响,有3次请求:首次get得到ask返回、再次asking确认指定节点是否有槽位、最后get

3、请求转发

Redis Cluster没有采用中心化模式的Proxy方案,而是把请求转发逻辑一部分放在客户端,一部分放在了服务端,它们之间互相配合完成请求的处理。

Redis Cluster没有了中间的Proxy代理层,那么是如何进行请求的转发呢?

 

Redis把请求转发的逻辑放在了Smart Client中,要想使用Redis Cluster,必须升级Client SDK,这个SDK中内置了请求转发的逻辑,所以业务开发人员同样不需要自己编写转发规则,Redis Cluster采用16384个槽位进行路由规则的转发。

没有了Proxy层进行转发,客户端可以直接操作对应的Redis节点,这样就少了Proxy层转发的性能损耗。

Redis Cluster也提供了在线数据迁移、节点扩容缩容等功能,内部还内置了哨兵完成故障自动恢复功能,可见它是一个集成所有功能于一体的Cluster。因此它在部署时非常简单,不需要部署过多的组件,对于运维极其友好。

Redis Cluster在节点数据迁移、扩容缩容时,对于客户端的请求处理也做了相应的处理。当客户端访问的数据正好在迁移过程中时,服务端与客户端制定了一些协议,来告知客户端去正确的节点上访问,帮助客户端订正自己的路由规则。

三、Codis方案

codis是Go语言编写的Redis proxy集群方案:

 

codis-proxy作为上层proxy,负责路由请求至底层的Redis分片。client与proxy交互,可以把proxy当作普通的Redis实例一样,因为codis-proxy实现了Redis协议,API保持一致。

Redis分片是一个codis-group,包括了多个codis-server,其中有1个主节点、n个从节点,用来作读写分离,主节点承担写请求,从节点分摊读请求。各个分片的Redis实例是独立的,互不感知。codis-server与普通Redis实例的区别是,在Redis的基础上扩展实现了slot槽的功能,用于扩容、数据迁移。

 

  • 分片规则:对key做crc32 % 1024
  • 强依赖zookeeper,来存储节点槽位信息。
  • codis-dashboard、codis-fe是集群运维工具。

1、优点

  • 客户端无需感知背后细节,跟Redis单实例无明显区别(除部分命令不支持)
  • 平滑扩容,运维操作简单,有易于使用的web界面

2、缺点

  • 是在Redis官方未支持集群方案之前的可选方案,目前已停止更新
  • proxy会带来额外的网络开销,请求链路多了一层
  • 读写分离可能出现不一致的问题,也需要评估请求读写比
  • 需要额外维护zookeeper