微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

Redis集群之Codis

【Codis简介】
首先理清楚几个概念,Redis的主从,从从都是一种备份机制,所有节点上的内容基本相同,从节点努力赶上主节点的数据状态;而Sentinel哨兵是一种调度机制,能够监控、并在主节点挂掉的时候择优选择从节点为新主节点。接下来要介绍的Codis是一种分治工具。
在大数据高并发的场景下,单个Redis实例难以支撑。1.单个redis内存不宜过大,内存过大会导致rdb文件过大,进一步导致主从同步时时间过长,在实例重启恢复时会消耗很长的数据加载时间;2.单个redis实例只能利用单个cpu核心,指望单个核心完成海量数据的存取和管理工作,压力会很大。
解决上述问题,需要用到Redis集群,它是利用多个小内存的Redis实例,将分布在多个机器上的cpu核心的计算能力聚集到一起,完成海量数据存储与高并发读写操作。
Codis就是Redis集群方案之一,它是一个中间代理,和Redis一样也使用Redis协议对外提供服务,当客户端向Codis发送指令时,Codis负责将指令转发到后面的Redis实例执行,并将返回结果返回给客户端。客户端操作Codis与操作Redis几乎没有区别,甚至还可以使用相同的客户端SDK。

当集群空间不足时,可以通过动态增加Redis实例来实现扩容需求。
另外启动多个Codis代理还可增加整体的QPS,还能起到容灾功能,挂掉一个Codis代理不妨碍剩下的Codis代理继续服务。

【Codis分片原理】
Codis需要将特定的key转发到特定的Redis实例。Codis认将所有的key划分为1024个slot,首先对传入的key进行crc32运算计算hash值,再将hash后的整数值对1024这个整数进行取模,余数就是对应key的slot。
每个slot会唯一映射到多个Redis实例之一,而一个Redis实例可能被多个slot指向,二者是多对一的关系。如图:

Codis会在内存中维护槽位和Redis实例的映射关系,如果集群节点比较多,建议将这个数值设置大一些,如2048,4096等。
【不同Codis实例之间的槽位关系同步】
Codis的slot-redis实例的关系如果只存储在内存中,那么不同codis实例之间的关系就无法同步。所以Codis还需要一个分布式配置存储数据库专门用来持久化槽位关系。Codis将槽位关系存储在zookeeper中,并且提供了一个Dashboard可以用来观察和修改槽位关系,当槽位关系变化时,Codis Proxy会监听到变化并重新同步槽位关系,从而实现多个Codis Proxy之间共享相同的槽位关系配置。

【扩容】
增加redis实例时,codis需要将一部分slot对应的key分配给新的redis实例。首先,codis增加了SLOTSSCAN指令,可以遍历指定slot下的所有key,然后挨个迁移每个key到新的Redis节点。
在迁移过程中,Codis还是会接收到新的请求,打在正在迁移的slot上,Codis会强制对当前的key进行迁移,然后再将请求转发到新的Redis实例中。
自动均衡】
自动均衡会在系统比较空闲时观察每个redis实例对应的slot数量,如果不平衡,就会自动进行迁移。
【Codis的缺点】
1.不支持事务:Redis的实例分散在了不同的机器,不再支持事务
2.不支持部分指令,Codis官方文档给出了一些列不支持的命令,比如rename,它的参数是两个key,如果这两个key在不同的Redis实例中,该操作无法正确完成
3.为了支持扩容,单个key对应的value不宜过大,否则会带来迁移卡顿。官方给的建议是,单个集合结构总字节容量不要超过1M,如果存放的是社交关系数据,可以考虑分桶存储,在业务上做折中。
4.网络开销,作为中间层,所以网络开销会比redis大,但不明显
5.需要部署zookeeper,运维代价
【mget指令操作过程】
mget用于批量获取多个key值,这些key值可能分布在多个Redis实例中。Codis的策略是将key按照所分配的实例打散分组,然后依次对每个实例调用mget方法,最后将结果汇总为一个,再返回给客户端。

 

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐