Redis系列-4 Redis集群介绍

Redis集群

Redis提供了持久化能力,保证了重启不会丢失数据;但Redis重启至完全恢复期间,缓存不可用。另外,对于高并发场景下,单点Redis服务器的性能不能满足吞吐量要求,需要进行横向扩展。此时,可通过搭建Redis集群解决如上两个问题。按照并发量和具体业务的要求,可以部署三种架构的集群:主从模式、哨兵模式、Cluster模式,以下分章节分别进行介绍。

1.Redis主从复制

1.1 流程介绍

主从复制的整体流程可用下图表示:
在这里插入图片描述

具体流程
【1】从节点向主节点发送PSYNC命令(旧版本Redis发送SYNC)建立连接;
【2】主节点收到PSYNC消息后,判断是否需要全量同步:第一次连接时触发全量同步,通过BGSAVE机制将内存快照保存为RDB文件中,并将RDB文件发送给从节点;否则,触发增量同步(如主从节点因网络等原因断开重连);
【3】从节点将数据清空后,将RDB文件的数据写入内存;
【4】此过程中主节点的累积的写操作以AOF文件的形式增量同步至从节点;
【5】之后,主节点的所有写操作,通过AOF文件以增量形式通知从节点。
总之,从节点第一次同步数据以RDB形式进行全量同步,后续以AOF形式进行增量同步。

1.2 环境搭建

在持久化文章中为快速搭建演示环境,使用了docker方式安装Redis;
本文中,为了方便搭建集群,使用二进制的方式运行Redis.

本地安装Redis:

#下载和安装Redis
wget http://download.redis.io/releases/redis-5.0.4.tar.gz
tar xzf redis-5.0.4.tar.gz
cd redis-5.0.4
make

#启动redis(不指定配置文件时使用根目录下的redis.conf)
src/redis-server

#使用客户端连接
src/redis-cli
redis> set foo bar
OK
redis> get foo
"bar"

#使用客户端关闭redis
redis> shutdown

说明:每运行redis-server一次,会创建一个独立的Redis进程,需要注意使用不同的配置文件,以防止端口冲突。

集群搭建:

搭建如下图所示的主从集群, 包含1个主节点以及两个从节点:主节点监听6001端口,从节点分别监听6002和6003端口。
在这里插入图片描述
step1: 准备redis.conf文件
为每个redis实例准备一份redis.conf文件

#创建测试用例目录
mkdir -p /temp/slaveof/6001
mkdir -p /temp/slaveof/6002
mkdir -p /temp/slaveof/6003

#将redis根目录下的redis.conf复制到测试用例目录下
cp redis.conf /temp/slaveof/6001/
cp redis.conf /temp/slaveof/6002/
cp redis.conf /temp/slaveof/6003/

#修改监听的端口号
sed -i 's/6379/6001/g' /temp/slaveof/6001/redis.conf
sed -i 's/6379/6002/g' /temp/slaveof/6001/redis.conf
sed -i 's/6379/6003/g' /temp/slaveof/6001/redis.conf

step2: 配置主从关系
在从节点6001和6002中执行

slaveof 127.0.0.1 6001

也可以在redis.conf文件中加入slaveof配置.

step3: 启动redis

./redis-server /temp/slaveof/6001/redis.conf
./redis-server /temp/slaveof/6002/redis.conf
./redis-server /temp/slaveof/6003/redis.conf

启动日志如下所示:
主节点6001, 接收6002和6003的连接请求:
在这里插入图片描述
从节点6002, 连接到6001:
在这里插入图片描述
从节点6003, 连接到6001:
在这里插入图片描述
step4: 读写数据

#主节点写入数据
主节点6001:0>set key1 value1
"OK"
主节点6001:0>get key1
"value1"


#从节点读取数据,可以读取写入主节点的数据
从节点6002:0>get key1
"value1"


#从节点写数据,抛出异常
从节点6002:0>set key2 value2
"READONLY You can't write against a read only replica."

说明:主节点可读写,从节点只读;主节点写入的数据,通过redis主从复制机制同步至从节点。

另外,从节点后也可以添加从节点,如下所示:
在这里插入图片描述

只需要将6003节点中redis.conf的slaveof 设置为6002节点,即将"slaveof 127.0.0.1 6001"修改为"slaveof 127.0.0.1 6002".

2.哨兵模式

主从模式的主节点和从节点固定,程序不能自动切换。当主节点宕机时,整个缓存将不可写,直到手动恢复主节点(或者将幸存的从节点设置为主节点)为止。
章节1.2中存在 主节点(6001)和从节点(6002和6003), 如果主节点down机了,可以依次执行如下命令恢复环境:

#不妨将6002设置为主节点
主节点6002:>slaveof no one
主节点6003:>slaveof 127.0.0.1 6002

对于实际场景,显然不能通过手动方式去切换主从节点。哨兵模式的引入为其提供了一个解决方案,主从切换实现自动化。可以推断:哨兵需要具备识别主节点down机,从从节点选取主节点,调整节点的主次状态等三种能力。

2.1 流程介绍

在流程介绍之前,有必须关注一下主观离线和客观离线以及sentinel.conf(哨兵配置文件)中的配置项。
主观离线和客观离线:
哨兵与Redis主/从节点之间通过心跳保活,当哨兵发现某个节点超时未发心跳消息,认为这个节点离线,称为主观离线(主观怀疑,可能是网络问题,也可能离线了);此哨兵会询问其他哨兵该节点的状态信息,当足够数量的哨兵都主观认为Redis节点离线时,Redis客观离线(确实离线)。

配置项:
[1] 配置监听的主节点

sentinel monitor <master-name> <ip> <port> <quorum>

master-name表示主节点名称-自定义; ip和port表示主节点的ip和端口;quorum为主观离线转转客观离线的标准。如sentinel monitor mymaster 127.0.0.1 6379 2表示:哨兵监听主节点(127.0.0.1:6379),当有2个哨兵主观认为主节点离线时,此节点被标记为客观离线。

[2] 配置主观离线时间

 sentinel down-after-milliseconds <master-name> <milliseconds>

milliseconds表示Redis节点的心跳超时时间。当心跳超时后,哨兵认为该节点主观离线。
sentinel down-after-milliseconds mymaster 30000设置超时时间为30s.

[3] 配置通知脚本
当哨兵监听事件发生时,会调用配置的脚本,启动时需要保证该脚本存在。

sentinel notification-script <master-name> <script-path>
sentinel client-reconfig-script <master-name> <script-path>

script-path为脚本的存放路径。配置notification-script时,有节点主观或者客观离线会触发;配置client-reconfig-script时,只有故障转移(主节点替换)时才会触发。
哨兵模式的工作流程如下:
[1] 哨兵启动后,与Redis的主从节点建立心跳连接机制;
[2] 哨兵每秒向Redis节点发送PING心跳消息,等待PONG心跳回复消息;
[3] 当哨兵超时(大于down-after-milliseconds)未收到节点信息时,将该节点标记为主观离线;
[4] 哨兵向其他哨兵发送请求,获取该节点的状态,如果超过quorum数量的哨兵认为该节点离线,将该节点标记为客观离线;
[5] 如果该节点为主节点,触发故障转义流程;
[6] 哨兵间会选举一个leader,用于主导故障转义流程;
[7] 哨兵leader根据条件从从节点中选出主节点A(127.0.0.1 6001);
[8] 将选出的节点设置为主节点(slaveof no one),将其他节点设置为该节点的从节点(slaveof 127.0.0.1 6001);

其中,哨兵leader选择主节点的条件如下:
(1)排除主观离线的节点;
(2)排除优先级(slave-priority)为0的节点;
(3)选择优先级最高的节点;
(4)优先级相同,选择复制偏移量最大的节点(与原master数据重合度更高);

2.2 环境搭建

章节1.2的基础上添加两个哨兵,如下图所示:
![在这

step1: 准备redis.conf文件
为每个哨兵准备一份redis.conf文件

#创建测试用例目录
mkdir -p /temp/sentinel/20001
mkdir -p /temp/sentinel/20002

#将redis根目录下的sentinel.conf复制到测试用例目录下
cp sentinel.conf /temp/sentinel/20001/
cp sentinel.conf /temp/sentinel/20002/

#修改哨兵监听的端口号
sed -i 's/26379/20001/g' /temp/sentinel/20001/sentinel.conf
sed -i 's/26379/20002/g' /temp/sentinel/20002/sentinel.conf

step2:添加哨兵的检测规则

#设置监控的redis主节点的ip、port和quorum(当认为master主节点主观失联的哨兵数超过quorum,主节点客观失联)
sentinel monitor mymaster 127.0.0.1 6001 2

#主节点响应答哨兵的超时时间, 默认30秒
sentinel down-after-milliseconds mymaster 5000

# 故障转移的超时时间(r两次failover的间隔时间)
sentinel failover-timeout mymaster 60000

同时修改工作目录和日志配置:

pidfile "/temp/sentinel/20001/redis-sentinel.pid"
logfile ""
dir "/temp/sentinel/20001/tmp"

step3:启动哨兵程序

./redis-sentinel /temp/sentinel/20001/sentinel.conf
./redis-sentinel /temp/sentinel/20002/sentinel.conf

启动日志如下所示:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-nJEG8tO5-1715419002461)(C:\Users\0216001379\AppData\Roaming\Typora\typora-user-images\1715240740961.png)]

在这里插入图片描述
step4:重启主节点(以检测哨兵的反应)

(1) 通过info replication查看各个节点的状态:

67-6001:0>info replication
"# Replication
role:master
connected_slaves:2
slave0:ip=127.0.0.1,port=6002,state=online,offset=424559,lag=1
slave1:ip=127.0.0.1,port=6003,state=online,offset=424559,lag=1
...
"

67-6002:0>info replication
"# Replication
role:slave
master_host:127.0.0.1
master_port:6001
...
"

67-6003:0>info replication
"# Replication
role:slave
master_host:127.0.0.1
master_port:6001
...
"

此时6001为主节点,6002和6003为从节点。

(2) 手动停止6001节点:

67-6001:0>shutdown

此时,6002和6003报错,连接主节点失败:
在这里插入图片描述
当哨兵检测到6001主节点宕机后,进行节点选举:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Qks0UheI-1715419002461)(C:\Users\0216001379\AppData\Roaming\Typora\typora-user-images\1715242303237.png)]
选举完成后,将结果通知给各节点。此时选择了6003作为主节点, 再次查看6003节点的信息:

67-6003:0>info replication
"# Replication
role:master
connected_slaves:1
slave0:ip=127.0.0.1,port=6002,state=online,offset=459708,lag=0
...
"

3.cluster集群

3.1 流程介绍

支持多个master节点,每个master节点可以有多个slave节点,master可写而slave只读;cluster集群自带故障转移能力,不需要配置哨兵。
没有中心节点,对数据进行分片存储,每个master节点存储不同的数据;当有master节点宕机时,不影响其他节点的读写。
Redis节点通过gossip协议建立集群。
gossip工作原理是节点间的信息交换:不断地信息交换,很快所有节点都会拥有集群的完整信息,如同流言散播。
gossip协议包括meet,ping,pong,fail等消息类型:meet用于加入集群,ping用于心跳和数据交换,pong用于ping和meet的返回消息;fail用于广播节点宕机。
集群内部通过分片机制,每个redis节点负责整体数据的一个子集,数据和节点之间存在映射关系。
因此,在数据和redis节点之间引入了哈希槽的概念:一个集群固定有16384(2^14-1)个槽位,每个Redis节点分配一段槽位范围(slot range),数据(key)经过哈希算法得到一个哈希槽(slot),算法为CRC16(key) % 16384,
从而确定所属节点。
由于每个节点只负责部分slot(数据库子集), 且slot可能发生前移,使得客户端请求变得复杂。
Cluster集群通过重定向机制解决该问题,重定向机制包括两个消息类型:MOVED和ASK。
当客户端将一个数据操作发送给Redis实例时,如果这个数据所在的slot不是由该Redis实例负责,
该实例会返回一个MOVED消息,如下所示:
(error) MOVED 12345 127.0.0.1:6001
表示客户端正在操作的数据的slot是12345,这个槽点在127.0.0.1:6001实例上。

当客户端请求的数据所在的slot正在前移至另一个Redis实例,
此时给客户端响应一个ASk消息,如下所示:
(error) ASK 12345 127.0.0.1:6002
表示客户端正在操作的数据的slot是12345,这个槽点正在前移到127.0.0.1:6002实例上。

另外,客户端自身也会维护一份槽与节点的映射关系,当客户端操作数据时,先计算键的哈希值并根据映射关系找到对应的节点,然后将数据请求发送给对应节点。

3.1 环境搭建

以章节1为基础,搭建一个三主三从的cluster集群。
在这里插入图片描述
step1.准备配置文件
将/temp/slaveof/6001文件夹下的redis.conf配置文件复制6份, 并分别修改端口号为6001-6006:

/temp/cluster/6001/redis.conf 中端口port修改为 6001
/temp/cluster/6002/redis.conf 中端口port修改为 6002
/temp/cluster/6003/redis.conf 中端口port修改为 6003
/temp/cluster/6004/redis.conf 中端口port修改为 6004
/temp/cluster/6005/redis.conf 中端口port修改为 6005
/temp/cluster/6006/redis.conf 中端口port修改为 6006

step2.配置为集群模式
在redis.conf文件中添加配置项:

cluster-enabled yes

step3.启动所有节点

./redis-server /temp/cluster/6001/redis.conf
./redis-server /temp/cluster/6002/redis.conf
./redis-server /temp/cluster/6003/redis.conf
./redis-server /temp/cluster/6004/redis.conf
./redis-server /temp/cluster/6005/redis.conf
./redis-server /temp/cluster/6006/redis.conf

step4.创建集群

./redis-cli --cluster create --cluster-replicas 1 \
127.0.0.1:6001 \
127.0.0.1:6002 \
127.0.0.1:6003 \
127.0.0.1:6004 \
127.0.0.1:6005 \
127.0.0.1:6006

结果如下所示:
在这里插入图片描述
此时,主节点为6001,6002,6003, 对应从节点分别为6005,6006,6004.
step5.查看集群节点状态
使用info replication命令查看6001-6005主从节点的状态。
6001节点:

127.0.0.1:6001> info replication
# Replication
role:master
connected_slaves:1
slave0:ip=127.0.0.1,port=6005,state=online,offset=434,lag=1
master_replid:1b684bf671a34b36f80422b41a39eb887f0c15e0
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:434
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:1
repl_backlog_histlen:434

显示6001为主节点,6005为其从节点。
6005节点:

127.0.0.1:6005> info replication
# Replication
role:slave
master_host:127.0.0.1
master_port:6001
master_link_status:up
master_last_io_seconds_ago:8
master_sync_in_progress:0
slave_repl_offset:546
slave_priority:100
slave_read_only:1
connected_slaves:0
master_replid:1b684bf671a34b36f80422b41a39eb887f0c15e0
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:546
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:1
repl_backlog_histlen:546

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Java基础_Stream流

Java基础_Stream流 Stream流的简单使用Stream流的获取Stream流的中间方法Stream流的终结方法综合练习数字过滤字符串过滤并收集自定义对象过滤并收集 来源Gitee地址 Stream流的简单使用 public class StreamDemo01 {public static void main(String[] args) {/*** 创建集合添加…

【C++ | 拷贝赋值运算符函数】一文了解C++的 拷贝赋值运算符函数

&#x1f601;博客主页&#x1f601;&#xff1a;&#x1f680;https://blog.csdn.net/wkd_007&#x1f680; &#x1f911;博客内容&#x1f911;&#xff1a;&#x1f36d;嵌入式开发、Linux、C语言、C、数据结构、音视频&#x1f36d; ⏰发布时间⏰&#xff1a;2024-06-09 1…

API接口测试工具:jmeter的安装、汉化、Jmeter桌面快捷图标和基本使用

文章目录 测试工具&#xff1a;JmeterJmeter安装和配置Jmeter汉化设置中文语言&#xff1a;永久方式设置中文语言&#xff1a;临时方式 设置Jmeter桌面快捷图标jmeter基本用法Jmeter无法保存测试问题解决 测试工具&#xff1a;Jmeter Jmeter依赖于JDK&#xff0c;所以必须确保…

kafka集成flink api编写教程

1.引入依赖&#xff08;pox.xml&#xff09; <dependencies><dependency><groupId>org.apache.flink</groupId><artifactId>flink-java</artifactId><version>1.13.6</version></dependency><dependency><gro…

C# WPF入门学习主线篇(十六)—— Grid布局容器

C# WPF入门学习主线篇&#xff08;十六&#xff09;—— Grid布局容器 欢迎来到C# WPF入门学习系列的第十六篇。在前几篇文章中&#xff0c;我们已经探讨了 Canvas、StackPanel、WrapPanel 和 DockPanel 布局容器及其使用方法。本篇博客将介绍另一种功能强大且灵活的布局容器—…

MT76X8 RF定频使用方法

一、从下面网址下载QA软件包&#xff0c;然后在WIN系统下安装QA环境。https://download.csdn.net/download/zhouwu_linux/89408573?spm1001.2014.3001.5503 在WINDOWS 7系统下先安装WinPcap_4_1_3.exe。 二、硬件连接。 模块上电&#xff0c;PC机 的IP配置成为10.10.18.100&a…

GraphQL(6):认证与中间件

下面用简单来讲述GraphQL的认证示例 1 实现代码 在代码中添加过滤器&#xff1a; 完整代码如下&#xff1a; const express require(express); const {buildSchema} require(graphql); const grapqlHTTP require(express-graphql).graphqlHTTP; // 定义schema&#xff0c;…

Wireshark TS | 应用传输丢包问题

问题背景 仍然是来自于朋友分享的一个案例&#xff0c;实际案例不难&#xff0c;原因也就是互联网线路丢包产生的重传问题。但从一开始只看到数据包截图的判断结果&#xff0c;和最后拿到实际数据包的分析结果&#xff0c;却不是一个结论&#xff0c;方向有点跑偏&#xff0c;…

微服务第一轮

课程文档 目录 一、业务流程 1、登录 Controller中的接口&#xff1a; Service中的实现impl&#xff1a; Service中的实现impl所继承的接口IService&#xff08;各种方法&#xff09;&#xff1a; VO&#xff1a; DTO&#xff1a; 2、搜索商品 ​Controller中的接口&a…

牛客热题:最长公共子串

&#x1f4df;作者主页&#xff1a;慢热的陕西人 &#x1f334;专栏链接&#xff1a;力扣刷题日记 &#x1f4e3;欢迎各位大佬&#x1f44d;点赞&#x1f525;关注&#x1f693;收藏&#xff0c;&#x1f349;留言 文章目录 牛客热题&#xff1a;最长公共子串题目链接方法一&am…

【Redis学习笔记05】Jedis客户端(中)

Jedis客户端 1. 命令 1.1 String类型 1.1.1 常见命令 SET命令 语法&#xff1a;SET key value [EX seconds | PX milliseconds] [NX|XX] 说明&#xff1a;将string类型的value值设置到指定key中&#xff0c;如果之前该key存在&#xff0c;则会覆盖原先的值&#xff0c;原先…

Java--可变参数

1.JDK1.5开始&#xff0c;Java支持同类型的可变参数给一个方法 2.在方法声明之前&#xff0c;在指定参数类型后加一个省略号&#xff08;...&#xff09; 3.一个方法只能指定一个可变参数&#xff0c;它必须是方法的最后一个参数&#xff0c;任何普通的参数必须在它之前声明 …

Java----抽象类和接口

欢迎大家来这次博客-----抽象类和接口。 1.抽象类 1.1 抽象类概念 在Java中我们都是通过类来描述对象&#xff0c;但反过来并不是所有的类都是用来描述对象的。当一个类中没有足够的信息来描述一个具体对象&#xff0c;我们就将该类称为抽象类。 如上图中的Shape类&#xff…

支付宝订单支付和超时收单

下订单成功后&#xff0c;发送mq消息到死信队列&#xff0c;消息过期后根据死信的路由key重新路由到交换机&#xff0c;交换机根据消息的路由key把消息路由到普通队列上&#xff0c;消费者监听队列并消费。 问题&#xff0c;现在提交订单信息调用支付宝的支付页面&#xff0c;…

AI论文速读 | 2024[ICML]FlashST:简单通用的流量预测提示微调框架

题目&#xff1a; FlashST: A Simple and Universal Prompt-Tuning Framework for Traffic Prediction 作者&#xff1a;Zhonghang Li, Lianghao Xia&#xff08;夏良昊&#xff09;, Yong Xu&#xff08;徐勇&#xff09;, Chao Huang 机构&#xff1a;华南理工大学&#xf…

分享不用会员免费听歌的软件,可听付费,支持随听随下!

今天来点特别的&#xff0c;给你们带来几款全网免费听歌的神器&#xff0c;让你们的音乐之旅不再有障碍&#xff01; 现在&#xff0c;找好听的歌越来越像寻宝一样&#xff0c;动不动就得掏腰包。不过别担心&#xff0c;阿星今天就来分享几款好用的免费听歌app&#xff0c;电脑…

SQL(一)基本语法

文章目录 一、Sql 语言基本特点二、数据查询&#xff08;按执行顺序排列&#xff09;1. From & Join2. Where3. Group by4. Having5. Select6. Distinct7. Order by8. Limit/ Offset 三、功能公式1. 字符处理2. 时间处理3. 统计计算 一、Sql 语言基本特点 不区分大小写分号…

数据库(29)——子查询

概念 SQL语句中嵌套SELECT语句&#xff0c;称为嵌套查询&#xff0c;又称子查询。 SELECT * FROM t1 WHERE column1 (SELECT column1 FROM t2); 子查询外部语句可以是INSERT/UPDATE/DELETE/SELECT的任何一个。 标量子查询 子查询返回的结果是单个值&#xff08;数字&#xff…

pdf压缩文件怎么压缩最小,软件工具压缩清晰

PDF格式的文件&#xff0c;当其体积过于庞大时&#xff0c;确实在上传的过程中显得尤为不便。今天给大家分享一个压缩pdf的简单的方法&#xff0c;让大家可以轻松的压缩pdf。 浏览器打开 "轻云处理pdf官网" &#xff0c;上传pdf文件&#xff0c;文件上传完成后网站会…

ChatGPT Prompt技术全攻略-精通篇:Prompt工程技术的高级应用

系列篇章&#x1f4a5; No.文章1ChatGPT Prompt技术全攻略-入门篇&#xff1a;AI提示工程基础2ChatGPT Prompt技术全攻略-进阶篇&#xff1a;深入Prompt工程技术3ChatGPT Prompt技术全攻略-高级篇&#xff1a;掌握高级Prompt工程技术4ChatGPT Prompt技术全攻略-应用篇&#xf…