文章目录

  • Redis学习笔记-Codis 和 Redis Cluster 的区别
  • 1.笔记图
  • 2.Codis 集群的 4 类关键组件
  • 3.Codis 是如何处理请求的?
  • 4.Codis 的关键技术原理
  • 4.1 数据如何在集群里分布?
  • 4.2 数据、Slot 、 codis server 的映射关系
  • 5.Codis集群扩容和数据迁移
  • 5.1 Codis 集群扩容
  • 5.2 Codis 集群数据迁移
  • 6.如何保证可靠性
  • 7.切片集群方案选择建议


Redis学习笔记-Codis 和 Redis Cluster 的区别

之前学习过 Redis Cluster,但是在 Redis Cluster 官方正式发布前,业界已经广泛使用 Codis,这篇文章主要学习一下 Codis 的整体架构和流程,对比一下 Redis Cluster

1.笔记图

cluster key redis 槽位 redis cluster codis_redis

2.Codis 集群的 4 类关键组件

cluster key redis 槽位 redis cluster codis_mysql_02

  • codis server:这是进行了二次开发的 Redis 实例,其中增加了额外的数据结构,支持数据迁移操作,主要负责处理具体的数据读写请求
  • codis proxy:接收客户端请求,并把请求转发给 codis server
  • Zookeeper 集群:保存集群元数据,例如数据位置信息和 codis proxy 信息
  • codis dashboard 和 codis fe
  • codis dashboard:负责执行集群管理工作,包括增删 codis servercodis proxy 和数据迁移
  • codis fe:提供 dashboardWeb 操作界面,便于直接在 Web 界面上集群管理

3.Codis 是如何处理请求的?

cluster key redis 槽位 redis cluster codis_数据库_03

  • 使用 codis dashboard 设置 codis servercodis proxy 的访问地址,完成设置后,codis servercodis proxy 才会开始接收连接
  • 当客户端要读写数据时,客户端直接和 codis proxy 建立连接
  • codis proxy 本身支持 RedisRESP 交互协议,客户端访问 codis proxy 时,和访问原生的 Redis 实例没有什么区别
  • codis proxy 接收到请求,就会查询请求数据和 codis server 的映射关系,并把请求转发给相应的 codis server 进行处理

4.Codis 的关键技术原理

4.1 数据如何在集群里分布?

  • Codis 集群一共有 1024Slot,编号依次是 01023,可以手动分配,也可以自动均匀分配
  • 当客户端读写数据时,使用 CRC32 算法计算数据 key 的哈希值,把这个哈希值对 1024 取模,对应 Slot 的编号

4.2 数据、Slot 、 codis server 的映射关系

cluster key redis 槽位 redis cluster codis_nosql_04

  • 数据 keySlot 的映射关系是客户端在读写数据前直接通过 CRC32 计算得到的
  • Slotcodis server 的映射关系是通过分配完成的,需要用存储系统保存,否则,集群有故障,映射关系就会丢失
  • Slotcodis server 的映射关系称为数据路由表(简称路由表)
  • codis dashboard 上分配好路由表,dashboard 会把路由表发给 codis proxydashboard 也会把路由表保存在 Zookeeper

5.Codis集群扩容和数据迁移

5.1 Codis 集群扩容

  • 增加 codis server 时扩容步骤
  • 启动新的 codis server,将它加入集群
  • 把部分数据迁移到新的 server
  • 增加 codis proxy 时扩容步骤
  • 直接启动 proxy,再通过 codis dashboardproxy 加入集群就行
  • codis proxy 的访问连接信息都会保存在 Zookeeper 上,新增了 proxy 后,Zookeeper 上会有最 新的访问列表,客户端也就可以从 Zookeeper 上读取 proxy 访问列表,把请求发送给新增的 proxy

5.2 Codis 集群数据迁移

  • 增加 codis server 时迁移数据步骤
  • 在源 server 上,Codis 从要迁移的 Slot 中随机选择一个数据,发送给目的 server
  • 目的 server 确认收到数据后,会给源 server 返回确认消息。这时,源 server 会在本地将刚才迁移的数据删除
  • 第一步和第二步就是单个数据的迁移过程。Codis 会不断重复这个迁移过程,直到要迁移的 Slot 中的数据全部迁移完成
  • Codis 的两种数据迁移模式
  • 同步迁移:
  • 在数据从源 server 发送给目的 server 的过程中,源 server 是阻塞的,无法处理新的请求操作
  • 迁移过程涉及多个操作(数据在源 server 序列化、网络传输、在目的 server 反序列化、在源 server 删除)
  • 如果迁移的数据是一个 bigkey,源 server 就会阻塞较长时间,无法及时处理用户请求
  • 异步迁移
  • 当源 server 把数据发送给目的 server 后,就可以处理其他请求操作了,不用等到目的 server 的命令执行完
  • 目的 server 会在收到数据并反序列化保存到本地后,给源 server 发送一个 ACK 消息,表明迁移完成
  • server 在本地把刚才迁移的数据删除
  • 在迁移过程中,迁移的数据会被设置为只读,源 server 上的数据不会被修改,不会出现和目的 server 上的数据不一致的问题
  • 迁移bigkey:
  • 对于 bigkey,异步迁移采用了拆分指令的方式进行迁移,对 bigkey 中每个元素,用一条指令进行迁移,而不是把整个 bigkey 进行序列化后再整体传输
  • Codis 在目标 server 上,给 bigkey 设置过期时间,迁移过程发生故障,目标 serverkey 会在过期后被删除,不影响迁移的原子性,正常完成迁移后,过期时间会被删除
    可以通过异步迁移命令 SLOTSMGRTTAGSLOT-ASYNC 的参数 numkeys 设置每次迁移的 key 数量

6.如何保证可靠性

  • codis server 其实就是 Redis 实例,只不过增加了和集群操作相关的命令
  • Redis 主从复制和哨兵机制在 codis server 上是可以用的,Codis 使用主从集群来保证 codis server 的可靠性
  • Codis 给每个 server 配置从库,并使用哨兵机制进行监控,当发生故障时,主从库可以进行切换,从而保证了 server 的可靠性
  • 每个 server 成了一个 server group,每个 group 中是一主多从的 server
  • codis proxy 在转发请求时,也是按照数据所在的 Slotgroup 的对应关系
  • proxy 上的信息源头都是来自 Zookeeper(例如路由表)
  • Zookeeper 集群使用多个实例来保存数据,只要有超过半数的 Zookeeper 实例可以正常工作, Zookeeper 集群就可以提供服务,也可以保证这些数据的可靠性

7.切片集群方案选择建议

  • 从稳定性和成熟度来看,Codis 应用得比较早,在业界已经有了成熟的生产部署。虽然 Codis 引入了 proxyZookeeper,增加了集群复杂度,但是,proxy 的无状态设计和 Zookeeper 自身的稳定性,也给 Codis 的稳定使用提供了保证。而 Redis Cluster 的推出时间晚于 Codis,相对来说,成熟度要弱于 Codis,如果你想选择一个成熟稳定的方案,Codis 更加合适些
  • 从业务应用客户端兼容性来看,连接单实例的客户端可以直接连接 codis proxy,而原本连接单实例的客户端要想连接 Redis Cluster 的话,就需要开发新功能。所以,如果你的业务应用中大量使用了单实例的客户端,而现在想应用切片集群的话,建议你选择 Codis,这样可以避免修改业务应用中的客户端
  • 从使用 Redis 新命令和新特性来看,Codis server 是基于开源的 Redis 3.2.8 开发的,所以,Codis 并不支持 Redis 后续的开源版本中的新增命令和数据类型。另外,Codis 并没有实现开源 Redis 版本的所有命令,比如 BITOPBLPOPBRPOP,以及和与事务相关的 MUTLIEXEC 等命令。Codis 官网上列出了不被支持的命令列表,你在使用时记得去核查一下。所以,如果你想使用开源 Redis 版本的新特性,Redis Cluster 是一个合适的选择
  • 从数据迁移性能维度来看,Codis 能支持异步迁移,异步迁移对集群处理正常请求的性能影响要比使用同步迁移的小。所以,如果你在应用集群时,数据迁移比较频繁的话,Codis 是个更合适的选择