当前位置: 首页 > news >正文

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分片结构实现了数据的分散存储和读写负载均衡,同时通过哈希槽的管理和一致性哈希算法保障了系统的一致性和可用性。

相关文章:

Redis05-集群方案

目录 Redis集群方案 主从复制 主从复制的基本原理 主从复制的工作流程 乐观复制 主从复制的优势 哨兵机制 哨兵的关键作用 服务状态监控 哨兵选举Master规则 分片集群 分片集群中的数据读写 数据写入 数据读取 一致性哈希和客户端分片 Redis集群方案 微服务时代…...

故障演练的关键要素及重要性

故障演练是一种有计划的、模拟真实生产环境故障的活动。通过故意引入故障、模拟系统组件失效或模拟其他异常条件,团队可以观察并评估系统在这些情况下的反应。这有助于发现潜在的问题、改进应急响应和提高系统整体的可用性。 一、故障演练的关键要素 计划性&#xf…...

11月15日,每日信息差

今天是2023年11月15日,以下是为您准备的12条信息差 第一、去哪儿正式启动鸿蒙原生应用开发 第二、最高支持千亿向量规模,腾讯云向量数据库全面升级,同时和信通院一起联合50多家企业共同发布了国内首个向量数据库标准,推进向量数…...

java-关于alibaba的JSON.parseArray注意事项

String resultStr dataStrJosnObject.get("result").toString();JSONArray resultArray JSON.parseArray(resultStr);resultStr 格式是[{},{},{}] resultArray 的size是3 获取第一个{}字符串,使用resultArray.get(0) 获取第二哥个{}字符串,使…...

软文推广中媒体矩阵的优势在哪儿

咱们日常生活中是不是经常听到一句俗语,不要把鸡蛋放在同一个篮子里,其实在广告界这句话也同样适用,媒介矩阵是指企业在策划广告活动时,有目的、有计划的利用多种媒体进行广告传播,触达目标用户。今天媒介盒子就来和大…...

xss总结

xss注入总结 漏洞描述 XSS(跨站脚本攻击)是一种常见的网络安全漏洞,攻击者利用该漏洞在网页中插入恶意脚本,以获取用户的敏感信息或执行恶意操作。 XSS中文叫做跨站脚本攻击(Cross-site scripting)&…...

【MySQL学习】常见命令

数据库操作 (1)查询所有数据库名字 show databases;(2)常见数据库 create database db_name; //create if exist create database if exists databaseName;(3)删除数据库 drop database db_name;表格操…...

汽车ECU的虚拟化技术初探(二)

目录 1.概述 2.U2A虚拟化方案概述 3.U2A的虚拟化功能概述 4.虚拟化辅助功能的使能 5.留坑 1.概述 在汽车ECU的虚拟化技术初探(一)-CSDN博客里,我们聊到虚拟化技术比较关键的就是vECU的虚拟地址翻译问题,例如Cortex-A77就使用MMU来进行虚实地址的转换…...

vue3 el-menu初始化时选中没有高亮的问题(default-active和index的问题)

首先看官方文档的示例: 需要注意的是: 1、default-active的值是字符串,那么index绑定的值也要是字符串,且数字对应。不能default-avtive绑定的是1,而menu-item的index绑定的是45 2、default-active的值是当前选中me…...

Vue的class、style绑定

Vue中的样式也要回到原始的BOMDOMjs的前端组合去解读。 1、当模板直接引用style中定义的样式时&#xff0c;在HTML模板中按照正常的样式引用处理即可。 模板定义&#xff1a;<template> <div class"sizeclass">100</div> </template><st…...

day22_mysql

今日内容 零、 复习昨日 一、MySQL 一、约束 1.1 约束 是什么? 约束,即限制,就是通过设置约束,可以限制对数据表数据的插入,删除,更新 怎么做? 约束设置的语法,大部分是 create table 表名( 字段 数据类型(长度) 约束, 字段 数据类型(长度) 约束 );1.1 数据类型 其实数据类型…...

【VBA】基于EXCEL生成Insert语句工具

前言 基于Excel生成INSERT语句工具是为了解决在数据库中插入大量数据时手动编写INSERT语句繁琐和耗时的问题而开发的辅助工具。在软件开发和数据库管理等领域&#xff0c;测试数据是非常重要的&#xff0c;它可以用于测试和验证数据库的性能、功能和准确性。 手动编写INSERT语…...

算法与数据结构--前缀和

一维前缀和适用于计算某个一维数列某个数到某个数之间的累加和&#xff08;或者乘积&#xff0c;又或者异或和&#xff09;之类的。 比如计算某个一维度数列从i到j之间元素的和。最开始的想法就是从i遍历到j&#xff0c;将这之间的元素相加。但是当查询次数很多时候&#xff0…...

高频CSS面试题

给大家推荐一个实用面试题库 1、前端面试题库 &#xff08;面试必备&#xff09; 推荐&#xff1a;★★★★★ 地址&#xff1a;web前端面试题库 BFC 块级格式上下文(block format context)是页面一块独立的渲染区域&#xff0c;具有一套独立的渲染规则 内部的…...

electron 内部api capturePage实现webview截图

官方文档 .capturePage([rect]) rect Rectangle (可选) - 要捕获的页面区域。 返回 Promise - 完成后返回一个NativeImage 在 rect内捕获页面的快照。 省略 rect 将捕获整个可见页面。 async function cap(){ let image await webviewRef.value.capturePage() console.log(im…...

sql9(Leetcode197上升的温度)

代码&#xff1a; inner join 至少存在一个 返回行 datediff 日期差 # Write your MySQL query statement below SELECT b.id FROM Weather a INNER JOIN Weather b WHERE DATEDIFF(b.recordDate,a.recordDate)1 AND b.Temperature>a.Temperature...

物联网AI MicroPython学习之语法 umqtt客户端

学物联网&#xff0c;来万物简单IoT物联网&#xff01;&#xff01; umqtt 介绍 模块功能: MQTT客户端功能 - 连线、断线、发布消息、订阅主题、KeepAlive等功能。 MQTT协议采用订阅者/发布者模式&#xff0c;协议中定义了消息服务质量&#xff08;Quality of Service&#x…...

SQLite3 数据库学习(二):SQLite 中的 SQL 语句详解

参考引用 SQLite 权威指南&#xff08;第二版&#xff09;SQLite3 入门 1. SQL 语句操作 SQLite 数据库 1.1 创建数据表格 create table 表名(字段名 数据类型&#xff0c; 字段名 数据类型&#xff0c; 字段名 数据类型&#xff0c; 字段名 数据类型); 命令行语句结束要加分…...

基础课4——客服中心管理者面临的挑战

客服管理者在当今的数字化时代也面临着许多挑战。以下是一些主要的挑战&#xff1a; 同行业竞争加剧&#xff1a;客服行业面临着来自同行业的竞争压力。为了获得竞争优势&#xff0c;企业需要不断提高自身的产品和服务质量&#xff0c;同时还需要不断降低成本、提高效率。然而…...

RFID技术在危险废物管理中的应用解决方案

一、背景介绍 随着我国经济的快速发展&#xff0c;轻纺、化工、制药、电子等行业的危险废物排放量逐年增加。然而&#xff0c;由于危险废弃物处理不当&#xff0c;可能导致大气、水体和土壤污染&#xff0c;对环境和人体健康造成严重威胁&#xff0c;制约了经济和健康的可持续…...

Java 语言特性(面试系列1)

一、面向对象编程 1. 封装&#xff08;Encapsulation&#xff09; 定义&#xff1a;将数据&#xff08;属性&#xff09;和操作数据的方法绑定在一起&#xff0c;通过访问控制符&#xff08;private、protected、public&#xff09;隐藏内部实现细节。示例&#xff1a; public …...

高频面试之3Zookeeper

高频面试之3Zookeeper 文章目录 高频面试之3Zookeeper3.1 常用命令3.2 选举机制3.3 Zookeeper符合法则中哪两个&#xff1f;3.4 Zookeeper脑裂3.5 Zookeeper用来干嘛了 3.1 常用命令 ls、get、create、delete、deleteall3.2 选举机制 半数机制&#xff08;过半机制&#xff0…...

使用van-uploader 的UI组件,结合vue2如何实现图片上传组件的封装

以下是基于 vant-ui&#xff08;适配 Vue2 版本 &#xff09;实现截图中照片上传预览、删除功能&#xff0c;并封装成可复用组件的完整代码&#xff0c;包含样式和逻辑实现&#xff0c;可直接在 Vue2 项目中使用&#xff1a; 1. 封装的图片上传组件 ImageUploader.vue <te…...

现代密码学 | 椭圆曲线密码学—附py代码

Elliptic Curve Cryptography 椭圆曲线密码学&#xff08;ECC&#xff09;是一种基于有限域上椭圆曲线数学特性的公钥加密技术。其核心原理涉及椭圆曲线的代数性质、离散对数问题以及有限域上的运算。 椭圆曲线密码学是多种数字签名算法的基础&#xff0c;例如椭圆曲线数字签…...

关键领域软件测试的突围之路:如何破解安全与效率的平衡难题

在数字化浪潮席卷全球的今天&#xff0c;软件系统已成为国家关键领域的核心战斗力。不同于普通商业软件&#xff0c;这些承载着国家安全使命的软件系统面临着前所未有的质量挑战——如何在确保绝对安全的前提下&#xff0c;实现高效测试与快速迭代&#xff1f;这一命题正考验着…...

中医有效性探讨

文章目录 西医是如何发展到以生物化学为药理基础的现代医学&#xff1f;传统医学奠基期&#xff08;远古 - 17 世纪&#xff09;近代医学转型期&#xff08;17 世纪 - 19 世纪末&#xff09;​现代医学成熟期&#xff08;20世纪至今&#xff09; 中医的源远流长和一脉相承远古至…...

Java求职者面试指南:Spring、Spring Boot、MyBatis框架与计算机基础问题解析

Java求职者面试指南&#xff1a;Spring、Spring Boot、MyBatis框架与计算机基础问题解析 一、第一轮提问&#xff08;基础概念问题&#xff09; 1. 请解释Spring框架的核心容器是什么&#xff1f;它在Spring中起到什么作用&#xff1f; Spring框架的核心容器是IoC容器&#…...

Go 并发编程基础:通道(Channel)的使用

在 Go 中&#xff0c;Channel 是 Goroutine 之间通信的核心机制。它提供了一个线程安全的通信方式&#xff0c;用于在多个 Goroutine 之间传递数据&#xff0c;从而实现高效的并发编程。 本章将介绍 Channel 的基本概念、用法、缓冲、关闭机制以及 select 的使用。 一、Channel…...

前端中slice和splic的区别

1. slice slice 用于从数组中提取一部分元素&#xff0c;返回一个新的数组。 特点&#xff1a; 不修改原数组&#xff1a;slice 不会改变原数组&#xff0c;而是返回一个新的数组。提取数组的部分&#xff1a;slice 会根据指定的开始索引和结束索引提取数组的一部分。不包含…...

6.9-QT模拟计算器

源码: 头文件: widget.h #ifndef WIDGET_H #define WIDGET_H#include <QWidget> #include <QMouseEvent>QT_BEGIN_NAMESPACE namespace Ui { class Widget; } QT_END_NAMESPACEclass Widget : public QWidget {Q_OBJECTpublic:Widget(QWidget *parent nullptr);…...