Redis05-集群方案

目录

Redis集群方案

主从复制

主从复制的基本原理

主从复制的工作流程

乐观复制

主从复制的优势

哨兵机制

哨兵的关键作用

服务状态监控

哨兵选举Master规则

分片集群

分片集群中的数据读写

数据写入

数据读取

一致性哈希和客户端分片


Redis集群方案

微服务时代背景下,现实中我们的项目往往需要多台Redis服务器的支持:

  • 结构上:单个Redis容易引发单点故障,一台服务器需要承载所有请求。所以需要多个节点同步复制。

  • 容量上:单个Redis的内存很容易成为存储瓶颈。所以需要进行数据分片。

针对Redis的集群方案,常见的有:主从复制、哨兵模式、分片集群。

主从复制

Redis的主从复制是一种常见的数据复制和高可用性的机制。它通过将一个Redis节点的数据复制到其他节点,实现数据的备份和读写分离。

主从复制的基本原理
  1. 全量复制: 初始阶段,从节点会向主节点发送一次SYNC命令,主节点会将自己的数据库快照发送给从节点。从节点接收到快照后,会清空自己的数据库,然后将接收到的快照数据加载到自己的数据库中,完成全量复制。

    • Replication Id:简称replid,是数据集的标记,id一致则说明是同一数据集。每一个master都有唯一的replid,slave则会继承master节点的replid。

    • offset:偏移量,随着记录在repl_baklog中的数据增多而逐渐增大。slave完成同步时也会记录当前同步的offset。如果slave的offset小于master的offset,说明slave数据落后于master,需要更新。

  2. 增量复制: 一旦从节点完成全量复制,主节点会继续将自己的写操作(写命令)发送给从节点。这样从节点就能保持自己的数据库和主节点保持一致。增量复制通过主节点将执行的写命令传播给从节点来实现。

主从复制的工作流程
  1. 从节点连接到主节点: 从节点通过发送PING命令或PSYNC命令与主节点建立连接。PSYNC命令是增量复制的一部分,它用于在断线重连时,从节点告知主节点自己的复制偏移量。

  2. 主节点创建快照: 一旦从节点连接到主节点,主节点会执行BGSAVE命令创建一个RDB快照。这个快照包含了当前主节点数据库的全部数据。

  3. 从节点加载快照: 主节点创建快照后,会将快照数据传输给从节点。从节点接收到快照后,会清空自己的数据库,然后加载主节点传来的快照数据,完成全量复制。

  4. 增量复制: 从节点完成全量复制后,主节点会将自己的写操作(写命令)发送给从节点。从节点接收到写命令后,会执行相同的写操作,保持与主节点数据的一致性。

  5. 心跳和断线重连: 主节点和从节点会通过心跳机制保持连接。如果从节点与主节点的连接断开,从节点会尝试重新连接,并使用PSYNC命令告知主节点自己的复制偏移量,主节点会根据从节点的复制偏移量发送缺失的写命令,从而实现断线重连时的增量同步。

乐观复制

乐观复制(Optimistic Replication)通常是指一种基于版本控制的复制策略,其核心思想是节点在进行数据复制时,不需要先获取到全局锁,而是通过版本号等机制来进行冲突的检测和解决。在Redis中,乐观复制并非官方的特性,但是可以通过一些手段实现类似的效果。

  1. 版本号: 在Redis中,你可以使用自定义的版本号,通过 INCR 等命令来增加节点的版本号。在写操作时,将写操作和对应的版本号发送给其他节点。

  2. 冲突检测: 在节点接收到写操作时,检查接收到的写操作的版本号是否比自己的版本号大。如果大,执行写操作并更新版本号;如果小,则发生冲突,需要进行冲突解决。

  3. 冲突解决: 冲突解决可以采用一些策略,例如最后一次写操作覆盖之前的写操作,或者保留所有冲突的写操作等。

需要注意的是,这种自定义的乐观复制机制需要谨慎设计,因为在分布式环境中,冲突的发生是不可避免的,需要考虑如何解决冲突、保证数据的一致性等问题。另外,Redis本身提供的主从复制和哨兵机制已经能够满足大部分应用场景,使用官方提供的复制机制通常更为稳妥。

主从复制的优势
  1. 数据备份: 主从复制可以用作数据的备份机制,当主节点发生故障时,从节点可以升级为主节点,确保数据的可用性。

  2. 读写分离: 从节点可以处理读请求,实现读写分离,分担主节点的读负载,提高系统的并发处理能力。

  3. 容灾性: 当主节点发生故障时,可以快速切换到从节点,提高系统的容灾性。

  4. 故障恢复: 当主节点恢复正常工作时,可以将从节点重新配置为主节点的从节点,实现故障恢复。

哨兵机制

Redis提供了哨兵(Sentinel)机制:哨兵通过协调多个哨兵进程的工作来实现主从集群的自动故障恢复。

哨兵的关键作用
  1. 监控: 哨兵负责监控Redis主节点和从节点的健康状态。它通过周期性的检查节点的状态,包括网络连接状态、是否存活等。

  2. 故障检测: 当哨兵发现某个Redis节点不可用时,它会将这一信息广播给其他哨兵和客户端。哨兵根据一定的条件来判断一个节点是否处于不可用状态,例如在规定时间内未响应等。

  3. 故障转移: 在主节点不可用时,哨兵会自动进行故障转移。它会通过选举的方式选择一个从节点升级为新的主节点,保证系统的可用性。

  4. 自动发现: 哨兵可以通过 SENTINEL 命令进行自动发现,不需要手动配置所有哨兵的信息。这使得系统更加灵活,能够适应节点的动态变化。

服务状态监控

Sentinel基于心跳机制监测服务状态,每隔1秒向集群的每个实例发送ping命令:

  • 主观下线:如果某sentinel节点发现某实例未在规定时间响应,则认为该实例主观下线。

  • 客观下线:若超过指定数量(quorum)的sentinel都认为该实例主观下线,则该实例客观下线。quorum值最好超过Sentinel实例数量的一半。

哨兵选举Master规则

Redis哨兵进行主节点选举时,遵循一定的规则和条件,以确保选出的新主节点是可用的。以下是哨兵选举Master的基本规则:

  1. Quorum(仲裁):

    • 选举需要达到Quorum,Quorum的计算方式为 (哨兵总数 / 2) + 1。只有得到足够多的哨兵投票,选举才能生效。

    • Quorum的引入是为了防止因为网络分裂等问题导致多个主节点同时被选举。

  2. 哨兵优先级:

    • 每个哨兵节点都有一个配置的优先级,可以通过 sentinel.conf 文件中的 sentinel myid priority 配置项设置。默认为100。

    • 哨兵在选举时会选择优先级最高的哨兵作为领导者,由领导者发起主节点选举。

  3. 最高优先级的Slave:

    • 如果有多个从节点具有相同的优先级,哨兵将选择复制偏移量(replication offset)最大的从节点作为新的主节点。

    • 复制偏移量是指从节点的复制进度,选择复制偏移量最大的从节点有助于保持数据的一致性。

  4. 选举超时和投票:

    • 当一个哨兵发现主节点不可用后,它会发起一轮选举,设定一个选举超时时间。在这个时间内,哨兵会收集其他哨兵的投票。

    • 哨兵通过相互通信,进行选举投票,包括对自身的投票。哨兵节点可以投票给自己,也可以投票给其他哨兵。

  5. 领导者发起选举:

    • 选举开始时,哨兵中优先级最高的节点成为领导者,由领导者发起主节点选举。

    • 领导者向其他哨兵广播自己的选票,其他哨兵在收到选票后进行投票。

  6. 多轮投票:

    • 选举可能进行多轮,直到某个哨兵得到Quorum的支持为止。在每一轮选举中,哨兵都会尝试发起并参与投票。

  7. 新主节点确认:

    • 当一个哨兵获得Quorum的支持后,它会确认选出的新主节点。其他哨兵节点收到确认后,会更新配置并将新的主节点信息广播给其他节点。

  8. 客户端更新:

    • 一旦新的主节点选出,哨兵将通知客户端更新连接信息,使客户端连接到新的主节点。

通过这些规则,Redis哨兵确保了在主节点发生故障时,能够选出一个优先级高、复制偏移量最大的从节点作为新的主节点,从而确保系统的高可用性。

分片集群

主从和哨兵可以解决高可用、高并发读的问题。但是依然有两个问题没有解决:

  • 海量数据存储问题

  • 高并发写的问题

使用分片集群可以解决上述问题,分片集群特征:

  • 集群中有多个master,每个master保存不同数据

  • 每个master都可以有多个slave节点

  • master之间通过ping监测彼此健康状态

  • 客户端请求可以访问集群任意节点,最终都会被转发到正确节点

分片集群中的数据读写

Redis分片集群使用了哈希槽(Hash Slot),Redis分片集群将整个数据集划分为16384个哈希槽,每个槽都有一个唯一的编号。这些哈希槽用于存储数据,同时也用于管理数据的分片。数据的键通过哈希算法映射到某个哈希槽上,决定了数据应该由哪个节点负责存储。

数据写入
  1. 计算哈希槽:

    • 当客户端向Redis集群发送写入请求时,Redis首先计算键对应的哈希槽。通过哈希算法,确定键属于哪个哈希槽。

  2. 选择节点:

    • 哈希槽确定后,根据哈希槽和集群中的节点分布,选择负责处理该哈希槽的节点。这个节点被称为槽的持有者。

  3. 发送写请求:

    • 客户端将写请求发送给被选择的节点。如果该节点是主节点,它将负责处理写请求;如果是从节点,写请求将被转发给主节点。

  4. 写入数据:

    • 主节点接收到写入请求后,将数据写入自己的数据存储。然后,主节点会将写入操作通过集群总线广播给其他从节点,以保持数据的一致性。

数据读取
  1. 计算哈希槽:

    • 当客户端向Redis集群发送读取请求时,同样需要计算键对应的哈希槽,确定数据所在的槽。

  2. 选择节点:

    • 根据哈希槽和节点分布,选择负责处理该哈希槽的节点。这个节点可能是主节点,也可能是从节点。

  3. 发送读请求:

    • 客户端将读请求发送给被选择的节点。如果是主节点,它将直接处理读请求;如果是从节点,读请求可能会被转发到主节点。

  4. 读取数据:

    • 节点处理读请求,如果是主节点,直接从自己的数据存储中读取数据并返回给客户端;如果是从节点,它可能会从主节点获取最新的数据并返回给客户端。

一致性哈希和客户端分片
  • 为了在节点变动时保持哈希槽的一致性,Redis使用一致性哈希算法。这确保了在节点加入或退出时,只有少量的槽需要迁移,而不是整个数据集。

  • 客户端也需要进行分片,以确保请求被正确发送到负责处理对应数据分片的节点。通常,客户端使用一致性哈希算法或其他分片策略来选择正确的节点。

通过上述过程,Redis分片结构实现了数据的分散存储和读写负载均衡,同时通过哈希槽的管理和一致性哈希算法保障了系统的一致性和可用性。

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

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

相关文章

Python编程爬虫代码

这是一个基本的爬虫程序的示例,按照你的需求进行了修改: typescript import * as request from request; import * as cheerio from cheerio; const proxyHost ; const proxyPort ; // 创建一个request实例,使用 const requestWithProxy…

基于单片机智能浇花系统仿真设计

**单片机设计介绍, 基于单片机智能浇花系统仿真设计 文章目录 一 概要二、功能设计设计思路 三、 软件设计原理图 五、 程序六、 文章目录 一 概要 基于单片机的智能浇花系统可以实现自动化浇水、测土湿度和温度等功能,以下是一个基本的仿真设计步骤&am…

详细推导MOSFET的跨导、小信号模型、输出阻抗、本征增益

目录 前言 什么是跨导 什么是小信号模型 什么是输入阻抗和输出阻抗 什么是MOS管的输出阻抗 什么是MOS管的本征增益 共源极放大电路的输入和输出阻抗 一些其它MOS拓扑电路的增益 负载为恒流源 负载为二极管 前言 相信很多人在学习集成电路领域的时候 都对MOS管的…

【机器学习基础】机器学习入门(1)

🚀个人主页:为梦而生~ 关注我一起学习吧! 💡专栏:机器学习 欢迎订阅!后面的内容会越来越有意思~ 💡专栏介绍: 本专栏的第一篇文章,当然要介绍一下了~来说一下这个专栏的开…

asp.net core mvc之 RAZOR共享指令和标签助手 TagHelpers

一、RAZOR共享指令 RAZOR共享指令:在视图中导入命名空间,执行依赖注入。 RAZOR共享指令是写在 Views目录下的 _ViewImports.cshtml 文件 支持指令如下: addTagHelper 增加标签助手 removeTagHelper 移除标签助手 tagHelperPrefix 标签助手…

javaSE学习笔记(八)-多线程

目录 九、多线程 1.概述 线程 多线程并行和并发的区别 Java程序运行原理 多线程为什么快 如何设置线程数比较合理 CPU密集型程序 I/O密集型程序 注意 线程的五种状态 新建状态(new) 就绪(runnable) 运行状态&#x…

ubutun上编译出现undefined reference to symbol ‘dladdr@@GLIBC_2.2.5‘的错误

作者:朱金灿 来源:clever101的专栏 为什么大多数人学不会人工智能编程?>>> ubutun上编译一段C程序,出现错误: /usr/bin/ld: /tmp/ccghh3FJ.o: undefined reference to symbol ‘dladdrGLIBC_2.2.5’ //lib/…

记录一个错误

通过Resource注解,将IStateHandler接口的实现类 StateHandlerImpl注入进来 Resource private IStateHandler stateHandler;Resource注解默认按照名称进行装配,这里抛出异常是因为IStateHandler和StateHandlerImpl都被 Spring 容器管理,在进行…

css渐变背景,linear-gradient()线性渐变和radial-gradient()径向渐变

嗨,大家好,我是爱搞知识的咸虾米。 许多APP、小程序、网站等都喜欢采用渐变色背景,这样做不但可以增加设计感,而且能提升品牌辨识度。 所以,今天使用css的线性渐变和径向渐变,给大家将这几种不同类型的渐变…

【mybatisPlus简化开发过程】

mybatisPlus简化开发过程 1.入门案例1.1 SpringBoot整合Mybatis开发过程(复习) 2.Mp简介3. 增删改查4. 分页插件5. 多条件查询(lambda版本)6 条件查询的null值处理7. Lambda查询投影8.条件查询8.1 范围查询(>、、between)8.2 模糊查询 (like)8.3 空判定(null)8.4 包含性判定…

重复性工作自动化解决方案——影刀

以前,影刀是一个邂逅的初见小工具,新奇在里头,踌躇在外头; 现在,影刀是一个稳定的职场贾维斯,高效在里头,悠闲在外头; 以后,影刀是一个潜力的知己老司机,有序…

【网络奇缘】我和英特网再续前缘

🌈个人主页: Aileen_0v0🔥系列专栏: 一见倾心,再见倾城 --- 计算机网络~💫个人格言:"没有罗马,那就自己创造罗马~" 目录 计算机网络的概念 计算机网络的功能 ⭐1.数据通信 ⭐2.资源共享 ⭐3.分布式处理 ⭐4.提高可靠性 ⭐…

如何使用`open-uri`模块

首先,我们需要使用open-uri模块来打开网页,并使用Nokogiri模块来解析网页内容。然后,我们可以使用Nokogiri的css方法来选择我们想要的元素,例如标题,作者,内容等。最后,我们可以使用open-uri模块…

算法的入门基础了解

目录 算法的特征 如何设计算法? 伪代码 “算法”一词最早出现在《周髀算经》这本书中,对应的英文单词是“algorism”(由 9 世纪的波斯数学家阿尔霍瓦里兹米提出),代指阿拉伯数字的运算规则。随着计算机的快速发展&a…

小白看CLIP代码解析

CLIP代码解析 CLIP演示代码(以cifar100举例)补充11. 为什么选用100*image_feature?2. 为什么使用L2规范点积,而不直接使用点积? cifar100的所有类别model.encode_image >> VisionTransformer补充21. 为什么加入c…

GoldWave v6.78 绿色免费便携版功能介绍及使用说明

GoldWave v6.78 绿色免费便携版是一款集声音编辑、播放、录制与转换为一体的音频编辑工具,还可以对音频内容进行转换格式等处理。该软件支持许多格式的音频文件,包括WAV, OGG, VOC, IFF, AIF, AFC, AU, SND, MP3,MAT, DWD, SMP, VOX, SDS, AVI, MOV等音频…

程序运行前后内存分区存储

程序运行前是源码 在程序运行后,生成了exe可执行程序 分为代码区和全局区 代码区: 存放CPU执行的机器指令代码区是共享的,共享的目的是对于频繁被执行的程序,只需要在内存中有一份代码就可以了代码区是只读的,其只读…

淘宝京东优惠券信息API接口系列

获取淘宝优惠券信息接口需要使用淘宝开放平台提供的API接口。以下是获取优惠券信息的步骤: 进入淘宝开放平台,注册并登录账号。在开放平台页面中,找到“优惠券”或“营销工具”等相关的API接口,根据需要进行选择。根据接口文档&a…

C语言——函数

导读 : 这篇文章主要讲解一下C语言函数的一些基本知识。 前言:函数的概念 C语言中的函数又常常被称为子程序,是用来完成某项特定的工作的一段代码。就像我们生活中的模块化建造技术,类比模块化建房子的过程:整个程序…

快速掌握队列的基础知识

目录 队列的特点基于链表实现队列用栈实现队列用队列实现栈 队列是一种线性数据结构,它只允许在一边进行插入操作(队尾),另一边进行删除操作(队头)。插入操作称为入队,删除操作称为出队。队列遵…