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

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

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

相关文章

mmdeploy环境部署流程

参考&#xff1a;mmdeploy/docs/zh_cn/01-how-to-build/linux-x86_64.md at main open-mmlab/mmdeploy (github.com) 从零入门《openmmlab》mmdeploy[1]环境安装及简单上手_哔哩哔哩_bilibili 我的环境&#xff1a; docker容器&#xff0c;ubuntu20.04&#xff0c;cuda11.7…

注解(Annotation)(一)

Java 注解&#xff08; Annotation &#xff09;又称 Java 标注&#xff0c;是 JDK5.0 引入的一种注释机制。 Java 语言中的类、 构造器、 方法、成员变量、参数等都可以被注解进行标注。 自定义注解 --- 格式 自定义注解就是自己做一个注解来使用。 public interface …

C++ | Leetcode C++题解之第140题单词拆分II

题目&#xff1a; 题解&#xff1a; class Solution { private:unordered_map<int, vector<string>> ans;unordered_set<string> wordSet;public:vector<string> wordBreak(string s, vector<string>& wordDict) {wordSet unordered_set(w…

[Cloud Networking] SPDY 协议

文章目录 1. 背景2. SPDY 之前3. SPDY 项目目标4. SPDY 功能特点4.1 SPDY基本功能4.2 SPDY高级功能 1. 背景 TCP是通用的、可靠的传输协议&#xff0c;提供保证交付、重复抑制、按顺序交付、流量控制、拥塞避免和其他传输特性。 HTTP是提供基本请求/响应语义的应用层协议。 不…

Apache IoTDB进行IoT相关开发实践

当今社会&#xff0c;物联网技术的发展带来了许多繁琐的挑战&#xff0c;尤其是在数据库管理系统领域&#xff0c;比如实时整合海量数据、处理流中的事件以及处理数据的安全性。例如&#xff0c;应用于智能城市的基于物联网的交通传感器可以实时生成大量的交通数据。据估计&…

【面试干货】Integer 和 int 的区别

【面试干货】Integer 和 int 的区别 1、基本类型与包装类型2、内存占用3、自动装箱与拆箱4、null 值5、常量池6、总结 &#x1f496;The Begin&#x1f496;点点关注&#xff0c;收藏不迷路&#x1f496; 在Java中&#xff0c;Integer 和 int 是两种不同类型的变量&#xff0c;…

REST风格

黑马程序员Spring Boot2 文章目录 1、REST简介1.1 优点1.2 REST风格简介1.3 注意事项 2、RESTful入门案例 1、REST简介 1.1 优点 隐藏资源的访问行为&#xff0c;无法通过地址的值对资源适合中操作书写简化 1.2 REST风格简介 按照RST风格访问资源时使用行为动作区分对资源进…

Python:基础爬虫

Python爬虫学习&#xff08;网络爬虫&#xff08;又称为网页蜘蛛&#xff0c;网络机器人&#xff0c;在FOAF社区中间&#xff0c;更经常的称为网页追逐者&#xff09;&#xff0c;是一种按照一定的规则&#xff0c;自动地抓取万维网信息的程序或者脚本。另外一些不常使用的名字…

OpenGauss常操作

OpenGauss官网已经有很详细的说明了,但是对于新手而言还有一些需要注意的地方; 安装 yum一键安装; yum -y install libaio-devel yum -y install readline-devel yum -y install libnsl 单独创建用户和组; groupadd dbgroup useradd -g dbgroup omm passwd omm 取消打开文…

RK3568平台(input篇)输入设备应用编程

一.输入设备介绍 输入设备其实就是能够产生输入事件的设备就称为输入设备&#xff0c;常见的输入设备包括鼠标、键盘、触摸屏、按钮等等&#xff0c;它们都能够产生输入事件&#xff0c;产生输入数据给计算机系统。 对于输入设备的应用编程其主要是获取输入设备上报的数据、输…

Django更改超级用户密码

Django更改超级用户密码 1、打开shell 在工程文件目录下敲入&#xff1a; python manage.py shell再在python交互界面输入&#xff1a; from django.contrib.auth.models import User user User.objects.get(username root) user.set_password(123456) user.save()其中ro…

每日一练——有效的括号

20. 有效的括号 - 力扣&#xff08;LeetCode&#xff09; 错误记录 #include<stddef.h> #include<stdlib.h> #include<assert.h> #include<stdbool.h>typedef char STDataType;typedef struct Stack {STDataType* a;int capacity;int top; } Stack;vo…

【回文 马拉车】214. 最短回文串

本文涉及知识点 回文 马拉车 LeetCode214. 最短回文串 给定一个字符串 s&#xff0c;你可以通过在字符串前面添加字符将其转换为回文串。找到并返回可以用这种方式转换的最短回文串。 示例 1&#xff1a; 输入&#xff1a;s “aacecaaa” 输出&#xff1a;“aaacecaaa” 示…

超详解——Python 字典详解——小白篇

目录 1. 创建字典 示例&#xff1a; 2. 访问字典中的元素 示例&#xff1a; 3. 修改字典元素 示例&#xff1a; 4. 删除字典元素 示例&#xff1a; 5. 查找元素是否是字典的键 示例&#xff1a; 6. 标准类型操作符 获取字典长度 合并两个字典 7. 常用内置函数 k…

【Qt】QT textBrowser 设置字体颜色和大小

1. 效果 2. 代码 {ui->methodText->append("<font size9 colorgreen> dddddddddd </font>");ui->methodText->append("<font size9 colorred> vvvvvvvvvv </font>"); }

读AI新生:破解人机共存密码笔记02进化

1. 人工智能的标准模型 1.1. 机器优化人类提供的固定目标 1.1.1. 是一条死胡同 1.1.1.1. 当你走进死胡同时&#xff0c;你最好掉头返回&#xff0c;找出走错的地方 1.2. 问题不在于我们可能无法做好构建人工智能系统的工作&…

atmega8 上传程序

使用icsp 烧写时先关闭串口程序&#xff0c;与串口uart连接相关的电路勿于电脑连接 接触不良 1.使用icsp 上传 1&#xff09;可以直接上传程序 如官方示例blink 或是 serial示例 2&#xff09;可以先烧录bootload 方便下次使用串口上传程序代码 A)使用专门的icsp 上传器上传…

AI Stable diffusion 报错:稳定扩散模型加载失败,退出

可能是内存不够&#xff0c;看看你最近是加了新的大的模型&#xff0c;可以把你的stable-diffusion-webui\models\Stable-diffusion目录下的某个ckpt删除掉&#xff0c;可能ckpt太大&#xff0c;无法加载成功&#xff1b; Stable diffusion model failed to load, exiting 如图…

如何在WIndows虚拟机安装 macOS 黑苹果系统?

在本教程中&#xff0c;我们将介绍如何在虚拟机上安装 macOS 黑苹果系统。黑苹果系统是非苹果公司官方支持的 macOS 系统的非官方版本&#xff0c;可以在普通 PC 上运行。请注意&#xff0c;安装黑苹果系统可能违反苹果的许可协议&#xff0c;请自行承担风险。参考视频教程&…

如何应对生活中的不确定性:仁者安仁,知者利仁。

有较高自尊水平的人&#xff0c;接近于孔子说的&#xff1a;仁者。 ——— 有着稳定的高自尊&#xff0c;无论外在环境如何变化&#xff0c;对其影响都不大&#xff0c;他能够愉快地生活。 相反&#xff1a;一个人处于低自尊状态&#xff0c;就会活得很痛苦&#xff0c;对自己…