【Redis】Redis高并发高可用(集群方案)

Redis集群

Redis Cluster是Redis的分布式解决方案,在3.0版本正式推出,有效地解决了Redis分布式方面的需求。当遇到单机内存、并发、流量等瓶颈时,可以采用Cluster架构方案达到负载均衡的目的。之前,Redis分布式方案一般有两种:

1、客户端分区方案,优点是分区逻辑可控,缺点是需要自己处理数据路由、高可用、故障转移等问题。

2、代理方案,优点是简化客户端分布式逻辑和升级维护便利,缺点是加重架构部署复杂度和性能损耗。

现在官方为我们提供了专有的集群方案:Redis Cluster,它非常优雅地解决了Redis集群方面的问题,因此理解应用好 Redis Cluster将极大地解放我们使用分布式Redis 的工作量。

集群前置知识

数据分布理论

        分布式数据库首先要解决把整个数据集按照分区规则映射到多个节点的问题,即把数据集划分到多个节点上,每个节点负责整体数据的一个子集。

        需要重点关注的是数据分区规则。常见的分区规则有哈希分区和顺序分区两种,哈希分区离散度好、数据分布业务无关、无法顺序访问,顺序分区离散度易倾斜、数据分布业务相关、可顺序访问。

节点取余分区

使用特定的数据,如Redis的键或用户ID,再根据节点数量N使用公式: hash(key)%N计算出哈希值,用来决定数据映射到哪一个节点上。这种方案存在一个问题:当节点数量变化时,如扩容或收缩节点,数据节点映射关系需要重新计算,会导致数据的重新迁移。

这种方式的突出优点是简单性,常用于数据库的分库分表规则,一般采用预分区的方式,提前根据数据量规划好分区数,比如划分为512或1024张表,保证可支撑未来一段时间的数据量,再根据负载情况将表迁移到其他数据库中。扩容时通常采用翻倍扩容,避免数据映射全部被打乱导致全量迁移的情况,如图10-2所示。

一致性哈希分区

一致性哈希分区( Distributed Hash Table)实现思路是为系统中每个节点分配一个 token,范围一般在0~23,这些token构成一个哈希环。数据读写执行节点查找操作时,先根据key计算hash值,然后顺时针找到第一个大于等于该哈希值的token节点。例如:

集群中有三个节点(Node1、Node2、Node3),五个键(key1、key2、key3、key4、key5),其路由规则为:

image.png

当集群中增加节点时,比如当在Node2和Node3之间增加了一个节点Node4,此时再访问节点key4时,不能在Node4中命中,更一般的,介于Node2和Node4之间的key均失效,这样的失效方式太过于“集中”和“暴力”,更好的方式应该是“平滑”和“分散”地失效。

image.png

这种方式相比节点取余最大的好处在于加入和删除节点只影响哈希环中相邻的节点,对其他节点无影响。但一致性哈希分区存在几个问题:

1、当使用少量节点时,节点变化将大范围影响哈希环中数据映射,因此这种方式不适合少量数据节点的分布式方案。

2、增加节点只能对下一个相邻节点有比较好的负载分担效果,例如上图中增加了节点Node4只能够对Node3分担部分负载,对集群中其他的节点基本没有起到负载分担的效果;类似地,删除节点会导致下一个相邻节点负载增加,而其他节点却不能有效分担负载压力。

正因为一致性哈希分区的这些缺点,一些分布式系统采用虚拟槽对一致性哈希进行改进,比如虚拟一致性哈希分区。

虚拟一致性哈希分区

image.png

为了在增删节点的时候,各节点能够保持动态的均衡,将每个真实节点虚拟出若干个虚拟节点,再将这些虚拟节点随机映射到环上。此时每个真实节点不再映射到环上,真实节点只是用来存储键值对,它负责接应各自的一组环上虚拟节点。当对键值对进行存取路由时,首先路由到虚拟节点上,再由虚拟节点找到真实的节点。

如下图所示,三个节点真实节点:Node1、Node2和Node3,每个真实节点虚拟出三个虚拟节点:X#V1、X#V2和X#V3,这样每个真实节点所负责的hash空间不再是连续的一段,而是分散在环上的各处,这样就可以将局部的压力均衡到不同的节点,虚拟节点越多,分散性越好,理论上负载就越倾向均匀。

虚拟槽分区

Redis则是利用了虚拟槽分区,可以算上面虚拟一致性哈希分区的变种,它使用分散度良好的哈希函数把所有数据映射到一个固定范围的整数集合中,整数定义为槽( slot)。这个范围一般远远大于节点数,比如RedisCluster槽范围是0 ~16383。槽是集群内数据管理和迁移的基本单位。采用大范围槽的主要目的是为了方便数据拆分和集群扩展。每个节点会负责一定数量的槽。

比如集群有3个节点,则每个节点平均大约负责5460个槽。由于采用高质量的哈希算法,每个槽所映射的数据通常比较均匀,将数据平均划分到5个节点进行数据分区。Redis Cluster就是采用虚拟槽分区,下面就介绍Redis 数据分区方法。

image.png

为什么槽的范围是0 ~16383?

为什么槽的范围是0 ~16383,也就是说槽的个数在16384个?redis的作者在github上有个回答:why redis-cluster use 16384 slots? · Issue #2576 · redis/redis · GitHub

image.png

这个意思是:

Redis集群中,在握手成功后,连个节点之间会定期发送ping/pong消息,交换数据信息,集群中节点数量越多,消息体内容越大,比如说10个节点的状态信息约1kb,同时redis集群内节点,每秒都在发ping消息。例如,一个总节点数为200的Redis集群,默认情况下,这时ping/pong消息占用带宽达到25M。

那么如果槽位为65536,发送心跳信息的消息头达8k,发送的心跳包过于庞大,非常浪费带宽。

其次redis的集群主节点数量基本不可能超过1000个。集群节点越多,心跳包的消息体内携带的数据越多。如果节点过1000个,也会导致网络拥堵。因此redis作者,不建议redis cluster节点数量超过1000个。

那么,对于节点数在1000以内的redis cluster集群,16384个槽位够用了,可以以确保每个 master 有足够的插槽,没有必要拓展到65536个。

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

所以Redis作者决定取16384个槽,作为一个比较好的设计权衡。

Redis数据分区

Redis Cluser采用虚拟槽分区,所有的键根据哈希函数映射到0 ~16383整数槽内,计算公式:slot=CRC16(key) &16383。每一个节点负责维护―部分槽以及槽所映射的键值数据。

image.png

image.png

Redis 虚拟槽分区的特点

1、解耦数据和节点之间的关系,简化了节点扩容和收缩难度。

2、节点自身维护槽的映射关系,不需要客户端或者代理服务维护槽分区元数据。口支持节点、槽、键之间的映射查询,用于数据路由、在线伸缩等场景。

3、数据分区是分布式存储的核心,理解和灵活运用数据分区规则对于掌握Redis Cluster非常有帮助。

集群功能限制

Redis集群相对单机在功能上存在一些限制,需要开发人员提前了解,在使用时做好规避。限制如下:

1、 key批量操作支持有限。如mset、mget,目前只支持具有相同slot值的key执行批量操作。对于映射为不同slot值的key由于执行mget、mget等操作可能存在于多个节点上因此不被支持。

2、key事务操作支持有限。同理只支持多key在同一节点上的事务操作,当多个key分布在不同的节点上时无法使用事务功能。

3、key作为数据分区的最小粒度,因此不能将一个大的键值对象如hash、list等映射到不同的节点。

4、不支持多数据库空间。单机下的Redis可以支持16个数据库,集群模式下只能使用一个数据库空间,即 db 0。

5、复制结构只支持一层,从节点只能复制主节点,不支持嵌套树状复制结构。

搭建集群

介绍完Redis集群分区规则之后,下面我们开始搭建Redis集群。搭建集群有几种方式:

1)依照Redis 协议手工搭建,使用cluster meet、cluster addslots、cluster replicate命令。

2)5.0之前使用由ruby语言编写的redis-trib.rb,在使用前需要安装ruby语言环境。

3)5.0及其之后redis摒弃了redis-trib.rb,将搭建集群的功能合并到了redis-cli。

我们简单点,采用第三种方式搭建。集群中至少应该有奇数个节点,所以至少有三个节点,官方推荐三主三从的配置方式,我们就来搭建一个三主三从的集群。

节点配置

我们现在规定,主节点的端口为6900、6901、6902,从节点的端口为6930、6931、6932。

首先需要配置节点的conf文件,这个比较统一,所有的节点的配置文件都是类似的,我们以端口为6900的节点举例:

--javascripttypescriptbashsqljsonhtmlcssccppjavarubypythongorustmarkdown

port 6900# 这个部分是为了在一台服务上启动多台Redis服务,相关的资源要改
pidfile /var/run/redis_6900.pid
logfile "/home/lijin/redis/redis/log/6900.log"
dir "/hom

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

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

相关文章

2024 年甘肃省职业院校技能大赛中职组 电子与信息类“网络安全”赛项竞赛样题-C卷

2024 年甘肃省职业院校技能大赛中职组 电子与信息类“网络安全”赛项竞赛样题-C卷 2024 年甘肃省职业院校技能大赛中职组 电子与信息类“网络安全”赛项竞赛样题-C卷A模块基础设施设置/安全加固(200分)A 模块基础设施设置/安全加固(200 分&am…

java+springboot停车场小区车库租赁预订系统ssm+jsp

该平台为客户和业主提供等信息服务平台的运营方,管理方,如何通过车库平台建立实现优化管理的方法提供参考。能够实现在一个相对广阔的地域内(例如一座城市)的多个停车场的随意停车。管理平台会统一调度车位资源,自动进行交易结算。…

密码学概论之基本概念

本人信息安全专业,大三,为着将来考研做准备,打算按照自己目前的理解给大家唠唠密码学。 这个专栏我将从以下七个章节来聊聊密码学,若有不当之处,敬请指出。 • 密码学概论 • 流密码 • 分组密码 • 公钥密码 •…

Hdoop学习笔记(HDP)-Part.13 安装Ranger

十三、安装Ranger 1.安装服务 (1)Choose Services (2)Assign Masters (3)Assign Slaves and Clients 选择不安装Ranger Tagsync (4)Customize Services 设置RANGER ADMIN DB FLAVOR:选择MySQL,依据ambari使用的数据库来定 Ranger DB name&#xff…

16、什么是损失函数

上一节介绍了训练的过程,一个模型在训练的过程中,每一轮训练数据计算到到最后一层时,都会输出本轮的预测值,那么如何将本轮的预测值与标签中的真实值进行对比呢? 这就要用到损失函数(Loss function)。 什么是损失函数 损失函数是用来衡量模型预测结果与真实标签(grou…

ansible模块

目录 一、ansible的command模块 1.ad-hoc 2.playbook 3.command模块 二、ansible的shell模块 1.shell模块帮助 2.shell模块支持的参数和解释 3.简单试验 4.批量远程执行脚本 三、script模块 1.script模块帮助 2.shell模块支持的参数和解释 3.实践 四、ansible文件…

Spring AOP 代码案例

目录 AOP组成 通知的具体方法类型 引入Spring AOP依赖 定义AOP层 UserController Postman测试 AOP工作流程 AOP组成 切面 : 切⾯(Aspect)由切点(Pointcut)和通知(Advice)组成,它既包含了…

搭建nfs文件目录共享

搭建nfs文件目录共享 一、简介 NFS,英文全称是Network File System,中文全称是网络文件系统,是FreeBSD支持的文件系统中的一种,它允许网络中的计算机之间通过TCP/IP网络共享资源,在NFS应用中,本地NFS的客…

如何选择 Facebook 代理?

Facebook上从事业务推广、广告或资料推广以及群组的用户需要高质量且可靠的代理。使用代理,用户可以在账号被封锁的情况下访问自己的资料,同时与多人进行即时通信,并能够: 自动发送邀请参加各种活动; 通过特殊的机器人…

2022年高校大数据挑战赛A题工业机械设备故障预测求解全过程论文及程序

2022年高校大数据挑战赛 A题 工业机械设备故障预测 原题再现: 制造业是国民经济的主体,近十年来,嫦娥探月、祝融探火、北斗组网,一大批重大标志性创新成果引领中国制造业不断攀上新高度。作为制造业的核心,机械设备在…

经典神经网络——VGGNet模型论文详解及代码复现

论文地址:1409.1556.pdf。 (arxiv.org);1409.1556.pdf (arxiv.org) 项目地址:Kaggle Code 一、背景 ImageNet Large Scale Visual Recognition Challenge 是李飞飞等人于2010年创办的图像识别挑战赛,自2010起连续举办8年&#xf…

C/C++ 内存管理(1)

文章目录 C/C 内存划分静态和动态内存C语言的动态内存分配函数mallocfreecallocrealloc 常见内存使用错误 C/C 内存划分 栈区(stack):在执行函数时,函数内局部变量的存储单元都可以在栈上创建,函数执行结 束时这些存储…

【数据结构】初识排序 直接插入排序

初识排序 & 直接插入排序 🐟排序在现实中的应用🐟排序的概念🐟常见的排序算法🐟直接插入排序💦举例--直接插入排序在现实种的应用💦单趟直接插入排序讲解💦直接插入排序算法 🐟排…

应用于智慧零售的AI边缘计算盒子+AI算法软硬一体化方案

中国是世界上最大的消费市场,零售行业拥有极大的发展潜力,阿里、腾讯两大互联网巨头正在加紧、加大布局; 信迈智慧零售方案可涵盖快消行业、服饰行业、餐饮行业、酒店行业、美家行业、消费电子行业、新零售商行业、服饰连锁、大卖场/商超、百…

fastmock如何判断头信息headers中的属性值

fastmock可以快速提供后端接口的ajax服务。 那么,如何判断头信息headers中的属性值呢? 可以通过function中的参数_req可以获得headers中的属性值,比如 User-Agent,由于User-Agent属性带有特殊符号,因此使用[]方式而不…

生成式 AI 与数据融合:亚马逊云科技的前沿探索与应用

目录 前言1 生成式AI和数据2 亚马逊云科技的AI创新2.1 数据与生成式 AI 的协同创新2.2 多模态融合与创新驱动2.3 构建创新平台与工作智能助手2.4 数据整合与安全保障 3 生成式AI结合企业数据的典型技术Amazon Q4 展望未来 授权声明:本篇文章授权活动官方亚马逊云科技…

经典神经网络——ResNet模型论文详解及代码复现

论文地址:Deep Residual Learning for Image Recognition (thecvf.com) PyTorch官方代码实现:vision/torchvision/models/resnet.py at main pytorch/vision (github.com) B站讲解: 【精读AI论文】ResNet深度残差网络_哔哩哔哩_bilibili …

NXP iMX8M Plus Qt5 双屏显示

By Toradex胡珊逢 简介 双屏显示在显示设备中有着广泛的应用,可以面向不同群体展示特定内容。文章接下来将使用 Verdin iMX8M Plus 的 Arm 计算机模块演示如何方便地在 Toradex 的 Linux BSP 上实现在两个屏幕上显示独立的 Qt 应用。 硬件介绍 Verdin iMX8M Plu…

C++的explicit和隐式转换

隐式转换是指在某些情况下,编译器会自动进行类型转换,将一种类型的值转换为另一种类型,以满足表达式的要求。这种转换是隐式进行的,不需要显式地调用转换函数或构造函数。 int a 5; double b a; // int 到 double 的隐式转换上…

支持Upsert、Kafka Connector、集成Airbyte,Milvus助力高效数据流处理

Milvus 已支持 Upsert、 Kafka Connector、Airbyte! 在上周的文章中《登陆 Azure、发布新版本……Zilliz 昨夜今晨发生了什么?》,我们已经透露过 Milvus(Zilliz Cloud)为提高数据流处理效率, 先后支持了 Up…