系列十四、Redis的集群(一)

一、是什么

1.1、概述

        由于数据量过大,单个master-slave模式难以承担,当出现master节点故障的一瞬间,哨兵重新选举新的master节点之前,这一小段时间将会导致Redis服务不可用,因此需要对多个master-slave主从复制集进行集群,形成水平扩展,每个master-slave主从复制只负责存储整个数据集的一部分,这就是Redis的集群,其作用是提供在多个Redis节点之间共享数据的程序集。

1.2、演化

1.3、一句话

        Redis集群是一个提供在多个Redis节点间共享数据的程序集,Redis集群可以支持多个master。

二、集群架构图

三、功能

(1)Redis集群支持多个master,每个master又可以挂载多个slave;

  • 读写分离
  • 支持数据的高可用
  • 支持海量数据的读写存储操作

(2)由于Cluster自带Sentinel的故障转移机制,内置了高可用的支持,无需再去使用哨兵功能

(3)客户端与Redis的节点连接,不再需要连接集群中的所有节点,只需要任意连接集群中的一个可用节点即可;

(4)槽位slot负责分配到各个物理服务节点,由对应的集群来负责维护节点、插槽和数据之间的关系;

四、集群算法&分片&槽位slot

4.1、槽位slot

        Redis集群没有使用一致性hash,而是引入了哈希槽的概念。Redis集群中有16384个哈希槽,每个Key通过CRC16算法校验后对16384取模,进而决定要存储的数据放在哪个槽位中,集群中的每一个节点负责一部分hash槽,例如:当前集群有3个节点,那么:

4.2、CRC16算法的特点

  • 对集群模式下的所有key进行CRC16计算,计算的结果始终在0-16383之间;
  • 对客户端的key进行CRC16计算时,同一个key经过多次CRC16计算的结果始终一致;
  • 对客户端的不同key进行CRC16算法,计算的结果会出现不同的key计算结果一致;

4.3、分片

4.3.1、概述

        使用Redis集群时,我们会将存储的数据分散到多台Redis机器上,这即被称为分片,换言之,集群中的每个Redis实例都被认为是整个数据集的一个分片。

4.3.2、如何找到给定key的分片

        为了找到给定key的分片,我们对key进行CRC16(key)算法处理,并通过对总分片数量(16384)取模,然后使用确定性哈希函数这意味着给定的key将多次始终映射到同一个分片,我们据此可以推断将来读取key所在的分片。

4.4、分片 + 槽位的优点

        方便扩容缩容和数据分片查找。这种结构很容易的添加或者删除节点,比如如果我想添加一个节点D,我需要从节点A、B、C上得到部分槽位给到D,如果我想移除节点A,那么需要先将A中的槽位移到B和C上,然后将没有任何槽位的A节点从集群中移除即可,由于从一个节点将哈希槽移动到另外一个节点的过程中并不会停止服务,所以无论添加节点还是删除节点或者改变某个节点的哈希槽数量都不会造成集群不可用的状态。

4.5、槽位映射业界解决方案@哈希取余分区

4.5.1、概述

        2亿条数据就是2亿个k:v,我们单机不行,必须要分布式多机,假设有3台机器构成一个集群,用户每次读写操作都是根据公式:hash(key)%N(机器数量),计算出哈希值,用来决定将数据映射到哪一个节点上。

4.5.2、优点

        简单粗暴,直接有效。只需要预估好数据,规划好节点,例如:3台、8台、10台,就能保证一段时间的数据支撑。使用hash算法让固定的一部分请求落到同一台机器上,这样每台机器固定处理一部分请求(并维护这些请求信息),起到负载均衡+分而治之的作用。

4.5.3、缺点

        原来规划好的节点,进行扩容或者缩容就比较麻烦了,不管扩容还是缩容,每次数据变动导致节点有变动,映射关系就需要重新进行计算,在服务器的数量固定不变时没有问题,如果需要弹性扩容或者故障停机的情况下,原来的取模公式就会发生变化:hash(key)/3 ===> hash(key)/?,此时地址经过取余运算的结果将会发生很大变化,根据公式获取的服务器也会变得不可控。某个Redis机器宕机了,由于机器的数量发生变化,会导致hash取余的全部数据重新洗牌。

4.6、槽位映射业界解决方案@一致性哈希算法分区

4.6.1、概述

        一致性哈希算法是1997年由麻省理工学院提出,设计目的是为了解决分布式缓存数据变动和映射问题,当某个机器宕机了,分母数量改变了,自然余数不是预期结果了。

4.6.2、作用

        当服务器个数发生变化时,尽量减少影响客户端到服务器的映射关系。

4.6.3、三大步骤

  • 算法构建一致性哈希环

        

  • 服务器IP节点映射

  • key落到服务器的落键规则

         

4.6.4、优点

容错性

扩展性 

4.6.5、缺点

4.6.6、小总结

    为了在节点数目发生改变时尽可能少的迁移数据,将所有的存储节点排列在首尾相接的Hash环上,每个key在计算Hash后会顺时针找到临近的存储节点进行存放。而当有节点加入或退出时仅影响该节点在Hash环上顺时针相邻的后续节点。
优点:加入和删除节点只影响哈希环中顺时针方向的相邻的节点,对其他节点无影响。
缺点:数据的分布和节点的位置有关,因为这些节点不是均匀的分布在哈希环上的,所以数据在进行存储时达不到均匀分布的效果。

4.7、槽位映射业界解决方案@哈希槽分区

4.7.1、为什么会出现

        一致性哈希算法存在数据倾斜的问题。哈希槽实质上就是一个数组[0-2^14-1],形成hash slot空间。

4.7.2、解决了什么问题

        解决均匀分配的问题,在数据和节点之间又增加了一层,被增加的这层称为哈希槽(slot),用于管理数据和节点之间的关系,现在就相当于节点上放的是槽,槽里边放的是数据。

槽解决的是粒度的问题,相当于把粒度变大了,这样便于数据的移动。哈希解决的是映射的问题,使用key的哈希值来计算所在槽,便于数据分配。

4.7.3、有多少个哈希槽

        一个集群只能有16384个槽,区间为[0-2^14-1],这些槽会分配给集群中的所有主节点,分配策略没有要求。集群会记录节点和槽的对应关系,解决了节点和槽的关系后,接下来就需要对key求hash值,然后对16384取模,余数是多少,key就落到对应的槽里,HSAH_SLOT = CRC16(key)%16384。以槽位单位移动数据,因为槽的数目是固定的,处理起来比较容易,这样数据移动的问题就解决了。

4.7.4、哈希槽的计算

五、经典面试题

5.1、为什么Redis集群的最大槽数是16384个?

        Redis集群并没有使用一致性hash,而是引入了哈希槽的概念,Redis集群有16384个哈希槽,每个key通过CRC16校验后对16384取模来决定放在哪个槽里面,集群的每个节点负责维护一部分hash槽,所有的节点维护的哈希槽共同组成一个完整的哈希槽。但是为什么哈希槽的数量是16384(2^14)个,而不是其他的值呢?CRC算法产生的哈希值有16bit,该算法可以产生2^16即65536个值,换句话说值是分布在0-65535之间,有更大的65536不用,为什么只用16384就够?作者在取模的时候,为什么不%65536,而选择%16384?HASH_SLOT = CRC16(key)%65536为什么没启用?

https://github.com/redis/redis/issues/2576

(1)如果槽位为65536,发送的心跳信息的消息头达8KB,发送的心跳包过于庞大

        在消息头中最占用空间的是myslots[CLUSTER_SLOTS/8],当槽位为65536时,这块的大小为:65536/8/1024=8KB

                                                                                                       当槽位为16384时,这块的大小为:16384/8/1024=2KB

由于Redis节点每秒钟需要发送一定数量的PING消息作为心跳包,如果槽位为65536,这个PING消息的消息头太大了,浪费带宽。

(2)Redis集群的主节点数量基本不可能超过1000个

        集群节点越多,心跳包的消息体内携带的数据越多,如果节点超过1000个,将会导致网络拥堵。因此Redis作者不建议Redis Cluster节点的数量不超过1000个,那么对于节点数量在1000以内的Redis Cluster集群,16384个槽位足够用了,没有必要扩展到65536个。

(3)槽位越小,节点少的情况下,压缩比高,容易传输

        Redis主节点的配置信息中,它负责的哈希槽是通过一张bitmap的形式来保存的,在传输过程中会对bitmap进行压缩,但是如果bitmap的填充率slots/N很高的话(N表示节点数),bitmap的压缩率就很低,如果节点数很少,而哈希槽的数量很多的话,bitmap的压缩率就很高。

5.2、缺点

        Redis集群不保证强一致性。这意味着在特定条件下,Redis集群可能会丢弃掉一些被系统收到的写入命令。

六、集群细节

  • 所有的Redis节点彼此互联(ping-pong机制),内部使用二进制协议优化传输速度和带宽;
  • 节点的fail是通过集群中超过半数的节点检测失效时才生效;
  • 客户端与Redis节点直连,不需要中间Proxy层,客户端不需要连接集群中的所有节点,连接集群中任意一个可用的节点即可;
  • redis-cluster把所有的物理节点映射到[0-16383]个slot上,cluster负责维护node《===》slot《===》value

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

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

相关文章

Kafka与MySQL的组合使用

根据上面给出的student表,编写Python程序完成如下操作: (1)读取student表的数据内容,将其转为JSON格式,发送给Kafka; 创建Student表的SQL语句如下: create table student( sno ch…

设计模式-综合应用(一)

介绍 使用jQuery做一个模拟购物车的示例 用到的设计模式 工厂模式 单例模式装饰器模式 观察者模式状态模式 模板方法模式 代理模式 UML类图

ChatGPT(1):ChatGPT初识

1 ChatGPT原理 ChatGPT 是基于 GPT-3.5 架构的一个大型语言模型,它的工作原理涵盖了深度学习和自然语言处理技术。以下是 ChatGPT 的工作原理的一些关键要点: 神经网络架构:ChatGPT 的核心是一个深度神经网络,采用了变种的 Tran…

网络协议--ICMP:Internet控制报文协议

6.1 引言 ICMP经常被认为是IP层的一个组成部分。它传递差错报文以及其他需要注意的信息。ICMP报文通常被IP层或更高层协议(TCP或UDP)使用。一些ICMP报文把差错报文返回给用户进程。 ICMP报文是在IP数据报内部被传输的,如图6-1所示。 ICMP…

GRASP 、SOLID 与 GoF 设计模式

一、GRASP GRASP:通用职责分配软件设计模式(General Responsibility Assignment Software Patterns),其主要思想是基于单一职责设计软件对象。 思考软件对象设计以及大型构件的流行方式是,考虑其职责、角色和协作。这是被称为职责驱动设计&a…

基于CNN实现谣言检测 - python 深度学习 机器学习 计算机竞赛

文章目录 1 前言1.1 背景 2 数据集3 实现过程4 CNN网络实现5 模型训练部分6 模型评估7 预测结果8 最后 1 前言 🔥 优质竞赛项目系列,今天要分享的是 基于CNN实现谣言检测 该项目较为新颖,适合作为竞赛课题方向,学长非常推荐&am…

高速DSP系统设计参考指南(七)电磁干扰基础

(七)电磁干扰基础 1.概述2.EMI概述3.数字信号4.电流环路5.电源6.传输线7.电源层和地层8. 减少电磁干扰经验法则9.总结 1.概述 高速DSP系统中的辐射是由通过印刷电路板走线传播的快速开关电流和电压引起的。随着DSP速度的提高,印刷电路板走线…

C++ 字符串编码转换封装函数,UTF-8编码与本地编码互转

简介 字符串编码转换封装函数,UTF-8编码与本地编码互转。 中文乱码的解决方法 有时候我们会遇到乱码的字符串,比如: 古文码 可能是用GBK方式读取UTF-8编码的中文导致的,用下面的Utf8ToLocal(string str)函数转换一下就可以了。…

017 基于Spring Boot的食堂管理系统

部分代码地址: https://github.com/XinChennn/xc017-stglxt 基于Spring Boot的食堂管理系统 项目介绍 本项目是基于Java的管理系统。采用前后端分离开发。前端基于bootstrap框架实现,后端使用Java语言开发,技术栈包括但不限于SpringBoot、…

Filter与Listener(过滤器与监听器)

1.Filter 1.过滤器概述 过滤器——Filter,它是JavaWeb三大组件之一。另外两个是Servlet和Listener 它可以对web应用中的所有资源进行拦截,并且在拦截之后进行一些特殊的操作 在程序中访问服务器资源时,当一个请求到来,服务器首…

unity操作_碰撞器 c#

碰撞器Collider 在场景中选择一个物体Cube 观察检查器Inspector 自带Cube会默认挂载盒子碰撞器Box Colilider 增加组件可以增加更多中碰撞器 Edit Collider 编辑碰撞器形状 Is Trigger选项 Is Trigger :是否是触发器,如果启用此属性 则该碰撞体将用于触…

数据挖掘(6)聚类分析

一、什么是聚类分析 1.1概述 无指导的,数据集中类别未知类的特征: 类不是事先给定的,而是根据数据的相似性、距离划分的聚类的数目和结构都没有事先假定。挖掘有价值的客户: 找到客户的黄金客户ATM的安装位置 1.2区别 二、距离和相似系数 …

UITesting 界面测试

1. 创建界面测试视图 UITestingBootcampView.swift import SwiftUI/// 界面测试 ViewModel class UITestingBootcampViewModel: ObservableObject{let placeholderText: String "Add name here..."Published var textFiledText: String ""Published var…

2023年中国一次性医用内窥镜市场发展现状分析:相关产品进入上市高峰期[图]

基于对减少交叉感染风险和维护成本的需求等因素,一种新兴的、耗材化的一次性内窥镜可以避免因重复使用产品而导致的感染问题和高额的清洗消毒费用,从而提高患者的安全性并帮助医疗机构节省运营成本。 一次性和可重复使用医用内窥镜特点对比 资料来源&am…

Android 指定有线网或Wifi进行网络请求

Android 指定有线网或Wifi进行网络请求 文章目录 Android 指定有线网或Wifi进行网络请求一、前言:二、指定网络通讯测试1、 窗口命令 ping -I 网络节点 IP2、Java 代码指定特定网络通讯 三、指定特定网络的demo app 开发1、效果图:2、实际测试结果说明&a…

Nginx负载均衡反向代理动静分离

文章目录 nginx负载均衡&反向代理&动静分离环境说明部署动静分离1.主机lnmp部署一个动态页面,在此以discuz论坛系统为例2.主机n1部署两个静态页面访问动、静态页面 配置负载均衡配置反向代理访问测试 nginx负载均衡&反向代理&动静分离 环境 主机名…

【LINUX】1-移植NXP提供的源码

一、在Linux中添加自己的开发板 defconfig配置文件:一个就是imx6ull_alientek_emmc_defconfig默认配置文件 # 复制一份NXP 官方的SDK cd arch/arm/configs cp imx_v7_mfg_defconfig imx_alientek_emmc_defconfig 设备树:imx6ull-alientek-emmc.d…

【Arduino32】PWM控制直流电机速度

硬件准备 震动传感器:1个 红黄绿LED灯:各一个 旋钮电位器:1个 直流电机:1个 1K电阻:1个 220欧电阻:3个 杜邦线:若干 硬件连线 软件程序 const int analogInPin A0;//PWM输入引脚 const…

SpringCloud链路追踪——Spring Cloud Sleuth 和 Zipkin 介绍 Windows 下使用初步

前言 在微服务中,随着服务越来越多,对调用链的分析越来越复杂。如何能够分析调用链,定位微服务中的调用瓶颈,并对其进行解决。 本篇博客介绍springCloud中用到的链路追踪的组件,Spring Cloud Sleuth和Zipkin&#xf…

使用 PyAudio、语音识别、pyttsx3 和 SerpApi 构建简单的基于 CLI 的语音助手

德米特里祖布☀️ 一、介绍 正如您从标题中看到的,这是一个演示项目,显示了一个非常基本的语音助手脚本,可以根据 Google 搜索结果在终端中回答您的问题。 您可以在 GitHub 存储库中找到完整代码:dimitryzub/serpapi-demo-project…