前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >借 redis cluster 集群,聊一聊集群中数据分布算法

借 redis cluster 集群,聊一聊集群中数据分布算法

原创
作者头像
平头哥的技术博文
修改于 2019-12-13 02:14:54
修改于 2019-12-13 02:14:54
6390
举报

Redis Cluster 集群中涉及到了数据分布问题,因为 redis cluster 是多 master 的结构,每个 master 都是可以提供存储服务的,这就会涉及到数据分布的问题,在新的 redis 版本中采用的是虚拟槽分区技术来解决数据分布的问题,关于什么是虚拟槽分区技术我们后面会详细的介绍。在集群中除了虚拟槽分区技术之外,还有几种数据分布的算法,比如哈希算法,一致性哈希算法,这篇文章我们就来一起聊一聊这几种数据分布算法。

因为是集群,所以我们需要一个大前提,在这篇文章中假设 redis cluster 集群中有三台 master,我们需要存储的数据集为:[{id:1,"name":"1"},{id:2,name:"2"},{id:3,name:"3"},{id:4,name:"4"},{id:5:"name":"5"},{id:6,"name":"6"}],在这个大前提下,我们来聊一聊集群中的数据分布算法。

哈希算法

哈希算法在分布式架构中应用广泛,不仅仅是数据存储,还有负载均衡等应用上有用的比较多,哈希算法的思想非常简单,也许你知道 HashMap 的哈希函数,哈希算法跟 HashMap 一样,也是通过一个哈希函数得到某一个数字,然后根据数字找到相应的服务器。哈希算法的哈希函数比较简单,一般是根据某个key的值或者key 的哈希值与当前可用的 master节点数取模,根据取模的值获取具体的服务器。哈希算法服务结构模型图如下图所示:

哈希算法结构模型图
哈希算法结构模型图

用我们前面假设的数据,利用哈希算法来实验一把,加深我们对哈希算法在分布式中的应用的理。我们假设哈希算法中的哈希函数为“id % master 节点数”,结果为 0 的数据存放到 server1 服务器上,结果为 1 的数据存放到 server2 服务器上,结果为 2 的数据存放到 server3 服务器上。

所以经过哈希算法之后,id=3、id=6 的数据与 master 节点数取模为 0 (3%3=0,6%3=0),所以这两个数据会存放到 server1 服务器 ,以此类推,id=1、id=4 的数据将存放到 server2 服务器中,id=2、id=5 的数据将存放到 server3 上,这时候服务器存储数据如下图所示:

服务器存储数据
服务器存储数据

这就是哈希算法在分布式中的作用,比较简单,可以看出只要你哈希函数设计的好,数据在各个服务器上是比较均匀分布的,但是哈希算法有一个致命的缺点:扩展性特别的差,比如我们的集群中,服务器server3 宕机了,这时候集群中可用的机器只有两台了,这样哈希函数就变成了id % 2了,这就会导致一个问题,所有的数据需要重新计算,找到新的存储节点,每次有服务器宕机或者添加机器时,都需要进行大量的数据迁移,这会使得系统的可用性、稳定性变差。

一致性哈希算法

一致性哈希算法可以说是哈希算法的升级版,解决了哈希算法扩展性差的问题,一致性哈希算法跟哈希算法不一样,一致性哈希算法会将服务器和数据都通过哈希函数映射到一个首尾相连的哈希环上,存储节点映射可以根据 ip 地址来进行哈希取值,数据映射到哈希环上后按照顺时针的方向查找存储节点,即从数据映射在环上的位置开始,顺时针方向找到的第一个存储节点,那么他就存储在这个节点上

我们使用一致性哈希算法来存储我们的数据,我画了一张图来模拟一致性哈希算法可能出现的结果:

一致性算法模拟存储图
一致性算法模拟存储图

我们先来解读一下这张图,按照一致性哈希算法的规则,数据沿着顺时针的方向查找数据,那么 id=4 的数据存放在 server1 服务器,id=2 的数据存放在服务器 server2 上,id=3、id=1、id=5、id=6 的数据都存放在服务器 server3 上,如果你比较敏感的话,也许你就会发现一致性哈希算法的不足之处, 从图中可以看出,我们六条数据分布不均匀,并不是每台服务器存储 2 条数据,而且差距好像还有点大,这里我们就要来说一说一致性哈希算法的缺点:一致性哈希算法会会造成数据分布不均匀的问题或者叫做数据倾斜问题,就像我们图中那样,数据分布不均匀可能会造成某一个节点的负载过大,从而宕机。造成数据分布不均匀有以下两种情况:

  • 第一:哈希函数的原因,经过哈希函数之后服务器在哈希环上的分布不均匀,服务器之间的间距不相等,这样就会导致数据不均匀。
  • 第二:某服务器宕机了,后继节点就需要承受原本属于宕机机器的数据,这样也会造成数据不均匀。

前面我们提到过一致性哈希算法解决了哈希算法中扩展性差的问题,这个怎么理解呢?我们来看看,在一致性哈希算法中当有存储节点加入或者退出时,只会影响应该该节点的后继节点,举个例子说明一下,例如我们要在服务器server3 和服务 server2 之间加入了一个服务器存储节点 server4,只会对服务器server3 造成影响,原本存储到服务器server3 上的数据有一部分会落入到服务器 server4 上,对服务器 server1 和 server2 并没有任何影响,这样就不会进行大量的数据迁移,扩展性就变强了。

带有限负载的一致性哈希算法

因为一致性哈希算法的数据分布不均匀的问题,Google 在 2017 年提出了带有限负载的一致性哈希算法来解决这个问题,带有限负载的一致性哈希算法思想比较简单,给每个存储节点设置了一个存储上限值来控制存储节点添加或移除造成的数据不均匀,当数据按照一致性哈希算法找到相应的存储节点时,要先判断该存储节点是否达到了存储上限;如果已经达到了上限,则需要继续寻找该存储节点顺时针方向之后的节点进行存储。

我们利用带有限负载的一致性哈希算法来改进上面的数据存储,我们限定每台服务器节点存储的数据上限为 2 ,数据插入的顺序就按照 ID 大小的顺序,同样我也画了一张模拟图:

带有限负载的一致性哈希算法
带有限负载的一致性哈希算法

一起来分析一下这张图,因为我们的添加顺序是按照 id 大小的顺序,所以前四个数据都没有问题,这时候的服务器都没有超过最高负载数量,id=5 的数据落在了服务器server2 和服务器server3 之间,本应该是存储在服务器server3 上,但是由于此时的服务器server3 上已经存储了 id=1、id=3 的数据达到了最高限定,因此 id=5 的数据会沿着顺时针的方向继续往下寻找服务器,下一个服务器就是server1,此时的服务器server1 就存储了 id=4 的数据并没有达到上限,所以 id=5 的数据就会存储在服务器server1,id=6 的数据同样的道理。这样就利用带有限负载的一致性哈希算法解决了一致性哈希算法中数据分布不均匀的问题。

带虚拟节点的一致性哈希算法

带有限负载的一致性哈希算法也有一个问题,那就是每台服务器的性能配置可能存在不一样,如果规定数量过小的话,对于配置高的服务器来说有点浪费,这是因为服务器之间可能存在差异,叫做服务器之间的异构性,为了解决服务器之间的异构性问题,引入了一种叫做带虚拟节点的一致性哈希算法,带虚拟节点的一致性哈希算法核心思想是:根据每个节点的性能为每个节点划分不同数量的虚拟节点,并将这些虚拟节点映射到哈希环中,然后再按照一致性哈希算法进行数据映射和存储

为了演示带虚拟节点的一致性哈希算法,我们先做一个假设服务器server3是配置最差的,所以我们以服务器server3 为基准,服务器server2 是服务器server3 的两倍,服务器server1 是服务器server3 的三倍,有了这个前提之后,我们就可以来建立虚拟节点,我们假设服务器server3 的虚拟节点为服务器server3_1,服务器server2 就有两个虚拟节点服务器server2_1、服务器server2_2,服务器server1 有三个虚拟节点 服务器server1_1、服务器server1_2、服务器server1_3。我还是跟前面一样画了一张模拟图:

落到虚拟节点上的数据都会存到对应的物理服务器上,所以通过带虚拟节点的一致性哈希算法后,数据存储结果为:数据id=2、id=3、id=5 的数据都会存储到服务器server1 上,id=1 的数据将会存储到服务器server2 上,数据 id=4、id=6 都会存放到服务器server3上。

虚拟节点可以让配置好的服务器存储更多的数据,这样就解决了系统异构性的问题,同时由于大量的虚拟节点的存在

在数据迁移时数据会落到不同的物理机上,这样就减小了数据迁移时某台服务器的分担压力,能够保证系统的稳定性。

虚拟槽分区

虚拟槽分区是 redis cluster 中默认的数据分布技术,虚拟槽分区巧妙地使用了哈希空间,使用分散度良好的哈希函数把所有数据映射到一个固定范围的整数集合中,这个整数定义为槽(slot),而且这个槽的个数一般远远的大于节点数。

在 redis cluster 中有16384(0~16383)个槽,会将这些槽平均分配到每个 master 上,在存储数据时利用 CRC16 算法,具体的计算公式为:slot=CRC16(key)/16384 来计算 key 属于哪个槽。在我们的集群环境中,一个 key 的存储或者查找过程,可能如下图所示:

虚拟槽分区解耦了数据与节点的关系,通过引入槽,让槽成为集群内数据管理和迁移的基本单位,简化了节点扩容和收缩难度,你只需要关注数据在哪个槽,并不需要关心数据在哪个节点上。所以虚拟槽分区可以说比较好的兼容了数据均匀分布和扩展性的问题。

以上就是我要分享关于集群中数据分布的技术,希望本文的内容对大家的学习或者工作能带来一定的帮助,感谢大家的支持

最后

目前互联网上很多大佬都有数据分布相关文章,如有雷同,请多多包涵了。原创不易,码字不易,还希望大家多多支持。若文中有所错误之处,还望提出,谢谢。

原文发布于微信公众号 -平头哥的技术博文(id:pingtouge_java) 作者:平头哥,学会伺机而动,实现弯道超车 ZjYyMjU2OWMyMTA3?x-oss-process=image/format,png)

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
暂无评论
推荐阅读
如何破解一个Python虚拟机壳并拿走12300元ETH
之前在群里看到有人发了一个挑战,号称将 5 ETH 的私钥放在了加密的代码中,只要有人能解密就可以取走,所以我又管不住自己这双手了。
evilpan
2023/02/12
5710
如何破解一个Python虚拟机壳并拿走12300元ETH
Python写的Python解释器(四)
真正的Python字节码 现在让进入真正的Python字节码中,从一个简单的函数开始:
哒呵呵
2018/08/06
6400
一文让你完全弄懂Stegosaurus
国内关于 Stegosaurus 的介绍少之又少,一般只是单纯的工具使用的讲解之类的,并且本人在学习过程中也是遇到了很多的问题,基于此种情况下写下此文,也是为我逝去的青春时光留个念想吧~
Angel_Kitty
2018/12/19
1.2K0
简单入门python字节码混淆
我就是小菜鸡本鸡了,不是很会写东西,请各位大佬多多见谅。本文基于python2.7,因为python3并不是很懂。
ChaMd5安全团队
2019/05/07
2.4K1
你了解 Python 字节码的原理吗?
如果你曾经写过或者用过 Python,你可能已经习惯了看到 Python 源代码文件;它们的名称以.Py 结尾。你可能还见过另一种类型的文件是 .pyc 结尾的,它们就是 Python “字节码”文件。这里转载一篇文章,专门讲解 Python 字节码的相关内容,给大家看看。
崔庆才
2019/06/14
2.6K0
你了解 Python 字节码的原理吗?
【PY】Python3 字节码详解
在逆向的时候遇到过反编译 py 字节码,之前也就没咋在意,啥不会查就完事儿了,好家伙,省赛让我给遇到了,直接嘤嘤嘤😭,但还好解出来了;
sidiot
2023/08/31
3450
【PY】Python3 字节码详解
[oeasy]python0135_python_语义分析_ast_抽象语法树_abstract_syntax_tree
print("1982------Guido in cwi") print("1995------Guido in cnri") print("2000------Guido in beopen") print("2005------Guido in google") print("2012------Guido in dropbox") print("2020------Guido in microsoft")
oeasy
2023/04/16
4200
[oeasy]python0135_python_语义分析_ast_抽象语法树_abstract_syntax_tree
Python 高级教程之探索 Python code object
Code objects 是 CPython 实现的低级细节。 代码对象是 CPython 对一段可运行 Python 代码的内部表示,例如函数、模块、类体或生成器表达式。当你运行一段代码时,它会被解析并编译成一个代码对象,然后由 CPython 虚拟机 (VM) 运行。代码对象包含直接操作 VM 内部状态的指令列表,例如“将堆栈顶部的两个对象加在一起,将它们弹出,然后将结果放入堆栈”。这类似于像 C 这样的语言的工作方式:您将代码编写为人类可读的文本,该代码由编译器转换为二进制格式,然后运行二进制代码(C 的机器代码和 Python 的所谓字节码)直接由 CPU(对于 C)或由 CPython VM 的虚拟 CPU 执行。
海拥
2022/05/07
7500
Python 之父亲自优化解释器性能
2020 年 11 月 Python 之父(Guido)加入微软,按他个人的说法是自己的退休生活太无聊了。站在现在的这个时间点,一年半的时间过去了。Guido 的工作中对开发者来说感知最强的应该数 Cpython 解释器的性能优化了。
初代庄主
2022/09/22
3150
Python 之父亲自优化解释器性能
[oeasy]python0010 - python虚拟机解释执行py文件的原理
​解释运行程序 🥊回忆上次内容我们这次设置了断点设置断点的目的是更快地调试调试的目的是去除​​bug​​别害怕​​bug​​一步步地总能找到​​bug​​这就是程序员基本功调试​​debug​​我心中还是有疑问​​python3​​ 是怎么解释​​hello.py​​ 的?🤔纯文本我们的py文件是一个纯文本文件​编辑​打开我们的guido.py​如果没有就新做一个这里面是一个个的字符print("1982------Guido in cwi")print("1995------Guido in cnri
oeasy
2022/10/21
4940
[oeasy]python0010 - python虚拟机解释执行py文件的原理
python数据分析源码_python 统计分析
第一步克隆 Cpython 仓库到本地, 切换到我当前的版本, 我当前的版本号是 3.8.0a0
全栈程序员站长
2022/09/24
5870
python数据分析源码_python 统计分析
通过内置对象理解 Python(二)
在上一节的基础上,下面从一些最有趣的内容开始,这些内容构建了 Python 作为一种语言的基础,逐一对内置函数进行探讨。
老齐
2021/11/04
4050
一个关于 += 的谜题
当时看到这个问题,第一反应就是选 2。因为 tuple 是不可变对象,不支持对它的元素赋值,会报错。
AlwaysBeta
2022/02/28
3190
Python的Sequence切片下标问题
在python中, 切片是一个经常会使用到的语法, 不管是元组, 列表还是字符串, 一般语法就是:
Lin_R
2018/10/22
9870
Python dis 模块初步使用
Python 代码先被编译为字节码后,再由Python虚拟机来执行字节码, Python的字节码是一种类似汇编指令的中间语言, 一个Python语句会对应若干字节码指令,虚拟机一条一条执行字节码指令, 从而完成程序执行。 Python dis 模块支持对Python代码进行反汇编, 生成字节码指令。 先来一小段代码:
py3study
2020/01/07
1.1K0
详解Python的is操作符
is 操作符是Python语言的一个内建的操作符。它的作用在于比较两个变量是否指向了同一个对象。 与 == 的区别 class A(): def __init__(self, v): self.value = v def __eq__(self, t): return self.value == t.value a = A(3) b = A(3) print a == b print a is b 这个结果是True,False。因为我们重写了__
海纳
2018/03/02
8110
python 基准测试(cProfile \ kcachegrind \ line_profiler \ memory_profiler)
该包可以了解代码是如何转换为字节码的, dis 表示 disassemble 反汇编
Michael阿明
2022/09/21
1.4K0
python 基准测试(cProfile \ kcachegrind \ line_profiler \ memory_profiler)
【PY】Python3 字节码混淆
emmm,关于字节码混淆,最早碰到还是在校赛的时候,当时一脸懵逼,什么情况,怎么 uncompyle6 不能反编译 pyc 了,不过之后也就不了了之了,今天特地写此博文纪念 DASCTF Oct X 吉林工师魔法赛 中的一道 RE 题 —— 魔法叠加,出题人是真的阴间💩  
sidiot
2023/08/31
5260
【PY】Python3 字节码混淆
初识Python(一)
默认执行上述的hello.py文件,需要明确的指出hello.py脚本由python解释器来执行,即python hello.py。
py3study
2020/01/11
4320
笨办法学 Python3 第五版(预览)(二)
现在你将把函数与你从之前练习中了解到的变量结合起来。如你所知,变量给数据片段一个名称,这样你就可以在程序中使用它。如果你有这段代码:
ApacheCN_飞龙
2024/03/03
2540
笨办法学 Python3 第五版(预览)(二)
相关推荐
如何破解一个Python虚拟机壳并拿走12300元ETH
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档