结论
有以下几种Redis集群方案,先说结论:
-
Redis cluster:应当优先考虑使用Redis cluster。 -
codis:旧项目如果仍在使用codis,可继续使用,但也推荐迁移到Redis cluster。 -
twemproxy:不建议使用,与codis同为proxy方案,但不如codis(twemproxy不能平滑地扩容)。 -
客户端分片:应当禁止使用,因为扩容复杂,如果2个服务同时读写,其中一个修改了路由,另一个不修改会有问题。
下面重点介绍Redis cluster和codis。
Redis cluster原理
架构

是官方支持的Redis集群方案:
-
去中心化架构,不依赖外部存储,每个节点都有槽位信息、以及一部分数据,各节点之间使用gossip协议交互信息 -
划分为16384个slot槽位,每个key按照分片规则,对key做crc16 % 16384得到slot id -
每个Redis节点存储了一部分槽位数据,各个Redis节点共同分担16384个slot槽位 -
客户端需遵守Redis cluster规范读写数据,客户端连接集群时,会得到一份集群的槽位配置信息,客户端本地缓存了slot到node的映射关系,以便直接定位到对应的Redis节点 -
用key计算出slot -
通过本地缓存的slot到node映射关系(某个slot范围映射到某个node),用slot得出node -
请求对应的node节点,如果key对应的槽位在Redis节点存储的各槽位中,则查询结果 -
如果key对应的槽位不在Redis节点存储的各槽位中(即key所在的槽位不归该节点管理),则返回moved <节点> 提示客户端再次请求指定的节点,并更新本地映射关系 -
如果请求的key对应槽位正在迁移,则返回ask <节点> 提示客户端再次请求指定的节点 -
主库读写,从库用于高可用备份、一般不用来承担读请求:主从同步通过指令流、环形数组来做增量同步,通过RDB来做全量同步
优点
-
官方支持的集群方案,能使用最新feature -
性能好,无多余网络开销 -
无一致性问题,读写请求都走主节点 -
槽位更精细,16384(2^14)相比于codis的1024
缺点
-
如果是从旧版不支持集群的Redis升级而来,需做较大改造,把传统的Jedis client需替换成智能客户端来维护key到slot的映射关系,如lettuce -
官方是最小使用原则,没有易用的扩容、迁移工具,需要寻找社区提供的易用界面,或自行研发 -
迁移过程中性能可能受影响,有3次请求:首次get得到ask返回、再次asking确认指定节点是否有槽位、最后get
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是集群运维工具。
优点
-
客户端无需感知背后细节,使用起来跟Redis单实例无明显区别(除部分命令不支持) -
平滑扩容,运维操作简单,有易于使用的web界面
缺点
-
是在Redis官方未支持集群方案之前的可选方案,目前已停止更新 -
proxy会带来额外的网络开销,请求链路多了一层 -
读写分离可能出现不一致的问题,也需要评估请求读写比 -
需要额外维护zookeeper
原文始发于微信公众号(Java烘焙师):架构师必备:Redis的几种集群方案
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/27398.html