33.Codis和Redis Cluster的对比
Reids的切片集群官方方案 Redis Cluster是切片集群的实现方式之一,在Redis Cluster之外,还有着Codis
那么本章我们也是主要说一下Codis的整体架构,然后对于数据流转的基本流程,以及优缺点这几点进行讲解
1.Codis的整体架构
其包含了4类关键组件
codis server进行了二次开发的Redis实例,增加了额外的数据结构,支持数据迁移操作,负责实际的数据读写请求
codis proxy 接受客户端请求,转发给codis server
Zookeeper集群 保存集群元数据,数据位置信息和codis proxy信息
codis dashboard 和 codis fe 共同组成了集群管理工具,codis dashboard 执行集群管理工作,增删codis server codis proxy 和数据迁移,codis fe负责提供Web操作界面
整体框架如下
为了让集群接收并处理请求,要先使用codis dashboard设置codis server和codis proxy访问地址,设置完成后 codis server和codis proxy开始接收链接
客户端读写数据时候,客户端直接和codis proxy建立连接,proxy支持Redis的RESP交互协议,所以访问proxy的时候,和访问原生的Redis实例没有任何区别
最后codis proxy接收到请求,就会查询数据和codis server的映射关系,并将请求转发给相应的codis server进行处理,处理完成,返回给codis proxy,最后返回数据
那么在集群中,Codis如何保存数据的
Codis中,数据如何和codis server挂钩的呢?具体来说,分为两步
第一步,Codis一共有1024个slot,默认情况下,会把这1024个Slost在所有server上平分
第二步,数据读写的时候,会使用CRC算法获取哈希值,并对1024进行取模,取模后的值, 对应Slot的编号
然后对于第一步,Slot和codis server的映射关系表称为数据路由表,在建立并分配完成之后,dashboard会将其发送给Zookeeper,codis-proxy会将路由表缓存在本地,这样就完成了持久化和快速访问需求
其次是集群下的扩容问题
Codis按照Slot的粒度来进行数据迁移,我们看下迁移的基本流程
分为了两种迁移方式,分别是同步迁移和异步迁移,同步迁移是指的,在源server上选择数据,发往目的server
目的server收到数据后,返回确认给源server,这时候源server会在本地将之前的数据进行删除
然后有多个数据的情况下,就会不断的执行前两步,直到迁移完成
再同步模式下,这个迁移流程中,源server会阻塞的
而异步情况下,源server只负责将数据发往目的server就可以了,不必等待目的server执行完成
目的serer会在收到数据并反序列化之后,给源server返回一个ACK,让源server将迁移的数据删除
然后由于选择key进行删除的时候,遇到bigkey的话,必然会阻塞长时间,故codis采用了指令拆分的原因,对于bigkey中的每一个元素,都使用一条指令来进行迁移,而不是将整个bigkey序列化后传输,这种化整为零的方式,避免了bigkey迁移的时候,阻塞源server的可能性
比如说,我们有1个1万个元素的List类型数据,使用异步迁移的时候,就会传输1万条RPUSH命令,依次执行,完成数据迁移,为了避免迁移中出现故障导致的失败,还会在迁移中加上一个临时过期时间,避免影响原子性
而且codis还贴心的支持每次迁移多个key,通过异步迁移命令
SLOTSMGRTTAGSLOT-ASYNC的参数 numkeys设置每次迁移的key数量
我们学习的是codis server的扩容和数据迁移的机制,在Codis集群中,增加codis server,还有时候需要增加codis proxy
codis proxy本身是无状态的,直接启动proxy,通过codis dashboard将proxy加入集群即可
然后在实际使用中,是否需要重新开发客户端呢?
这一点,在codis集群中,被codis proxy完美的解决了,方便业务应用直接使用客户端代码,保证了业务代码的稳定性和兼容性
最后是关于集群的可靠性,对于集群可靠性,我们需要针对集群的不同组件查看
首先是codis server,本质上就是Redis实例,Codis使用主从集群来保证codis server的可靠性
Codis给每个server配置从库,使用哨兵机制来进行监控,发生故障的时候,主从库可以进行切换,保证了server的可靠性
其次是codis proxy,这个组件本身就是无状态的,所以不用担心
最后是Zookeeper,zookeeper利用集群来保证数据,有半数以上的的ZK正常工作,就可以提供服务
对于codis dashboard和codis fe来说,主要是提供额外的配置管理和管理员手动操作,负载不打,一般手动重启即可
最后我们说明一下Codis和Redis Cluster方案选择
整体的区别如上表,
而且从稳定性来看,Codis的稳定性相对高,但是由于引入了过多的组件,导致复杂度也相对高
从兼容性来看,codis支持原生客户端,而redis cluster需要使用集群客户端
最后一点就是,由于Codis是由3.2.8版本Redis开发而来的,所以Codis对于后续的新命令及新的数据类型支持不好,比如BITOP BLPOP BRPOP,MUTLI EXEC等命令,对于新功能的替换,Codis并不是一个好选择
总结一下,我们学习了Redis切片集群的Codis方案,包含codis server,codis proxy Zookeeper codis dashboard codis fe 四大类组件,并且我们回顾下主要功能
codis proxy和codis server 负责处理数据读写请求,codis proxy 和客户端链接,接收请求,并转发给codis server,而codis server负责具体处理请求
codis dashboard 和codis fe负责集群管理,codis dashboard执行管理操作,codis fe提供Web管理界面
Zookeeper集群负责保存集群的所有元数据,包含路由表,proxy实例信息等,不过codis还支持使用etcd来保存元数据
最后一个问题,假设Codis集群中保存的键值对大部分都是Hash,每个Hash大约在10万-20万,每个元素大小约2KB,这样迁移,会对Codis性能造成影响吗?
我觉着不会造成影响,因为在Codis中,对于bigkey的迁移,是异步且拆分的,将集合对象拆分为更为细粒度的单个对象进行传输,避免了传输过程中的阻塞问题