【Redis进阶】集群

1. 集群分片算法

1.1 集群概述

首先对于"集群"这个概念是存在不同理解的:

  • 广义的"集群":表示由多台主机构成的分布式系统,称为"集群"
  • 狭义的"集群":指的是redis提供的一种集群模式,用来解决存储空间不足的问题(拓展存储空间)

前面我们介绍的哨兵、主从模式都是为了保障系统的可用性,但是目前为止,无论是主节点还是从节点都需要完整的保存数据的全集,但是当前是一个"大数据时代",我们希望能够保证高效的同时,存储空间足够,因此引入了"集群模式"

1.2 分片算法

那么我们如何将数据分成多份,保存在不同的节点中呢?此时的每一份数据被称为一个"分片"(sharding)
常见的分片算法有如下三种:

  1. 哈希求余算法
  2. 一致性哈希算法
  3. 哈希槽分区算法

1.2.1 哈希求余算法

该算法本质借鉴了哈希表这种数据结构的思想:借助哈希函数将一个key映射为一个整数,然后对数组的长度进行取余操作得到对应数组下标,即保存位置。同理,哈希求余算法也是一样,比如一共分为三个分片,标记为0,1,2。然后就将redis中的key使用一种哈希算法(比如md5)计算结果得到hash值,然后对分片总数3进行取余操作得到对应的分片下标

示例:假设hash(key) % 3 == 0 => 计算得出保存的分片编号为0,于是将数据保存在0号分片上;当需要获取数据的时候也是通过同样的key以及同样的hash算法,经过计算hash(key) % 3 ==0 得到分片位置,取出数据

值得一提的是md5算法就是常见的哈希算法,内部经过一系列的数学运算能够将一个字符串转换为整数值,其特点如下:

  1. md5的计算结果是定长的,比如使用md5-16算法,无论原始字符串是怎样的,最终的计算结果都是一个16位的16进制数字
  2. md5计算结果是分散的,意味着即使两个输入字符串大部分内容相同,只有少部分不同,得到的计算结果也是大相径庭的
  3. md5是不可逆的(也用于加密算法),表示给定一个输入字符串可以轻易计算出结果,但是给定结果却无法还原出输入内容

哈希求余缺点:
当前哈希求余算法存在一定的缺点,比如当前为3个分片,哈希函数为hash(key) = key,再对3取余得到当前的分片结果为:0:102,105,108,1:103,106,109,2:104,107,110,但是此时需要进行扩容:重新哈希后分片结果为:0:104:108,1:105,109,2:102,106,110,3:103,107,不难发现,扩容之后大部分数据都需要进行迁移搬运。
总结:
因此当前扩容过程开销是很大的,是万万不能在生产环境上执行的,只能通过"替换"等曲线救国方式来实现扩容,成本更高、操作步骤也更为复杂了。

1.2.2 一致性哈希算法

为了降低上述的搬运开销,业界又提出了"一致性哈希算法",从key映射到分片序号的过程就不再是简单求余了,而是改成了以下过程:
Step1:将0 - 2^32 - 1这个数据空间,映射到一个圆环上,数据按照顺时针方向增长

Step2:假设当前存在3个分片,就把分片指针放到对应的位置:

Step3:假设有一个key,计算得到hash值为H,那么应该分配到哪个分片上呢?规则很简单,就是找到对应的位置然后顺时针找到的第一个分片就是其从属的分片位置

Step4:如果此时需要扩容,分片数由3 -> 4应该如何操作呢?、

我们随机在圆盘上找一个位置插入3号分片,此时只需要将2号分片的部分数据搬运到3号分片上就完成了搬运操作,上述过程虽然仍存在一定的搬运开销,但是相比较于哈希求余算法,就要少的多了,但是一致性哈希算法也存在着一个重要缺点:
一致性哈希缺点:
那就是存在"数据倾斜"问题,当前如果平均将0-2^32-1数据空间划分为0,1,2三个分片,一旦进行扩容,就会导致每个分片的数据量不均衡

1.2.3 哈希槽分区算法

这是redis真正采取的算法,其哈希槽计算公式为hash_slot = crc16(key) % 16384
该种算法实质上是将哈希求余算法和一致性哈希算法结合了起来,下面给出了一种分配方式
假设当前有三个分片:

  • 0号分片:[0, 5641]共5642个槽位号
  • 1号分片:[5642,10923]共5642个槽位号
  • 2号分片:[10924,16383]共5460个槽位号

虽然不是严格意义上的平均分配,但是差异非常小,可以近似看做是均匀分配了,并且每个分片还会使用位图这样的数据结构表示当前具有槽位号,16384个比特位 => 2KB存储空间

注意:这里只是其中一种分配方式,事实上分配方式是非常灵活的,每个分片持有的槽位号可以是连续的,也可以是不连续的

问题一:Redis集群是最多有16384个分片么?
如果redis集群有16384个分片,此时按照平均划分每个分片分配到一个槽位号(很难),因为我们的key是先映射到槽位号,然后再映射到分片上的,此时就很难保证各个分片的均衡性。
实际上redis的作者建议集群分片数不应该超过1000
问题二:为什么是16384个槽位号?
这个问题有人在github上询问了,作者给出的答复是:由于我们redis集群节点之间后续需要通过频繁传递心跳包检测是否存活,而心跳包中包含了某个分片含有哪些槽位号等信息,16384个槽位号可以用2KB存储,但是65535就需要8KB了,16384能保证通信可用性的同时尽可能节省网络带宽等资源

2. 集群故障恢复

集群故障:如果当前集群中有节点挂了,应该怎么办?这里需要分情况讨论:

  • case1:如果挂了的是从节点,那就没事
  • case2:如果挂了的是主节点,那就需要进行故障转移操作

2.1 故障判定

该步骤主要用于确定集群中哪个节点挂了,主要流程如下:

  1. 节点之间通过心跳包进行通信:比如节点A给节点B发送ping包,节点B需要给节点A返回pong包(这两个数据包只有message type字段不同,其余内容相同)心跳包中包含集群的配置信息,比如节点id、节点从属于哪个分片、是主节点还是从节点、持有哪些slots的位图
  2. 每个节点每秒钟都会给随机一些节点发送ping包,不是全发一遍(避免节点很多时洪泛发送心跳包)
  3. 当节点A给节点B发送ping包,B不能如期回应时,A就会尝试重置和B的TCP连接,如果仍连接失败,就会把B标记为PFAIL状态(主观下线)
  4. A判定B为PFAIL之后,就会通过redis内部Gossip协议与其他节点通信,确认B的状态(每个节点会维护一个主观下线列表)
  5. 如果超过半数节点认为B主观下线,那么A就会把B标记为FAIL状态(客观下线),并将此消息同步给其他节点

2.2 故障迁移

该步骤主要用于保障集群可用性,假设节点B被标记为FAIL客观下线,存在两种情况:

  • 如果是主节点,则将由B的从节点来触发故障转移
  • 如果是从节点,则不会触发故障转移操作

故障转移流程:

  1. 从节点判定自身是否有资格参与选举,如果主从之间太久没有通信,时间超过阈值,则没有资格参与选举
  2. 具有资格的从节点比如C和D,就会休眠上一段时间(500ms基础时间 + [0,500]ms随机时间 + 排名 * 1000ms),其中offset同步值越大,排名靠前(越小)
  3. 比如C的休眠时间到了,C就会给集群中其他节点发送请求,申请拉票(只有主节点才有资格投票
  4. 当节点C的得票数超过半数主节点之后,C就会晋升成为主节点(自己执行slaveof no one)并让D执行slaveof C
  5. 同时C还会把自己晋升为主节点的事,同步给集群中其余节点,大家就会更新保存的集群结构信息

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

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

相关文章

K210视觉识别模块学习笔记8:Mx_yolo3本地模型训练环境搭建_部署模型到亚博canmv(失败)

今日开始学习K210视觉识别模块: 本地模型训练环境搭建 亚博智能 K210视觉识别模块...... 固件库: canmv_yahboom_v2.1.1.bin 本地训练 Mx_yolo3 这里就简单地提示一下下载安装哪些软件,然后主要是使用Mx_yolo3 进行本地训练模型的...... 本文不…

【Android】Fragment的添加

上一篇文章学到了碎片的创建与生命周期,接下来学习碎片的常用操作,其中会用到上一篇文章的三个碎片,就做一个简单的说明吧:LeftFragment(包含一个按钮)、RightFragment4(以粉色为背景的文本&…

跨境电商选品师做好这几个关键点

在当今充满竞争的跨境电商市场上,成为一名成功的选品师并非易事。以下是几个关键点,能够帮助跨境电商选品师做好工作并取得成功。下面老阳为大家总结几点做好跨境选品师的几个关键点,希望对大家有所帮助。 首先,深入市场调研和产品…

Notepad

https://codeforces.com/contest/17/problem/D ​​​​​​​ 没有前导零 因此一共写个数字&#xff0c;再mod c 数据范围很大,因此我们魔改一下快读 再用扩展欧拉定理 #include<iostream> #include<cstdio> #include<cstring> using namespace std; ty…

JAVA里的多线程上部(详解)

1.实现多线程 1.1简单了解多线程【理解】 是指从软件或者硬件上实现多个线程并发执行的技术。 具有多线程能力的计算机因有硬件支持而能够在同一时间执行多个线程&#xff0c;提升性能。 1.2并发和并行【理解】 并行&#xff1a;在同一时刻&#xff0c;有多个指令在多个CPU上…

华清IOday2 24-7-29

1> 写一个日志文件&#xff0c;将程序启动后&#xff0c;每一秒的时间写入到文件中 1、2024- 7-29 10:31:19 2、2024- 7-29 10:31:20 3、2024- 7-29 10:31:21 ctrlc:停止程序 ./a.out 4、2024- 7-29 10:35:06 5、2024- 7-29 10:35:07 6、2024- 7-29 10:35:08 main.c …

缓存穿透,缓存击穿,缓存雪崩

目录 介绍 缓存穿透 缓存击穿 缓存雪崩 原因 影响 解决方案 缓存穿透 防止缓存穿透->空值缓存案例 缓存击穿 使用互斥锁解决缓存击穿 介绍 缓存穿透 定义&#xff1a;缓存穿透是指用户查询数据&#xff0c;缓存和数据库中都不存在该数据&#xff08;一般是发起恶意…

实战:ZooKeeper 操作命令和集群部署

ZooKeeper 操作命令 ZooKeeper的操作命令主要用于对ZooKeeper服务中的节点进行创建、查看、修改和删除等操作。以下是一些常用的ZooKeeper操作命令及其说明&#xff1a; 一、启动与连接 启动ZooKeeper服务器&#xff1a; ./zkServer.sh start这个命令用于启动ZooKeeper服务器…

403 forbidden (13: Permission denied)

403 forbidden (13: Permission denied) 目录 403 forbidden (13: Permission denied) 【常见模块错误】 【解决方案】 欢迎来到我的主页&#xff0c;我是博主英杰&#xff0c;211科班出身&#xff0c;就职于医疗科技公司&#xff0c;热衷分享知识&#xff0c;武汉城市开发者…

基于视觉的语义匹配见多了,那基于雷达的呢?

论文题目&#xff1a; LiDAR-based HD Map Localization using Semantic Generalized ICP with Road Marking Detection 论文作者&#xff1a; Yansong Gong, Xinglian Zhang, Jingyi Feng, Xiao He and Dan Zhang 作者单位&#xff1a;北京驭势科技有限公司 导读&#xff…

python 查询机器python、gpu、安装包等环境版本信息

checkenv.py """Check environment configurations and dependency versions."""import importlib import os import resource import subprocess import sys from collections import OrderedDict, defaultdictimport torch# 查询自己想要的包…

cf960(div2)

A. Submission Bait&#xff08;博弈&#xff09; 题意&#xff1a;爱丽丝和鲍勃在大小为n的数组a中进行游戏&#xff0c;他们轮流进行运算&#xff0c;爱丽丝先开始&#xff0c;不能运算的一方输&#xff0c;一开始mx0&#xff0c;每次操作&#xff0c;玩家可以选择一个牵引i…

MOMFEA-SADE--基于子空间对齐和自适应差分进化的多目标多任务优化算法

MOMFEA-SADE–基于子空间对齐和自适应差分进化的多目标多任务优化算法 title&#xff1a; Evolutionary Multitasking for Multiobjective Optimization With Subspace Alignment and Adaptive Differential Evolution author&#xff1a; Zhengping Liang, Hao Dong, Cheng …

【Git】 如何将一个分支的某个提交合并到另一个分支

【Git】 如何将一个分支的某个提交合并到另一个分支 在使用 Git 进行版本控制时&#xff0c;常常会遇到这样的需求&#xff1a;将某个分支的特定提交合并到另一个分支中。这种情况下&#xff0c;我们可以使用 cherry-pick 命令来实现。本文将详细介绍 cherry-pick 命令的使用方…

“链动革新:2+1模式引领用户复购与留存潮流“

大家好&#xff01;我是吴军&#xff0c;来自一家在业界享有盛誉的软件开发公司&#xff0c;担任产品经理一职。今天&#xff0c;我想和大家深入探讨一个话题——如何利用创新的链动21模式来显著提升用户的留存率和复购率。 提到链动模式&#xff0c;很多人可能第一时间想到的是…

醒醒,别睡了...讲《数据分析pandas库》了—/—<6>

一、 1、长宽格式转换 基于多重索引&#xff0c;Pandas 可以很容易地完成长型、宽型数据格式的相互转换。 1.1 转换为最简格式 stack&#xff08;&#xff09;其使用法如下&#xff1a; stack函数用于将DataFrame中的列转换为行&#xff0c;即将宽格式数据转换为长格式数据。…

中控屏UI设计全解析:布局与交互技巧

在现代科技的浪潮中&#xff0c;中控屏已成为智能系统不可或缺的交互界面。无论是智能家居、车载系统还是工业控制&#xff0c;一个直观、易用且美观的中控屏 UI 设计对于提升用户体验至关重要。本教程将带领你深入探索中控屏UI设计的精髓&#xff0c;指导你如何打造出既专业又…

2024.7.28 记录一次悲惨的笔试——作业帮NLP校招

小红的奇偶抽取 题目描述 题解 #include <iostream> #include<stack> using namespace std;int main() {long long n;stack <int> ji, ou;cin >> n;while (n) {int a n % 10;if (a % 2 0)ou.push(a);elseji.push(a);n n / 10;}long long jN 0, o…

用深度学习改进乳腺癌MRI诊断| 文献速递--AI辅助的放射影像疾病诊断

Title 题目 Improving breast cancer diagnostics with deep learning for MRI 用深度学习改进乳腺癌MRI诊断 01 文献速递介绍 乳腺磁共振成像&#xff08;MRI&#xff09;是一种检测乳腺癌的高度敏感的方式&#xff0c;报告的敏感性超过80%。传统上&#xff0c;其在筛查…

html+css+js作业王者荣耀司空震1个页面带js

htmlcssjs作业王者荣耀司空震1个页面带js 下载地址 https://download.csdn.net/download/qq_42431718/89595421 目录1 目录2 项目视频 htmlcssjs作业王者荣耀司空震1个页面 页面1