中学网站模板下载,wordpress最热文章,百度一下知道首页,韶关做网站公司前言#xff1a;此篇文章系本人学习过程中记录下来的笔记#xff0c;里面难免会有不少欠缺的地方#xff0c;诚心期待大家多多给予指教。 基础篇#xff1a;
Redis#xff08;一#xff09;Redis#xff08;二#xff09;Redis#xff08;三#xff09;Redis#x… 前言此篇文章系本人学习过程中记录下来的笔记里面难免会有不少欠缺的地方诚心期待大家多多给予指教。 基础篇
Redis一Redis二Redis三Redis四Redis五Redis六 接上期内容上期完成了Redis哨兵模式的学习。下面开始学习Redis集群(非常重点)话不多说直接发车。 一、集群定义
一、什么是集群
集群是由多个相互关联的节点构成的系统架构各节点之间通过协作机制协同运作对外界呈现出统一的整体形态。在Redis集群体系中每个节点均承担着部分数据的存储职责并共同为客户端提供服务以此达成数据的分布式存储与处理功能。 二、redis集群出现的背景
随着互联网应用的快速发展数据量呈爆发式增长单机的Redis在存储容量、读写性能和高可用性等方面逐渐难以满足需求。为了应对这些挑战Redis 集群应运而生它通过将数据分布在多个节点上实现了水平扩展大大提升了数据处理能力。 二、集群功能
数据分片将数据分散存储在多个节点上突破单机存储容量限制。高可用性通过节点间的复制和自动故障转移机制确保集群在部分节点故障时仍然能正常工作。读写分离从节点可以分担读请求提供系统的读性能。水平扩展可以方便地添加或删除节点实现集群的动态伸缩。 三、集群算法
一、Redis集群分区是什么
Redis集群分区是一种将数据分散存储到多个Redis节点的技术目的是实现数据的分布式存储和处理从而提升系统的可扩展性、性能和可用性。通过分区Redis集群可以处理比单个 Redis 实例更大的数据集并且可以并行处理更多的客户端请求。 二、Redis集群槽位是什么
Redis集群槽位Slot是Redis集群中用于管理数据分布的一种逻辑概念。Redis集群共有16384 个槽位编号从 0 到 16383每个键在存储时会通过特定的哈希算法CRC16计算出对应的槽位编号然后根据槽位的分配情况将键值对存储到相应的节点上。 三、Redis集群分区-槽位映射方案
1、哈希取余分区
1.1、定义
根据数据的键值进行哈希计算然后对节点数量取余数根据余数将数据分配到相应的节点。这里所说的 “分区”就是把数据按照这种哈希取余的规则分散到不同的节点上存储实现数据的分布式存储每个节点就相当于一个数据分区。
假设有3台机器构成一个集群用户每次读写操作都是根据公式Hash(key) % N台机器数计算出哈希值用来决定数据映射到那个节点上。 1.2、优劣势
优势算法简单易于实现在节点数量固定时能较好地实现数据分布。使用Hash算法让固定的一部分请求落到同一台服务器上这样每台服务器固定处理一部分请求并维护这些请求的信息起到负载均衡分而治之的作用。
劣势当节点数量发生变化如增加或减少节点时大量数据需要重新计算哈希值并进行迁移会导致数据的重新分布影响系统性能。 1.3、小总结
哈希取余分区适用于节点数量相对稳定的场景在节点动态变化频繁的场景下表现不佳。 2、一致性哈希算法分区
2.1、定义
将哈希值空间组织成一个虚拟的圆环节点和数据都映射到这个圆环上。根据数据的哈希值在圆环上顺时针查找找到的第一个节点就是该数据的存储节点。在这个算法里分区就是数据在虚拟圆环上对应到不同节点的存储区域不同的节点负责存储圆环上特定区间的数据 从而实现数据分区。
实现一致性哈希算法分区三大步骤
1、构建一致哈希环
一致性哈希算法必然有个hash函数并按照算法产生hash值这个算法的所有可能哈希值会构成一个全量集这个集合可以成为一个hash空间[0,2^32-1]这个是一个线性空间但是在算法中我们通过适当的逻辑控制将它首尾相连(0 2^32),这样让它逻辑上形成了一个环形空间。
它也是按照使用取模的方法而一致性Hash算法是对2^32取模简单来说一致性Hash算法将整个哈希值空间组织成一个虚拟的圆环如假设某哈希函数H的值空间为0-2^32-1即哈希值是一个32位无符号整形整个哈希环如下图整个空间按顺时针方向组织圆环的正上方的点代表00点右侧的第一个点代表1以此类推2、3、4、……直到2^32-1也就是说0点左侧的第一个点代表2^32-1 0和2^32-1在零点中方向重合我们把这个由2^32个点组成的圆环称为Hash环。 2、Redis节点IP映射
将各个服务器使用Hash进行一个哈希具体可以选择服务器的IP或主机名作为关键字进行哈希这样每台机器就能确定其在哈希环上的位置。假如4个节点NodeA、B、C、D经过IP地址的哈希函数计算(hash(ip))使用IP地址哈希后在环空间的位置如下 3、key落键规则
当我们需要存储一个kv键值对时首先计算key的hash值hash(key)将这个key使用相同的函数Hash计算出哈希值并确定此数据在环上的位置从此位置沿环顺时针“行走”第一台遇到的服务器就是其应该定位到的服务器并将该键值对存储在该节点上。
如我们有Object A、Object B、Object C、Object D四个数据对象经过哈希计算后在环空间上的位置如下根据一致性Hash算法数据A会被定为到Node A上B被定为到Node B上C被定为到Node C上D被定为到Node D上。 2.2、优劣势
优势①、容错性更高。假设Node C宕机可以看到此时对象A、B、D不会受到影响。一般的在一致性Hash算法中如果一台服务器不可用则受影响的数据仅仅是此服务器到其环空间中前一台服务器即沿着逆时针方向行走遇到的第一台服务器之间数据其它不会受到影响。简单说就是C挂了受到影响的只是B、C之间的数据且这些数据会转移到D进行存储。 ②、扩展性更好。假设需要增加一台节点NodeXX的位置在D和C之间那收到影响的也就是C到X之间的数据重新把C到D的数据录入到X上即可不会导致hash取余全部数据重新洗牌。 劣势会产生数据倾斜问题。一致性Hash算法在服务节点太少时容易因为节点分布不均匀而造成数据倾斜被缓存的对象大部分集中缓存在某一台服务器上问题例如系统中只有两台服务器 2.3、小总结
一致性哈希算法虽然在节点动态变化场景下有优势但在节点数量较少时会造成数据倾斜问题。 3、哈希槽分区
3.1、定义
Redis群将整个键值对空间划分为16384个哈希槽每个节点负责一部分哈希槽。根据数据的键计算出哈希值再映射到相应的哈希槽从而确定数据存储在哪个节点。这里的 “分区” 是基于哈希槽实现的每个哈希槽就是一个数据分区的最小单位 不同节点通过管理不同的哈希槽实现对数据的分区存储。而 “槽位” 就是指这16384个哈希槽中的每一个每个槽位都有唯一编号用于标识和管理数据存储位置。
它的出现就是为了解决一致性哈希算法分区数据倾斜问题。解决均匀分配的问题在数据和节点之间又加入了一层把这层称为哈希槽slot用于管理数据和节点之间的关系现在就相当于节点上放的是槽槽里放的是数据。 槽解决的是粒度问题相当于把粒度变大了这样便于数据移动。哈希解决的是映射问题使用key的哈希值来计算所在的槽便于数据分配。 3.2、优劣势
优势数据分布均匀节点的增加和删除操作相对简单通过哈希槽的迁移来实现数据的重新分布对系统性能影响较小。
劣势实现相对复杂需要额外的机制来管理哈希槽和节点的映射关系。 3.3、小总结
哈希槽分区是Redis集群采用的主要分区方式兼顾了数据分布的均匀性和集群的可扩展性。 四、经典面试题
QRedis 集群有16384个哈希槽每个key通过CRC16校验后对16384取模来决定放置哪个槽集群的每个节点负责一部分hash槽。但为什么哈希槽的数量是163842^14个呢CRC16算法产生的hash值有16bit该算法可以产生2^1665536个值为啥用16384而不用65536呢
ARedis之父的原话why redis-cluster use 16384 slots? · Issue #2576 · redis/redis · GitHub
总结下来有三点
①、心跳包太大了浪费带宽。
在消息头中最占空间的是myslots[CLUSTER_SLOTS/8]。 当槽位为65536时这块的大小是: 65536÷8÷10248kb。
在消息头中最占空间的是myslots[CLUSTER_SLOTS/8]。 当槽位为16384时这块的大小是: 16384÷8÷10242kb。
因为每秒钟redis节点需要发送一定数量的ping消息作为心跳包如果槽位为65536这个ping消息的消息头太大了浪费带宽。 ②、redis集群的主节点不可能超过1000个。
集群节点越多心跳包的消息体内携带的数据越多。如果节点过1000个也会导致网络拥堵。因此redis作者不建议redis cluster节点数量超过1000个。 那么对于节点数在1000以内的redis cluster集群16384个槽位够用了。没有必要拓展到65536个。 ③、槽位越小节点越少压缩比例越高越容易传输。
Redis主节点的配置信息中它所负责的哈希槽是通过一张bitmap的形式来保存的在传输过程中会对bitmap进行压缩但是如果bitmap的填充率slots / N很高的话(N表示节点数)bitmap的压缩率就很低。 如果节点数很少而哈希槽数量很多的话bitmap的压缩率也会很低。 四、集群实操
一、3主3从集群实操
1、3主3从集群搭建
1.1、前提说明
由于硬件关系电脑同时启动6台虚拟机吃不消所以还是三台虚拟机一台虚拟机上启动两个redis服务效果一样滴。
①、架构图
192.168.112.129 》6379、6380在同一台机器上
192.168.112.129 》6381、6382在同一台机器上
192.168.112.129 》6383、6384在同一台机器上 ②、前提准备
为了简洁明了提前按照架构图创建好需要的文件和文件夹。
创建文件夹 创建文件 创建日志目录 1.2、修改配置 bind 0.0.0.0
daemonize yes
protected-mode no
port 改为对应端口
logfile /myredis/cluster/clusterLogs/cluster对应端口.log
pidfile /myredis/cluster对应端口.pid
dir /myredis/cluster
dbfilename dump对应端口.rdb
aof-use-rdb-preamble yes
appendonly yes
appendfilename appendonly对应端口.aof
requirepass 登录密码
masterauth 登录密码# 开启 Redis 集群模式
cluster-enabled yes
# 指定集群配置文件
cluster-config-file nodes-6381.conf
# 设置节点超时时间为 5 秒
cluster-node-timeout 5000 以6379为例其他照着改就行了 1.3、构建关系
①、启动实例
redis-server /myredis/cluster/clusterConfig/redisClusterxxx.conf
分别启动6379、6380、81、82、83、84 ②、构建集群 redis-cli -a 密码 --cluster create --cluster-replicas 1
xxx.xxx.xxx:6379 xxx.xxx.xxx:6380
xxx.xxx.xxx:6381 xxx.xxx.xxx:6382
xxx.xxx.xxx:6383 xxx.xxx.xxx:6384 参数说明
--cluster create表明要创建一个新的Redis 集群。--cluster-replicas用于指定每个主节点对应的从节点数量。1表示为每个主节点分配 1 个从节点。
三台虚拟机都记得临时关闭防火墙 ③、查看集群并检验集群状态
以6379作为切入点查看集群
常用命令
info replication 查看自己节点信息 cluster info 查看集群信息 cluster nodes 查看集群节点关系 1.4、测试集群读写
①、随便设置key Q为啥设置k、k4报错设置k2、k3正常
A不同的键名经过哈希计算后会被映射到不同的哈希槽中而 Redis 集群里每个主节点Master负责一部分哈希槽。所以当客户端连接到某个节点并尝试设置键时如果该节点并非负责这个键对应的哈希槽就可能会设置失败这就导致了部分键设置成功部分键设置失败的情况。对于redis-cli命令行工具你可以在连接时添加-c参数开启集群模式这样客户端会自动处理重定向将命令转发到负责该键的正确节点上。 ②、测试其他实例 其他实例也能获取成功说明集群搭建成功完美收官。 2、集群中主从故障迁移实操
如果在Redis集群中某台Master宕机从机是否会上位先记住目前的节点信息 2.1、模拟集群中的某台Master宕机
手动关闭6379 在6381上查看集群节点信息 slave会上位变成新的Master。 2.2、恢复架构
①、QA
Q1假设当6379故障恢复后它会以什么身份回归呢
A1以slave身份回归。
启动6379恢复前
恢复后 Q2、虽然6379回归了服务也正常但是架构图跟以前不一样了啊
A2可以使用CLUSTER FAILOVER命令还原节点从属关系。 江山是没有那么容易易主滴。 2.3、小总结
通过上述实操得出以下结论
①、在Redis集群中如果Master宕机那么它对应的slave会迅速上位也就是说在Redis集群中默认集成了哨兵模式。
②、Redis集群为CP模式因此集群不保证数据一致性100%一定会有数据丢失情况官网也有说明。 二、集群扩容/容缩实操
1、集群扩容
1.1、需求说明
由于业务量的剧增原本的3主3从的redis集群已经不足以支持现有的业务需求决定新增redis服务来保证业务高可用。
架构图 1.2、扩容实操
①、新启实例
由于硬件问题所以将6385、6386放在6383那台服务器上。 此时6385、86都是Master。 ②、加入集群
将6385做为集群中的新Maste加入到集群中。
redis-cli -a 密码 --cluster add-node
xxx.xxx.xxx.xxx:xxxx xx2.xx2.xx2:xxx2 参数说明
add-node表明要向 Redis 集群中添加一个新节点。xxx.xxx.xxx.xxx:xxxx代表新加入的节点IP和端口号。xx2.xx2.xx2.xx2:xxx2代表集群任意已经存在的IP和端口号
以6379为切入点 6385加入集群成功。 ③、第一次检查集群
redis-cli -a 密码 --cluster check xxx.xxx.xxx.xxx:xxxx
new Master6385确实成功加入集群但是未分配槽号。 ④、为new Master分配槽号
redis-cli -a 密码 --cluster reshard xxx.xxx.xxx.xxx:xxxx
当在redis-cli执行次命令后redis-cli会提示你输入以下信息
要迁移的哈希槽数量输入想要从源节点迁移到目标节点的哈希槽数量。例如如果想迁移 100 个哈希槽就输入100。目标节点 ID指定接收迁移哈希槽的目标节点的 ID(new Master ID)。源节点信息指定要从哪些节点迁移哈希槽。可以选择具体的节点 ID也可以输入all表示从所有节点均匀地迁移哈希槽。 待定槽位分配完毕。 ⑤、第二次检查集群
槽位分配完成。 ⑥、为new Master分配slave
redis-cli -a 密码 --cluster add-node
xxx.xxx.xxx.xxx:xxxx xx2.xx2.xx2.xx2:xxx2
--cluster-slave --cluster-master-id id 参数说明
--cluster add-node向 Redis 集群中添加一个新节点。xxx.xxx.xxx.xxx:xxxx新节点的地址。xx2.xx2.xx2.xx2:xxx2集群中已存在节点的地址。--cluster-slave指定新添加的节点作为从节点slave加入集群--cluster-master-id指定新从节点要复制的主节点的 ID ⑦、第三次检查集群 自此redis集群由以前的3主3从变成了现在的4主4从完美收官。 2、集群容缩
2.1、需求说明
本项目运行稳定业务需求量增速放慢经过评估以前的3主3从足以支撑现有的业务需求打算撤掉部分资源去支持其他项目。
架构图
不一定非得撤去6385、86也可以撤掉其他的。 2.2、缩容实操
①、第一次查看集群
确定要删除的主节点和从节点信息。 ②、删除从节点
redis-cli -a 密码 --cluster del-node xxx.xxx.xxx.xxx:xxxx id 从节点删除成功。 ③、还原槽位
将6385的槽位全部清空交给6379。 后续还有一个输入项选择输入yes即可等待槽位清空完成。 ④、第二次查看集群 6385已经由Master变成了6379的slave。最开始6385就是由6379引荐入集群的 ⑤、删除主节点
redis-cli -a 密码 --cluster del-node xxx.xxx.xxx.xxx:xxxx id 删除6385 6385删除成功。 ⑥、第三次查看集群 自此以前的4主4从变为了3主3从redis集群的容缩完美收官。 五、集群常用操作命令
一、通配符
Q如何解决在同一个slot槽位下的键值无法使用mset、mget等多键操作。 A可以通过{}来定义同一个组的概念使key中{}内相同内容的键值对放到一个slot槽位去对照下图类似k1k2k3都映射为x(也可以是其他字符)自然槽位一样。 二、查看槽位状态
CLUSTER COUNTKEYSINSLOT 0-16383 返回存的个数0代表没存其他则代表存了几个key 三、判断key应该存在那个槽上
CLUSTER KEYSLOT key 六、浅谈CRC16
QRedis集群有16384个哈希槽每个key通过CRC16校验后对16384取模来决定放置哪个槽从文章在开头说到文末但是一直没说CRC16是个什么东西
A不是我不说而是我能力不足java都还没搞明白怎么敢去搞C的东西啊。。下图为CRC16的部分源码有兴趣自己去研究吧。网上cp的(●◡●) 七、总结
Redis集群通过巧妙的集群算法和高效的管理机制实现了数据的分布式存储和处理为大规模数据处理和高并发访问提供了可靠的解决方案。在实际应用中我们需要根据业务需求和场景选择合适的集群算法和配置参数充分发挥 Redis 集群的优势。同时掌握集群的搭建、操作和维护技能能够确保集群的稳定运行和高效工作。 ps努力到底让持续学习成为贯穿一生的坚守。学习笔记持续更新中。。。。