集群:Codis

生来就可爱ヽ(ⅴ<●) 提交于 2020-01-06 20:41:16

Codis就是一个Redis代理中间件,其对外协议与Redis协议保持一致,当客户端向Codis发送指令时,Codis负责将指令转发到后面的Redis实例来执行并将返回结果再转回给客户端。

Codis挂接的所有Redis实例构成一个Redis集群,当集群空间不足时,可以通过动态增加Redis实例来实现扩容需求。

问题1:Codis是如何分发客户端请求的呢???

答:

第一步:Codis将所有的key默认划分为1024个槽位(slot),它首先对客户端传过来的key进行crc32运算计算哈希值,再将 hash后的整数值对1024这个整数进行取模得到一个余数,这个余数就是对应key的槽位。(槽位数量默认是1024,它是可以配置的)

第二步:每个槽位都会唯一映射到后面的唯一一个Redis实例。

问题2:由于Codis也可以组成集群,那如何把集群中某个Coids槽位与key映射关系同步到其他Codis中呢?

答:这里Codis必须使用一个分布式数据库来实现这个目标,比如:ZooKeeper、etcd等。

问题3:还有个问题就是,假如1024个槽位映射到N个Redis实例,假如现在变成了(N+M)个Redis实例,那1024个槽位映射关系该怎么重写?

答:通过Codis的SLOTSSCAN指令来扫描1024个槽位所对应的key,然后筛选出符合条件的key,最后把这些key映射到新增加的Redis实例。

同时在新映射这个过程中,某些客户端请求恰恰落在这些待迁移的槽位上,由于当前槽位的数据同时存在于新旧两个槽位中,Codis无法判定迁移过程中的key究竟在哪个实例中,所以当Codis接收到位于正在迁移槽位中的key后,会立即强制对当前的单个key进行迁移,迁移完成后,再将请求转发到新的Redis实例。

同时Redis新增实例,手工均衡太繁琐,Codis提供了自动均衡功能。自动均衡会在系统比较空闲的时候观察每个Redis实例对应的 Slots数量,如果不平衡,就会自动进行迁移。

问题4:那Codis的缺点是什么?

答:

①不同key映射到不同的Redis实例,因此无法跨实例来支持事务。

②rename指令变得很危险,如果rename前后名字被映射到不同的Redis实例下,那rename指令无法被正确执行。

③key的数量不能太多,因为我需要取哈希,再去1024取余,如果key数量太多,会给迁移带来卡顿。官方建议单个集合结构的总字节容量不要超过1M。

④Codis作为中间件,直面客户端请求,因此网络开销比单个Redis大。

⑤如果Codis作为集群使用,必须使用分布式数据库,例如:ZooKeeper,而为了维护ZooKeeper也是一定工作量。

⑥Codis作为非官方Redis集群方案,当官方Redis有变化的时候它要实时去跟进。

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!