Codis VS Redis Cluster:我该选择哪一个集群方案?

234 阅读4分钟

Codis 的整体架构和基本流程

Codis 集群中包含了 4 类关键组件。

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

架构图:

image.png

处理流程:

image.png

数据分布

image.png

我们把 Slot 和 codis server 的映射关系称为数据路由表(简称路由表)。我们在 codis dashboard 上分配好路由表后,dashboard 会把路由表发送给 codis proxy,同时,dashboard 也会把路由表保存在 Zookeeper 中。codis-proxy 会把路由表缓存在本地,当它接收到客户端请求后,直接查询本地的路由表,就可以完成正确的请求转发了。

在 Redis Cluster 中,数据路由表是通过每个实例相互间的通信传递的,最后会在每个实例上保存一份。当数据路由信息发生变化时,就需要在所有实例间通过网络消息进行传递。所以,如果实例数量较多的话,就会消耗较多的集群网络资源。

数据迁移

image.png

为了避免数据迁移阻塞源 server,Codis 实现的第二种迁移模式就是异步迁移。异步迁移的关键特点有两个。第一个特点是,当源 server 把数据发送给目的 server 后,就可以处理其他请求操作了,不用等到目的 server 的命令执行完。而目的 server 会在收到数据并反序列化保存到本地后,给源 server 发送一个 ACK 消息,表明迁移完成。此时,源 server 在本地把刚才迁移的数据删除。在这个过程中,迁移的数据会被设置为只读,所以,源 server 上的数据不会被修改,自然也就不会出现“和目的 server 上的数据不一致”的问题了。第二个特点是,对于 bigkey,异步迁移采用了拆分指令的方式进行迁移。具体来说就是,对 bigkey 中每个元素,用一条指令进行迁移,而不是把整个 bigkey 进行序列化后再整体传输。这种化整为零的方式,就避免了 bigkey 迁移时,因为要序列化大量数据而阻塞源 server 的问题。此外,当 bigkey 迁移了一部分数据后,如果 Codis 发生故障,就会导致 bigkey 的一部分元素在源 server,而另一部分元素在目的 server,这就破坏了迁移的原子性。所以,Codis 会在目标 server 上,给 bigkey 的元素设置一个临时过期时间。如果迁移过程中发生故障,那么,目标 server 上的 key 会在过期后被删除,不会影响迁移的原子性。当正常完成迁移后,bigkey 元素的临时过期时间会被删除。

使用redis集群,客户端需要增加和集群功能相关的命令操作的支持。如果原来使用单实例客户端,想要扩容使用集群,就需要使用新客户端,这对于业务应用的兼容性来说,并不是特别友好。

Codis 使用 codis proxy 直接和客户端连接,codis proxy 是和单实例客户端兼容的。而和集群相关的管理工作(例如请求转发、数据迁移等),都由 codis proxy、codis dashboard 这些组件来完成,不需要客户端参与。

切片集群方案选择建议

image.png

综合比较codis和redis cluster:

  1. codis出现的早,工程实践多,比较稳定
  2. codis有proxy兼容单实例客户端,客户端无需改造
  3. redis cluster对redis新特性支持的更好
  4. codis支持异步迁移数据,迁移数据频繁建议用codis

此文章为8月Day28学习笔记,内容来源于极客时间《redis核心技术与实战》