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

Redis-集群Cluster

上篇文章谈到的哨兵机制,提高了系统的可用性,但是真正存储数据的还是master主节点和slave从节点,所有的数据都要存储在master和slave上.数据量很大时,超出master/slave所在物理机的物理内存,就可能会出现很严重的问题了.

怎样获取更大的空间来存储数据呢?


目录

1.redis集群:

2.数据分片算法:

1.哈希求余:

2.一致性哈希算法:

3.哈希槽分区算法(Redis采用的):

这里有两个问题:


所谓"大数据"的核心是一台机器存储不下了,可以用多态机器共同来存储.

1.redis集群:

redis集群就在解决上述问题:

通过引入多组master/slave,每组matser/slave存储数据全集的一部分,从而构成一个更大的整体,就称为redis集群.

将每一组master/slave称为一个"分片".

当数据量进一步增多时,通过增加分片的方法即可解决.

2.数据分片算法:

redis-cluster通过多个分片共同存储所有数据,又有两个核心问题:

1 .当写入一个数据,要存储到哪个分片上;读取数数据时,从哪个分片读取;

2. 当当前分片由于数据的增多又无法存储,需要再增加新分片机器时,又要如何调整呢?

这里有几种方法来实现:

1.哈希求余:

设有N个分片,对其进行编号[0,N-1]; 针对某一数key,先对其求哈希值,得到一个整数,把得到的hash值%分片个数N,得到的值就是要存储的分片编号.

后续要取数据时,也是针对要取得key,对key计算hash值,再对其%N,就可以找到对应的分片编号了.

优点: 简单高效,数据分配均匀;

缺点: 一旦需要进行扩容时,N就要改变原有的映射规则就会被破坏,需要让节点之间相互数据传输, 对大量的数据进行重新排列,以满足新的映射规则,开销较大.

MD5算法 是一种计算哈希值的常用方法,MD5计算结果特点:

1. 计算结果是定长的: 16位/32位/64位

2.计算结果是分散的: 相差很小的key计算出的MD5值都有很大的差别.

3. 计算结果是不可逆的: 计算出的结果是无法复原的.

2.一致性哈希算法:

为了降低数据的搬运开销,更高效的扩容, 一致性和希算法 可以缓解上述问题:

具体过程:

1>. 将0-2^32-1这个数据空间,映射到一个圆环上,按照顺时针的方向增长;

2>. 首次分片时,将分片均匀的放到圆环上的某些位置.

3>. 当要存储一个数据时,计算其hash值, 根据hash值,在圆环上顺时针向下找,找到的第一个分片,就存储在该分片上;读取数据也是这样,先计算要读取数据的hash值,然后在圆环上顺时针向下找,找到的第一个分片就是数据所在的位置.

分片扩容时,仅需要在圆环的某个位置上安排一个新的分片即可,仅将圆环上 新分片插入位置 之前的数据从原分片上传到新分片上即可,无需对整体的数据进行调整.缓解了大量数据迁移的开销.

优点: 大大降低了分片扩容时,数据搬运的开销,提高了扩容操作的效率.

缺点: 这样分片会导致数据不均匀分布,出现数据倾斜.(有可能有的分片上一个数据也没有,浪费硬件资源)

3.哈希槽分区算法(Redis采用的):

上面两种分片方法都存在一定的缺陷,redis-cluster 并未采取上述两种方法,而是使用哈希槽分区算法. 该方法解决了数据搬运成本高和数据不均匀分配的问题.

算法规则:

把整个hash值,映射到16384个槽位上: [0,16383], 然后将这些槽位均匀的分给每一个分片. 每一个分片都要记录自己持有哪些槽点.

写入数时,先对16384求余,计算出哈希槽,然后根据哈希槽找到所在得分片,就可以将数据写入了.  

当要扩容分片时,针对原有分片重新分配,从每个分片上拿走一些槽位,放到新的分片上,保证每个分片上槽位尽量均匀即可. 槽位分配可以是连续的,也可以是不连续的,非常灵活,每个分片使用"位图"表示该分片上所属于的操作.

假设当前有3个分片,可以这样分配:

0号分片:[0,5461],共5462个槽位;

1号分片: [5462,10923],共5462个槽位;

2号分片: [10924,16383],共5460个槽位.

当要新增一个分片时: 只需要从0号,1号和2号 分片上取走一些槽位放到3号分片上,保证槽位尽量均匀分布到不同的分片上即可.

这里有两个问题:

1.槽位一共有16384个,那么redis集群最多只能有16384个分片吗?

当出现16384这么多分片时,就无法保证每个分片上的数据的均匀性了.

我们分片包含多个槽位时,可以认为每个分片上包含的key的数量是相当的;当分片上的槽位非常少的时候,就无法直观反映key的数目了.(有的槽位上的key非常多,有的非常少)

redis官方建议做多使用1000个分片. 当使用的分片过于多的时候,整个数据服务器的集群是非常大的,可用性就难以估量了.

2.为什么槽位设置的是16384个?

节点之间通过"心跳包"进行通信,心跳包中包含了该节点持有哪些槽位,使用位图这样的数据结构来表示16384个槽位,这个位图占用2kb的空间,若这个数太大了,就要占用更大的存储空间,且节点间发送心跳包是周期性的,非常频繁,会占用更大的网络带宽.

另外,redis集群建议使用不超过1000个分片,16384对于1000个分片来说是够用的,也不会占用较大的空间, 很合适.

下一篇文章就要搭建redis集群了.

http://www.dtcms.com/a/273222.html

相关文章:

  • Python练习(1)Python基础类型操作语法实战:20道实战题解与案例分析(上)
  • 《一起出发,“春”不“晚”》特别行动踏梦武当,探寻新春奇境
  • 教育领域AI教师培训计划及相关行业动态的综合简报
  • CVPR2022——RepLKNet模型有效感受野的热图可视化
  • Java Stream流:高效数据处理全解析
  • RV1126平台(Buildroot Linux)+ SunplusIT SPCA2688 USB摄像头 RTSP推流全流程复盘与问题解决记录
  • LabelImg标注工具详解与使用教程
  • SQL进阶:自连接的用法
  • 数字电子时钟——数字电路课设
  • 存在两个cuda环境,在conda中切换到另一个
  • vue3中ref和reactive的使用、优化
  • ABP vNext + OpenIddict:多租户授权中心
  • 二分查找篇——搜索旋转排序数组【LeetCode】两次二分查找
  • PPT 倒计时工具:把控节奏,掌握时间,超简单超实用让演示游刃有余
  • linux的DNS域名解析服务
  • Python操作redis数据库:终端下载安装命令、redis关键特性说明、redis的数据类型、redis的连接两种方式
  • 模块三:现代C++工程实践(4篇)第三篇《C++与系统编程:Linux内核模块开发入门》
  • 一个编辑功能所引发的一场知识探索学习之旅(JavaScript、HTML)
  • 笔记:CMakeLists基础语法
  • 在Zabbix 7 中配置对Nginx的监控
  • 外呼如何提高接通率
  • Rail开发日志_2
  • burpsuite记录
  • 深入理解oracle ADG和RAC
  • kotlin中集合的用法
  • kotlin中withContext,async,launch几种异步的区别
  • 【Python练习】035. 编写一个函数,实现简单的文本搜索功能
  • CPU调度调度算法
  • 低功耗小尺寸的空间入侵监测报警设备的市场需求方向
  • 【Python常见问题】【路径】路径总是有问题?深度剖析