Redis集群原理解析

一、单机Redis存在的问题

问题1:数据丢失问 解决方案:利用RDB和AOF实现数据的持久化
问题2:并发能力弱 解决方案:搭建主从集群,实现主从分离
问题3:存储空间小 解决方案:搭建分片集群,利用槽机制实现动态扩容
问题4:故障恢复 解决方案:利用Redis哨兵机制,实现健康检测和自动恢复

二、主从集群解析

2.1 定义

将一台Redis服务器的数据,复制到其他的Redis服务器。前者为主节点,后者为从节点

2.2 特点

  • 数据的复制是单向的,只能从主节点到从节点。Master以为主,Slave以为主;
  • 默认情况下,每台Redis都是主节点;
  • 一个主节点可以有多个从节点(或者没有从节点),一个从节点只能由一个主节点;
  • Redis主从复制支持主从复制从从复制。后者是Redis后续版本新增功能的。

二八定律:80%的情况下是在进行读操作,20%是在进行写操作

2.3 主从复制的作用

1. 数据冗余:主从复制实现了数据的"热备份",是持久化之外的一种数据冗余方式;
2. 故障恢复:当主节点出现问题时,可由从节点提供服务,实现快速的故障恢复
3. 负载均衡:在主从复制的基础上,配合"读写分离",由主节点提供写功能,从节点提供读功能分担服务器的负载。尤其是在"写少读多"的场景,通过多个从节点分担读负载,可以大大提高Redis服务器的并发量。
4. 高可用(集群)基石:主从复制还是"哨兵""集群"能够实施的基础。

2.4 数据同步机制

  1. Slave启动成功连接到master后会发送一个Sync同步命令,包括ReplictId和OffSet信息;
  2. Master接到命令,执行bgsave命令启动后台的存盘进程,同时收集所有收到的用于修改数据集命令,在后台进程执行完毕后,master将传送整个数据文件到slave,并完成一次完全同步,同时主服务器不会拒绝客户端的读写,将客户端的写命令写入到缓冲区中;【全量同步
  3. Master发送完快照数据后,会将缓冲区中的命令发送给slave服务器,slave服务器开始执行slave命令;
  4. 接下来,每当主服务器收到一条写命令后,就会将写命令同步给从服务器,保证主从服务器数据的一致。【增量同步】。
    其中ReplictId和Offset用于增量同步时,判断Master和Slave两者之间的数据版本以及差异等问题。

全量复制:slave服务在接收到数据库文件数据后,将其存盘并加载到内存中;
增量复制:Master继续将"新的"所有收集到的修改命令一次传给slave,完成同步
注意】:只要重新连接到Master,一次完全同步(全量复制)将会被自动执行。

2.5 两种配置模式(配置主机和从机)

配置文件配置:主机断开连接,从机依旧连接到主机,但是没有写操作。一旦主机回来了,从机依然接收主机写的信息。
命令行配置:如果从机重启了,就会变成主机。

三、哨兵(Sentinel)集群模式

解决的问题:一旦主机宕机后,能主动从从节点中选举出主机。
一对多(一个哨兵监控多个Redis实例):哨兵本质是一个独立进程,可独自运行。哨兵通过发送命令,等待Redis服务器响应,从而监控运行的多个Redis实例。

3.1 主要流程

  1. 哨兵发送命令,让Redis服务器返回监控其运行状态,包括Master server和Slave server;
  2. 当哨兵监测到master宕机后,会自动将slave切换到master,通过发布订阅模式通知其他的从机修改配置文件,切换主机。

存在的问题:单个哨兵如果出现问题,那么将无法监控Redis运行状态,就无法在主机出现故障时,及时的切换
解决方法:多对多模式,即多个sentinel哨兵监控多个Redis实例。

3.2 哨兵功能

1. 监控(monitor):哨兵会不断的检查主节点和从节点是否运作正常
2. 自动故障转移(Automatic failover):"主节点"不能正常工作时,哨兵会开始"自动故障转移操作",它会将失效主节点的其中一个"从节点升级为新的主节点",并让其他从节点改为复制新的主节点;
3. 配置提供者(Configuration provider):客户端在初始化时,通过连接哨兵来获得当前Redis服务的主节点地址
4. 通知:哨兵可以将故障转移的结果发送给客户端

其中,每个哨兵监控所有的主机和从机,哨兵之间也会相互监控。

3.3 整体运行机制

3.3.1 判断Master主节点故障

主观下线:当主服务器宕机后,假设哨兵1先检测到这个结果,系统并不会马上进failover(重新选举)过程,仅仅是哨兵1主观地认为主服务不可用,这个现象为主观下线
客观下线:当后面的哨兵也监测到主服务器不可用且数量达到一定值时,那么哨兵之间就进行一次投票,投票的结果由一个哨兵发起,进行failover操作,切换成功后,就会发布订阅模式让各个哨兵监控的从服务器切换主机,这个过程称为客观下线

3.3.2 选举新的Master节点

出现故障后,就需要选取新的Master节点。选举依据为:

排除原则:
1. 排除已经宕机的slaves;
2. Sentinel leader会向所有的slaves发送命令,响应慢(回复ping命令时间大于五秒钟)的排除;
3. 与原Master通信慢(与失效服务器连接断开的时长超过down-after选项指定的时长十倍)的排除;优先原则:
5. 判断slave节点的save-priority值, 越小优先级越高 -> 选择优先级高的slave节点;
6. 若优先级相同,选择offset大的节点, 越大数据复制的最完整 -> 选择offset大的slave节点;
7. 若offset相同,则选择runid最小的(启动最早的节点) -> 选择runid最小的slave节点

3.3.3 实现故障转移

新的Master节点选举完成后,需要更新每个节点的主从配置信息。包括故障的Master节点和Slave节点。所谓的更新,即故障转移机制,整理流程为:

1. 首先, sentinel给备选的slave节点发送salveof no one命令,使该节点成为Master节点;
2. 其次, sentinel给其他的slave节点发送salve of [master节点的ip和port],让这些slave成为新master的从节点,开始新的master同步数据;
3. 最后,sentinel将故障节点标记为slave,故障节点恢复后会自动成为新的master的slave节点。

四、分片集群(多个主节点)解析

4.1 背景

哨兵集群虽然可以解决高可用和高并发读的问题。但仍然存在两个问题:

  1. 大数据量的存储问题
  2. 高并发写的问题

因此,使用分片集群可以解决上述问题。

4.2 特点

  1. 数据分布式存储。每个Master存储数据部分数据;
  2. 健康状态自监测。master之间每隔一段时间会进行通信,若某一个master发生故障,可进行故障转移,取代了哨兵机制;
  3. 读写分离。单master和多slave之间也满足了读写分离。

4.3 集群数据分区方案

4.3.1 哈希值 % 节点数

过程:对key进行hash,利用hash值对节点数量取余,映射到对应节点上。
缺点:一旦其中某个master宕机,每个key对应的"映射关系"需要重新计算,短时间造成数据查询错误,导致数据库的压力增大,会影响所有数据,一般采用翻倍扩容方式

4.3.2 一致性哈希算法(自动缓存转移) + 虚拟节点(自动负载均衡)

原理:将多个master节点均匀的分布在一个圆环上,对key进行hash,判断hash落在哪个点上,然后顺时针旋转,去最近的master节点去查询。这样就算某一个master宕机,也只有1/3的数据失效。当增加或者删除节点时,部分节点信息会迁移到附近节点上。
缺点:当节点数量较少时,增加或删除节点,对单个节点的影响可能很大,造成数据的严重不平衡【影响单个节点的所有数据】
解决方案: 使用虚拟节点。在相邻节点之间增加非相邻的虚拟节点。例在node1和node2之间增加node3、node4等。当某个master宕机后,失效的数据远小于1/3.
缺点:一致性hash在扩容时还是会导致一个节点的部分时间不可用

4.3.3 虚拟槽分区

虚拟槽中的槽就是大量虚拟节点的抽象化,将原来的虚拟节点变成一个槽,Redis内置是有16383个槽。每个Redis节点存储一部分虚拟槽。将redis集群分成16384个槽,每个master1节点负责一些槽。

【特点:】key不是与节点绑定,而是与虚拟槽点绑定。redis会根据【key的有效部分】计算插槽值,主要分为两种情况:
- key中包含"{}","{}"中至少包含一个字符,使用"{num}"使用num来计算插槽值slot;
- 否则,使用key来计算插槽值slot;
场景:计算某个key在哪个实例?
1.16384个插槽分配到不同的实例上;
2. 根据key的有效部分计算哈希值,对16384取余;
3. 余数作为插槽,寻找插槽所在的实例即可。【好处:】
4. 方便的添加或移除节点;
5. 对应槽的采用【直接复制,槽不变化】数据过去显然比rehash快很多

为什么是16384(2^14)个?
答:因为redis发送心跳包时,会将所有槽信息放到心跳包中,发送给其他的redis来交换集群信息。CRC16算法产生的hash值有16bit,但是redis cluster实例建议不超过1000个,超过1000个容易发生网络阻塞,而在redis实例不超过1000个的情况下,将redis集群划分成16384个槽占用的大小的是2k,是比较节省内存空间的,否则使用16bit占用内存大小为16k,完全没有必要。

五、哨兵模式和集群模式的区别

5.1 哨兵模式

优点:高可用,在主节点出现故障时实现故障的转移
缺点:集群容量一旦达到上限,在线扩容十分麻烦,无法做到水平拓展

5.2 集群模式

优点:可以横向扩展
缺点:客户端实现复杂,且slave节点不提供读写的能力,仅仅是一个冷备节点

5.3 区别

  1. 哨兵模式监控权交给了哨兵系统;集群模式中工作节点自己做监控
  2. 哨兵模式发起选举是选举一个leader哨兵节点来处理故障转移;集群模式在节点中选举一个新的主节点来处理故障的转移。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

KY191 矩阵幂(用Java实现)

描述 给定一个n*n的矩阵&#xff0c;求该矩阵的k次幂&#xff0c;即P^k。 输入描述&#xff1a; 第一行&#xff1a;两个整数n&#xff08;2<n<10&#xff09;、k&#xff08;1<k<5&#xff09;&#xff0c;两个数字之间用一个空格隔开&#xff0c;含义如上所示…

《LeetCode热题100》笔记题解思路技巧优化_Part_3

《LeetCode热题100》笔记&题解&思路&技巧&优化_Part_3 &#x1f60d;&#x1f60d;&#x1f60d; 相知&#x1f64c;&#x1f64c;&#x1f64c; 相识&#x1f622;&#x1f622;&#x1f622; 开始刷题链表&#x1f7e2;1. 相交链表&#x1f7e2;2. 反转链表&…

大数据数据分析-scala、IDEA、jdk之间的搭配关系

Scala主要是一门面向对象编程语言和函数式编程语言。 一、大数据框架&#xff08;处理海量/流式数据&#xff09; - ---以HADOOP 2. x为系列的大数据生态系统处理框架 离线数据分析&#xff0c;分析的数据为N1天数据 -----MapReduce 并行计算框架&#xff0c;分而治之…

数据治理系统论-结合数据要素等

什么是数据治理&#xff1f; 数据治理是指组织内外部对数据进行管理和监控的全面框架。它涵盖了数据的安全、合规性、可用性和价值最大化等方面。通过有效的数据治理&#xff0c;组织能够更好地理解其数据资产&#xff0c;并确保数据被正确地管理和利用。 数据治理的重要性 在…

django实现api接口

&#xff08;前期准备&#xff09;第一步&#xff1a;虚拟环境 在windows上使用virtualenvwrapper。 pip install virtualenvwrapper-win 接着&#xff0c;添加环境变量。 echo %WORKON_HOME% 接下来就是创建虚拟环境&#xff0c;假如创建myenv mkvirtualenv myenv 进入…

sqllab第二十八关通关笔记(附带28a)

知识点&#xff1a; union select 整体过滤 union all select 替换where id(输入)空格 过滤了&#xff0c;使用%09代替 经过不断的测试&#xff0c;发现原始语句为 where id(输入) 构造payload:id1)and%091(1 成功回显出了相关的信息 好&#xff0c;尝试进行错误注入 构造…

acwing 3302. 表达式求值

​​​​​​给定一个表达式&#xff0c;其中运算符仅包含 ,-,*,/&#xff08;加 减 乘 整除&#xff09;&#xff0c;可能包含括号&#xff0c;请你求出表达式的最终值。 注意&#xff1a; 数据保证给定的表达式合法。题目保证符号 - 只作为减号出现&#xff0c;不会作为负号…

java虚拟机的堆核心知识介绍

Java虚拟机&#xff08;JVM&#xff09;的堆&#xff08;Heap&#xff09;是Java内存模型中一个至关重要的部分。它是运行时数据区&#xff0c;用于存储Java对象实例。堆是垃圾收集器工作的地方&#xff0c;也是Java应用程序内存管理的关键区域。在本教程中&#xff0c;我们将深…

nvm安装,nvm使用及常用命令,node版本管理

前端学习交流QQ群&#xff1a;1群&#xff1a;173683895 &#xff0c;2群: 173683866 承接项目开发&#xff0c;需求功能开发&#xff0c;博主微信号&#xff1a;Jay_09168 安装包下载地址 下载使用 安装&#xff1a; 点击 nvm-setup.exe&#xff0c;按下图步骤安装&#…

STM32系列——F103C8T6 控制SG90舵机(HAL库)

文章目录 一、舵机控制原理二、.CubeMX配置配置RCC、SYS、时钟树配置RCC配置SYS配置时钟树配置定时器产生PWM波形 Keil5代码接线图及效果如果您发现文章有错误请与我留言&#xff0c;感谢 一、舵机控制原理 舵机的控制一般需要一个20ms左右的时基脉冲&#xff0c;该脉冲的高电平…

(含链接)2024年NVIDIA GPU技术大会开发者合集(专为开发者挑选的合集)

2024年NVIDIA GPU技术大会开发者合集 我专门为开发者整理了NVIDIA GPU技术大会上专注技术的内容合集, 希望可以帮助开发者朋友们快速了解NVIDIA的最新技术. 注意:在电脑端打开更友好, 可以直接进入每一项的网页 文章目录 2024年NVIDIA GPU技术大会开发者合集如何登录和预约会…

[AutoSar]BSW_Com015 PDUR 模块配置

目录 关键词平台说明一、Abbreviations二、PduRBswModules三、PduRGeneration四、PduRDestPdus4.1 全局PDU ID和本地PDU ID 关键词 嵌入式、C语言、autosar、OS、BSW 平台说明 项目ValueOSautosar OSautosar厂商vector &#xff0c; EB芯片厂商TI 英飞凌编程语言C&#xff0…

react中setState是同步的还是异步的

首先说一下setState是同步的还是异步的&#xff1f; 1.解读 setState 工作流 接下来我们就沿着这个流程&#xff0c;逐个在源码中对号入座。首先是 setState 入口函数&#xff1a; ReactComponent.prototype.setState function (partialState, callback) {this.updater.enqu…

美食制作手记

美食制作手记 文章目录 美食制作手记1. 焖饭系列 1. 焖饭系列 一周五款不重样的电饭煲焖饭&#xff01;妈妈再也不用担心我没好好吃饭了~ 老干妈香菇腊肠焖饭 排骨土豆焖饭 南瓜鸡腿焖饭 番茄牛肉焖饭 羊肉胡萝卜葡萄干焖饭 不定期持续更新…

ThingsBoard初始化数据库Postgres

本章将介绍ThingsBoard的本地环境搭建&#xff0c;以及源码的编译安装。本机环境&#xff1a;centos7&#xff0c;docker,postgres 环境安装 开发环境要求&#xff1a; docker pcentos7 &#xff1b;docker&#xff1b;postgres: 1、使用Docker创建postgres容器化创建 docker…

JS函数知识点(复习)

在 JavaScript&#xff08;JS&#xff09;中使用函数有多种原因&#xff0c;这些原因不仅涉及到代码的组织和可读性&#xff0c;还涉及到代码的可维护性、复用性以及程序的模块化等方面。以下是一些关键的理由&#xff1a; 代码重用&#xff1a;函数允许你将一段代码块封装起来…

(五)消息队列

一、概念 队列又称消息队列&#xff0c;是一种常用于任务间通信的数据结构&#xff0c;队列可以在任务与任务间、中断与任务间传递信息&#xff0c;实现了任务接收来自于其他任务或中断的不定长度信息 二、常用函数 &#xff08;1&#xff09;xQueueCreate创建队列 &#xf…

基于深度学习的唇语识别系统的设计与实现

概要 人工智能作为三大工程之一&#xff0c;从上个世纪至今仍然活跃于各个行业的研究与应用之中&#xff0c;应时代的热潮方向&#xff0c;本 课题主要针对深度学习技术应用于唇语识别当中&#xff0c;实现词语唇语的翻译功能。唇语识别在图像处理中一直是一个富 有挑战性的课题…

C语言基础学习

1 extern 在C语言中&#xff0c;关键字extern用于声明一个变量或函数是在其他文件或模块中定义的。它告诉编译器变量或函数是在其他地方被定义的&#xff0c;而不是在当前文件中。这样做可以使多个文件共享同一个变量或函数&#xff0c;而不需要在每个文件中都重新定义一次。 …

力扣59. 螺旋矩阵 II

思路&#xff1a;此题思路就是绕圈遍历&#xff0c;全靠条件处理技巧&#xff0c;重点要清楚的就是循环不变量&#xff1a;左闭右开&#xff08;即拐弯处的一个数&#xff0c;留给第二行处理&#xff09; 以下是代码随想录的作者的一张图片&#xff0c;每次for循环&#xff0c;…