Redis核心技术与实战【学习笔记】 - 24.Redis 数据分片方案选择:Codis 和 Redis Cluster

简述

Redis 的切片集群使用多个实例保存数据,能很好的应对大数据量的场景。在《4.Redis 切片集群》中,介绍了 Redis 官方提供的切片集群方法 Redis Cluster。本章,再来学习下,在 Redis Cluster 方案正式发布前,业界广泛使用的 Codis


1.Codis 的整体架构和基本流程

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

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

在这里插入图片描述
先了解下 Codis 是如何处理请求的。

  1. 首先,为了让集群能接收并处理请求,我们要先使用 codis dashboard 设置 codis server 和 codis proxy 的访问地址,完成设置后,codis server 和 codis proxy 才开始接收连接。
  2. 然后,当客户端要读写数据时,客户端直接和 codis proxy 建立连接。codis proxy 支持 Redis 的 RESP 协议,所以客户端访问 codis proxy 时和访问原生Redis 实例没有什么区别,这样一来,原本连接单实例的客户端就可以轻松地和 Codis 集群建立起连接了。
  3. 最后,codis proxy 接收到请求,就会查询数据和 codis server 的映射关系,把请求转发给相应的 codis server 进行处理。当 codis server 处理完请求后,会把结果返回给 codis proxy ,codis proxy 再把数据返回给客户端。
    在这里插入图片描述

2.Codis 的关键技术原理

一旦使用了切片集群,就需要先了解,数据是怎么在多个实例上分布的

数据如何在集群里分布

在 Codis 集群中,一个数据应该保持在哪个 codis server 上,是通过逻辑槽(Slot)映射来完成的。具体来说,分为两步:

  • 第一步,Codis 集群一共有 1024 个 Solt,编号一次是 0 到 1023。我们可以把这些 Solt 手动分配给 codis server,每个 codis server 包含一部分 Solt。当日,我们也可以让 codis dashboard 进行自动分配,例如,codis dashboard 把 1024 个 Solt 在所有 Server 上均分。
  • 第二步,当客户端需要读写数据时,会使用 CRC32 算法计算数据 key 的哈希值,并把这个哈希值对 1024 取模。而取模后的值,则对应 Solt 的编号。此时,根据第一步分配的 Solt 和 Server 对应关系,我们就可以知道数据保存在哪个 Server 上了。

下图显示的就是数据、Solt 和 codis server 的映射保存关系。其中,Solt0 和 1 被分配到了 server1,Solt2 被分配到了 server2,Solt1022 和 1023 被分配到了 server8。当客户端访问 key1 和 key2 时,这两个数据的 CRC32 值对 1024 取模后,分别是 1 和 1022.因此,它们会被保存在 Solt1 和 Solt1022 上,而 Solt1 和 Solt1022 已经被分配到了 codis server1 和 8 上了。这样一来,key1 和 key2 的保存位置就很清楚了。
在这里插入图片描述
数据 key 和 Solt 的映射关系是客户端在读写数据前直接通过 CRC32 计算得到的,而 Solt 和 codis server 的映射关系是通过分配完成的,所以就需要用一个存储系统保存下来,否则,如果集群有故障了,映射关系就丢失了。

我们把 Solt 和 codis server 的映射关系称为数据路由表(简称路由表)。我们在 codis dashboard 上分配好路由表后,dashboard 会把路由表发送给 codis proxy,通时 dashboard 也会把路由表保存在 Zookeeper 中。codis proxy 会把路由表缓存在本地,当它接收到客户端请求后,直接查询本地的路由表,就可以完成正确的额请求转发了。
在这里插入图片描述
在数据分布的实现方法上,Codis 和 Redis Cluster 很相似,都采用了 key 映射到 Solt、Solt 再分配到实例上的机制。但是它们有明细的区别:

  • Codis 中的路由表是通过 codis dashboard 分配和修改的,并被保存在 Zookeeper 集群中。一旦数据位置发生变化(数据有增减),路由表被修改了,codis dashboard 会把修改后的路由表发送给 codis proxy,codis proxy 就可以根据最新的路由信息转发请求了。
  • 在 Redis Cluster 中,数据路由表是通过每个实例相互间的通信传递的,最后会在每个实例上保存一份。当数据路由信息发生变化时,就需要在所有实例间通过网络消息进行传递。所以,如果实例数量较多的话,就会消耗较多的机器网络资源。

集群扩容和数据迁移如何进行

Codis 集群包括增加 codis server增加 codis proxy

增加 codis server

我们先来看下增加 codis server,这个过程主要涉及到两步操作:

  1. 启动新的codis server,将它加入集群。
  2. 把部分数据迁移到新的 server。

需要注意的是,这里的数据迁移是一个重要的机制,接下来我来重点介绍下。

Codis 集群按照 Slot 的粒度进行数据迁移,我们来看下迁移的基本流程。

  1. 在源 server 上,Codis 要迁移的 Solt 中随机选择一个数据,发送给 目的 server。
  2. 目的 server 确认收到数据后,会给源 server 返回确认消息。这时,源 server 会在本地将刚才迁移的数据删除。
  3. 第一步和第二步就是单个数据的迁移过程。Codis 会不断重复这个迁移过程,直到要迁移的 Solt 中的数据全部迁移完成。
    在这里插入图片描述
    上面的介绍的单个数据的迁移过程,Codis 实现了两种迁移模式,分别是同步迁移和异步迁移。

同步迁移是指,在数据从源 server 发送给目的 server 的过程中,源 server 是阻塞的,无法处理新的请求操作。这种模式很容易实现,但是迁移过程中会涉及多个操作(包括数据在源 server 的序列化、网络传输、在目的 server 反序列化,以及在源 server 删除),如果迁移的数据是一个 bigkey,源 server 就会阻塞较长时间,无法及时处理用户请求。

为避免数据迁移阻塞源 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 元素的临时过期时间会被删除。

假设我们有一个 1 万个元素的List 类型数据,当使用异步迁移时,源 server 就会给目的 server 传输 1 万条 RPUSH 命令,每条命令对应了一个 List 中的元素的插入。在目的 server 上,这一万条命令再次被依次执行,就可以完成数据迁移。

这里,有个地方需要注意下,为了提升迁移的效率,Codis 在异步迁移 Solt 时,允许每次迁移多个 key。你可以通过异步迁移命令 SLOTSMGRTTAGSLOT-ASYNC 的参数 numkeys 设置每次迁移的 key 数量

增加 codis proxy

上面学习的是 codis server 的扩容和数据迁移机制,现在学习下增加 codis proxy 机制。

因为在 Codis 集群中,客户端是和 codis proxy 直接连接的,所以当客户端增加时,一个 codis proxy 无法支撑大量的请求操作,此时,我们就需要增加 proxy。

增加 codis proxy 比较容易,我们直接启动 proxy,在通过 codis dashboard 把 proxy 加入集群就行。

此时,codis proxy 的访问连接信息都会被保存在 Zookeeper。所以,当新增了 proxy 后,Zookeeper 上会有最新的访问列表,客户端也就可以从 Zookeeper 上读取 proxy 访问列表,把请求发送给新增的 proxy。这样一来,客户端的访问压力就可以在多个 proxy 上分担处理了。
在这里插入图片描述
好了,通过上面的学习,我们了解了 Codis 集群中的数据分布、集群扩容和数据迁移的方法,这都是切片集群中的关键机制。

集群客户端需要重新开发吗?

使用 Redis 单实例时,客户端只要符合 RESP 协议,就可以直接和实例进行交互和读写数据。但是,在使用切片集群时,有些功能和单实例是不一样的,比如集群中的数据迁移操作,在单实例上是没有的,而在数据迁移过程中,数据访问请求可能要被重定向(例如 Redis Cluster 中的 MOVE 命令)。

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

Codis 集群在设计时,就充分考虑了对现有单实例客户端的兼容性。

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

这样一来业务使用 Codis 集群时,就不用修改客户端了,可以复用和单实例连接的客户端,技能保证利用集群读写大容量数据,又能避免修改客户端增加复杂的操作逻辑,保证了业务代码的稳定性和兼容性。

怎么保证集群可靠性?

集群可靠性是一个核心的要求。对于一个分布式系统来说,它的可靠性和系统中的组件个数有关:组件越多,潜在的风险点也就越多。和 Redis Cluster 只包含 Redis 实例不一样,Codis 集群包含的组件有 4 类,这么多组件会降低 Codis 集群的可靠性吗?

codis server 可靠性

codis server 其实就是 Redis 实例,只不过增加了和集群操作的相关命令。Redis 的主从复制机制和哨兵机制在 Codis 上都是可以使用的,所以,Codis 就使用主从集群来保证 Codis Server 的可靠性。简单来说,Codis 给每个 Server 配置从库,并使用哨兵机制进行监控,当发生故障时,主从库就可以进行切换,从而保证了可靠性。

在这种情况下,每个 Server 就称为了一个 Server Group,每个 group 中是一主多从的 server。数据分布使用的 Solt ,也是按照 group 粒度进行分配的。同时 codis proxy 在转发请求时,也是按照数据所在的 Solt 和 group 的对应关系,把写请求发送到相应的 group 的主库,读请求发到 group 的主库或从库上。
在这里插入图片描述
因为 codis proxy 和 Zookeeper 这两个组件是搭配在一起使用的,所以接下来,我们看下这两个组件的可靠性。

在 Codis 集群设计时,proxy 上的信息源头都是来自 Zookeeper (如路由表)。而 Zookeeper 集群使用多个实例来保持数据,只要有超过半数的 Zookeeper 实例可以正常工作,Zookeeper 集群就可以提供服务,也可以保证这些数据的可靠性。

所以,codis proxy 使用 Zookeeper 集群保存路由表信息,可以充分利用 Zookeeper 的好可靠性来确保 codis proxy 的可靠性,不用再做额外的工作了。当 codis proxy 发生故障后,直接重启 codis proxy 就行。重启后的 codis proxy 的可靠性,可以通过 codis dashboard 从 Zookeeper 集群上获取路由表,然后,就可以接收客户端请求进行转发了。这样的设计,也降低了 Codis 集群本身的开发复杂度。

对于 codis dashboard 和 codis fe 来说,它们主要提供配置管理和管理员手工操作,负载压力不大,所以它们的可靠性可以不用额外进行保证了。

切片集群方案选择建议

到这里,Codis 和 Redis Cluster 这两种切片方案我们就学完了,我们把它们的区别总结在了一张表里面。

对比维度CodisRedis Cluster
数据路由信息中心化保存在 Zookeeper,proxy 在本地缓存每个实例都保存一份
集群扩容增加 codis server 和 codis proxy增加 Redis 实例
数据迁移支持同步异步迁移支持同步迁移
客户端兼容性兼容单实例客户端需要开发支持Cluster功能的客户端
可靠性codis server 主从集群机制保证可靠性
codis proxy 无状态设计,故障后重启就行
Zookeeper 可靠性高,只要有半数以上结点存在就能继续服务
实例使用主从集群保证可靠性

在实际应用时,对应这两种方案,该如何选择?有 4 条建议:

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/373441.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

CodeMeter强化了ETM WinCC 开放架构平台的许可与安全保护

在面对日益复杂的网络安全威胁时,ETM professional control采取了前瞻性的措施,选择了业界领先的威步CodeMeter技术,以保护其标志性的WinCC开放架构平台。这一选择不仅体现了ETM对安全的高度重视,也标志着其在保障关键基础设施运营…

Jmeter 01 -概述线程组

1、Jmeter:概述 1.1 是什么? Jmeter是Apache公司使用Java 开发的一款测试工具 1.2 为什么? 高效、功能强大 模拟一些高并发或多次循环等特殊场景 1.3 怎么用? 下载安装 1、下载jmeter,解压缩2、安装Java环境(jmet…

基于OpenCV灰度图像转GCode的螺旋扫描实现

基于OpenCV灰度图像转GCode的螺旋扫描实现 引言激光雕刻简介OpenCV简介实现步骤 1.导入必要的库2. 读取灰度图像3. 图像预处理4. 生成GCode5. 保存生成的GCode6. 灰度图像螺旋扫描代码示例 总结 系列文章 ⭐深入理解G0和G1指令:C中的实现与激光雕刻应用⭐基于二值…

5-3、S曲线生成器【51单片机+L298N步进电机系列教程】

↑↑↑点击上方【目录】,查看本系列全部文章 摘要:本节介绍步进电机S曲线生成器的计算以及使用 一.计算原理 根据上一节内容,已经计算了一条任意S曲线的函数。在步进电机S曲线加减速的控制中,需要的S曲线如图1所示,横…

React 实现表单组件

表单是html的基础元素,接下来我会用React实现一个表单组件。支持包括输入状态管理,表单验证,错误信息展示,表单提交,动态表单元素等功能。 数据状态 表单元素的输入状态管理,可以基于react state 实现。 …

09_树莓派_树莓派外设板_GPIO_按键的中断与消抖

目录 1.树莓派外设集成板总体介绍 2.第一部分 按键矩阵 GPIO_按键与中断 3.实现效果 1.树莓派外设集成板总体介绍 1)前言:这是一块为了验证树莓派【兼容树莓派多个型号】的40pins的外设接口的外接板,告别复杂的面包板外设搭建。【欢迎各位…

【Iceberg学习四】Evolution和Maintenance在Iceberg的实现

Evolution Iceberg 支持就底表演化。您可以像 SQL 一样演化表结构——即使是嵌套结构——或者当数据量变化时改变分区布局。Iceberg 不需要像重写表数据或迁移到新表这样耗费资源的操作。 例如,Hive 表的分区布局无法更改,因此从每日分区布局变更到每小…

Node.js+Express+Mysql服务添加环境变量

1、使用dotenv插件 1)安装插件:npm install dotenv-cli --save-dev 2)在项目根目录下添加对应的 .env 配置文件; // .env配置文件内容 MODEdevelopment, BASE_URLhttp://127.0.0.1:80813) 在启动命令中设置对应的加载文件&#…

RabbitMQ-1.介绍与安装

介绍与安装 1.RabbitMQ1.0.技术选型1.1.安装1.2.收发消息1.2.1.交换机1.2.2.队列1.2.3.绑定关系1.2.4.发送消息 1.2.数据隔离1.2.1.用户管理1.2.3.virtual host 1.RabbitMQ 1.0.技术选型 消息Broker,目前常见的实现方案就是消息队列(MessageQueue&…

新零售的升维体验,摸索华为云GaussDB如何实现数据赋能

新零售商业模式 商业模式通常是由客户价值、企业资源和能力、盈利方式三个方面构成。其最主要的用途是为实现客户价值最大化。 商业模式通过把能使企业运行的内外各要素整合起来,从而形成一个完整的、高效率的、具有独特核心竞争力的运行系统,并通过最…

springboot与Elasticsearch版本兼容对比

首先 大家在下载 Elasticsearch 时 最好先弄清楚版本 因为 如果 Spring Boot 版本 不兼容 Elasticsearch 那就是到头一场空了 Elasticsearch 版本 6.x 可以兼容 Spring Boot 2.x Elasticsearch 版本 7.x 可以兼容 Spring Boot 2.x 3.x 4x Elasticsearch 版本 7.x 以及 8.x 可以…

Golang-Map有序输出——使用orderedmap库实现

前言 工作中遇到一个问题:需要导出一个MySQL表格,表格内容由sql查询得来。但现在发现,所导出的表格中,各列的顺序不确定。多次导出, 每一次的序列顺序也是不定的。 因此确定是后端,Map使用相关导致的问题。…

分布式文件存储系统minio

参考Linux搭建免费开源对象存储 wget https://dl.minio.io/server/minio/release/linux-amd64/minio yum install -y wget yum install -y wget wget https://dl.minio.io/server/minio/release/linux-amd64/minio chmod x minio sudo mv minio /usr/local/bin/ minio --vers…

黑马头条 Kafka

我是南城余!阿里云开发者平台专家博士证书获得者! 欢迎关注我的博客!一同成长! 一名从事运维开发的worker,记录分享学习。 专注于AI,运维开发,windows Linux 系统领域的分享! 知…

玩家笔记:幻兽帕鲁搭建服务器开服教程

玩转幻兽帕鲁服务器,阿里云推出新手0基础一键部署幻兽帕鲁服务器教程,傻瓜式一键部署,3分钟即可成功创建一台Palworld专属服务器,成本仅需26元,阿里云服务器网aliyunfuwuqi.com分享2024年新版基于阿里云搭建幻兽帕鲁服…

1.0 Zookeeper 分布式配置服务教程

ZooKeeper 是 Apache 软件基金会的一个软件项目,它为大型分布式计算提供开源的分布式配置服务、同步服务和命名注册。 ZooKeeper 的架构通过冗余服务实现高可用性。 Zookeeper 的设计目标是将那些复杂且容易出错的分布式一致性服务封装起来,构成一个高…

实践:微服务版本升级步骤以及maven仓库相关概念

进行微服务开发的时候&#xff0c;上层服务依赖于下层的服务的api&#xff0c;比如适配属于上层服务&#xff0c;用户属于下层服务。 例子: 上层服务 <!--订单管理微服务api依赖--> <dependency><groupId>com.jn.server</groupId><artifactId>…

docker部署docker运维工具

简介 主要功能:管理容器,管理镜像,管理容器网络 安装 拉取镜像 docker pull joinsunsoft/docker.ui:1.0.1 启动容器 docker run -d --name docker.ui --restart always -v /var/run/docker.sock:/var/run/docker.sock -p 10039:8999 joinsunsoft/docker.ui:1.0.1 使用 打…

【ArcGIS微课1000例】0101:删除冗余节点或折点

文章目录 一、实验描述二、实验数据三、实验过程1. 手动删除2. 简化线工具四、注意事项一、实验描述 矢量数据获取通常来源于手动或者ArcScan自动采集,其基本存储方式就是记录每个要素的点坐标,如点要素就是一个坐标、线要素由多个点要素连接形成。当某段线要素被过多的节点…

多模态对比语言图像预训练CLIP:打破语言与视觉的界限,具备零样本能力

多模态对比语言图像预训练CLIP:打破语言与视觉的界限,具备零样本能力。 一种基于多模态(图像、文本)对比训练的神经网络。它可以在给定图像的情况下,使用自然语言来预测最相关的文本片段,而无需为特定任务进行优化。CLIP的设计类似于GPT-2和GPT-3,具备出色的零射击能力…
最新文章