共计 12198 个字符,预计需要花费 31 分钟才能阅读完成。
这篇文章主要介绍“redis 如何部署集群”,在日常操作中,相信很多人在 redis 如何部署集群问题上存在疑惑,丸趣 TV 小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”redis 如何部署集群”的疑惑有所帮助!接下来,请跟着丸趣 TV 小编一起来学习吧!
1、Redis 主从架构
1.1、主从复制原理
从服务器连接主服务器,发送 PSYNC 命令;
主服务器接收到 PSYNC 命名后,开始执行 BGSAVE 命令生成 RDB 文件并使用缓冲区记录此后执行的所有写命令;
主服务器 BGSAVE 执行完后,向所有从服务器发送快照文件,并在发送期间继续记录被执行的写命令;
从服务器收到快照文件后丢弃所有旧数据,载入收到的快照;
主服务器快照发送完毕后开始向从服务器发送缓冲区中的写命令;
从服务器完成对快照的载入,开始接收命令请求,并执行来自主服务器缓冲区的写命令;(从服务器初始化完成)
主服务器每执行一个写命令就会向从服务器发送相同的写命令,从服务器接收并执行收到的写命令(从服务器初始化完成后的操作)
当 master 与 slave 之间的连接由于某些原因而断开时,slave 能够自动重连 Master,如果 master 收到了多个 slave 并发连接请求,它只会进行一次持久化,而不是一个连接一次,然后再把这一份持久化的数据发送给多个并发连接的 slave。
1.2、主从复制优缺点
优点:
支持主从复制,主机会自动将数据同步到从机,可以进行读写分离
为了分载 Master 的读操作压力,Slave 服务器可以为客户端提供只读操作的服务,写服务仍然必须由 Master 来完成
Slave 同样可以接受其它 Slaves 的连接和同步请求,这样可以有效的分载 Master 的同步压力。
Master Server 是以非阻塞的方式为 Slaves 提供服务。所以在 Master-Slave 同步期间,客户端仍然可以提交查询或修改请求。
Slave Server 同样是以非阻塞的方式完成数据同步。在同步期间,如果有客户端提交查询请求,Redis 则返回同步之前的数据
缺点:
Redis 不具备自动容错和恢复功能,主机从机的宕机都会导致前端部分读写请求失败,需要等待机器重启或者手动切换前端的 IP 才能恢复。
主机宕机,宕机前有部分数据未能及时同步到从机,切换 IP 后还会引入数据不一致的问题,降低了系统的可用性。
Redis 较难支持在线扩容,在集群容量达到上限时在线扩容会变得很复杂。
1.3、redis 主从架构搭建,配置从节点步骤
此处使用 6380 作为 master 节点 6381 和 6382 作为 slave 节点
#1、 创建目录 conf/master-slave-cluster 存放对应集群的配置信息 mkdir -p conf/master-slave-cluster# 创建目录 data 存放对应集群对应的数据信息(数据目录)mkdir -p /usr/local/redis/data/6380
mkdir -p /usr/local/redis/data/6381
mkdir -p /usr/local/redis/data/6382
#复制一份 redis.conf 文件 重命名 redis-6381.conf# 2、将相关配置修改为如下值:# 修改端口号 port 6381# 把 pid 进程号写入 pidfile 配置的文件 pidfile /var/run/redis_6381.pid
# 指定日志存放目录 logfile 6381.log # 指定数据存放目录 dir /usr/local/redis-5.0.3/data/6381
# 需要注释掉 bind# bind 127.0.0.1(bind 绑定的是自己机器网卡的 ip,如果有多块网卡可以配多个 ip,代表允许客户端通过机器的哪些网卡 ip 去访问,内网一般可以不配置 bind,注释掉即可)# 3、配置主从复制(6380 是 master 不需要配置如下 只需给 6381 和 6382 配置如下属性)# 从本机 6379 的 redis 实例复制数据,Redis 5.0 之前使用 slaveofreplicaof xxx.xxx.xxx.xxx 6380 # 配置从节点只读 replica-read-only yes #4、启动从节点 redis-server redis-6381.conf5、连接从节点
redis-cli -p 63816、测试在 6380 实例上写数据,6381 实例是否能及时同步新修改数据 7、同样的方法再配置一个 6382 的从节点
1.4、校验结果
查看 redis 的主从集群
master 操作
# 连接 master[root@ip redis]# src/redis-cli -p 6380127.0.0.1:6380 auth xiu123
OK127.0.0.1:6380 set name zhangsan OK127.0.0.1:6380 get name
zhangsan
slave 操作
# 连接 slavesrc/redis-cli -p 6381127.0.0.1:6381 get name
zhangsan #从节点只能进行读操作 127.0.0.1:6381 set name lisi(error) READONLY You can t write against a read only replica.127.0.0.1:6381 ![在这里插入图片描述](https://img-blog.csdnimg.cn/36d9e96b1cae498fad03e04d695997c2.png#pic_center)
1.5、数据部分复制
当 master 和 slave 断开重连后,一般都会对整份数据进行复制。但从 redis2.8 版本开始,redis 改用可以支持部分数据复制的命令 PSYNC 去 master 同步数据,slave 与 master 能够在网络连接断开重连后只进行部分数据复制(断点续传)。
master 会在其内存中创建一个复制数据用的缓存队列,缓存最近一段时间的数据,master 和它所有的 slave 都维护了复制的数据下标 offset 和 master 的进程 id,因此,当网络连接断开后,slave 会请求 master 继续进行未完成的复制,从所记录的数据下标开始。如果 master 进程 id 变化了,或者从节点数据下标 offset 太旧,已经不在 master 的缓存队列里了,那么将会进行一次全量数据的复制。
主从复制 (部分复制,断点续传) 流程图:
如果有很多从节点,为了缓解主从复制风暴 **(多个从节点同时复制主节点导致主节点压力过大),可以做如下架构,让部分从节点与从节点 (与主节点同步) 同步数据
2、Redis 哨兵高可用架构
sentinel 哨兵是特殊的 redis 服务,不提供读写服务,主要用来监控 redis 实例节点。哨兵的作用就是监控 Redis 系统的运行状况。它的功能包括以下两个
(1)监控主服务器和从服务器是否正常运行。
(2)主服务器出现故障时自动将从服务器转换为主服务器。
2.1、哨兵的工作方式
哨兵架构下 client 端第一次从哨兵找出 redis 的主节点,后续就直接访问 redis 的主节点,当 redis 的主节点发生变化,哨兵会第一时间感知到,并且将新的 redis 主节点通知给 client 端。
Sentinel 会定时的对自己监控的 master 执行 info 命令,获取最新的主从关系,还会定时的给所有的 redis 节点发送 ping 心跳检测命令,如果检测到某个 master 无法响应了,就会在给其他 Sentinel 发送消息,主观认为该 master 宕机,如果 Sentinel 集群认同该 master 下线的人数达到一个值,那么大家统一意见,下线该 master。
下线之前需要做的是找 Sentinel 集群中的某一个来执行下线操作,这个步骤叫领导者选举,选出来以后会从该 master 所有的 slave 节点中挑一个合适的作为新的 master,并让其他 slave 重新同步新的 master
若没有足够数量的 Sentinel(哨兵)进程同意 Master 主服务器下线,Master 主服务器的客观下线状态就会被移除。若 Master 主服务器重新向 Sentinel(哨兵)进程发送 PING 命令返回有效回复,Master 主服务器的主观下线状态就会被移除。
三个定时任务
sentinel 在内部有 3 个定时任务
1)每 10 秒每个 sentinel 会对 master 和 slave 执行 info 命令,这个任务达到两个目的:
a)发现 slave 节点
b)确认主从关系
2)每 2 秒每个 sentinel 通过 master 节点的 channel 交换信息(pub/sub)。master 节点上有一个发布订阅的频道(sentinel:hello)。sentinel 节点通过__sentinel__:hello 频道进行信息交换(对节点的 看法 和自身的信息),达成共识。
3)每 1 秒每个 sentinel 对其他 sentinel 和 redis 节点执行 ping 操作(相互监控),这个其实是一个心跳检测,是失败判定的依据。
2.2、哨兵模式的优缺点
优点:
哨兵模式是基于主从模式的,所有主从的优点,哨兵模式都具有。
主从可以自动切换,系统更健壮,可用性更高。
缺点:
Redis 较难支持在线扩容,在集群容量达到上限时在线扩容会变得很复杂。
2.3、redis 哨兵架构搭建步骤 2.3.1、配置 sentinel.conf 文件
# 1、复制一份 sentinel.conf 文件 mkdir sentinelcp sentinel.conf sentinel-26380.conf
# 保护模式 protected-mode no
# 端口号 port 26380# 是否静默启动 daemonize yes
# pid 进程号 pidfile /var/run/redis-sentinel-26380.pid
# 日志文件 logfile /usr/local/redis/data/6380/sentinel.log
# 哨兵服务数据存储 dir /usr/local/redis/data
# 哨兵监控 sentinel monitor masterName maste 节点 redis ip num 哨兵认可主观下线数量
# 故障转移后 master 节点 ip 会发生变化 sentinel monitor mymaster 182.92.189.235 6380 2
# 连接 master 节点 密码 # 设置连接 master 和 slave 时的密码,注意的是 sentinel 不能分别为 master 和 slave 设置不同的密码,因此 master 和 slave 的密码应该设置相同。sentinel auth-pass mymaster xiu123#sentinel config-epoch mymaster 9#sentinel leader-epoch mymaster 9# 自动生成 从节点信息 但是此处没有自动生成 sentinel known-slave mymaster 182.92.189.235 6381sentinel known-slave mymaster 182.92.189.235 6382
# 自动生成配置 启动回自动生成一些配置
2.3.2、启动哨兵服务实例
# 启动 sentinel 哨兵实例 src/redis-sentinel sentinel-26380.conf
#查看 sentinel 的 info 信息 src/redis-cli -p 26379127.0.0.1:26379 info
#可以看到 Sentinel 的 info 里已经识别出了 redis 的主从
#同理再次添加两个 sentinel,端口 26381 和 26382 并同理启动,注意上述配置文件里的对应数字都要修改
sentinel 集群都启动完毕后,会将哨兵集群的元数据信息写入所有 sentinel 的配置文件里去(追加在文件的最下面),我们查看下如下配置文件 sentinel-26380.conf,如下所示:
2.3.3、redis 哨兵模式故障迁移
shell
# 1、查看当前 redis 集群服务 一主两从三哨兵
[root@iZ2ze505h9bgsa1t9twojyZ redis]# ps -ef | grep redis
root 1166 30926 0 22:43 pts/2 00:00:00 grep --color=auto redis
root 28998 1 0 21:12 ? 00:00:06 src/redis-server *:6380
root 29010 1 0 21:12 ? 00:00:06 src/redis-server *:6381
root 29020 1 0 21:12 ? 00:00:06 src/redis-server *:6382
root 31686 1 0 22:05 ? 00:00:05 src/redis-sentinel *:26380 [sentinel]
root 32553 1 0 22:22 ? 00:00:03 src/redis-sentinel *:26381 [sentinel]
root 32562 1 0 22:22 ? 00:00:03 src/redis-sentinel *:26382 [sentinel]
[root@iZ2ze505h9bgsa1t9twojyZ redis]# src/redis-cli -p 6380
127.0.0.1:6380 auth xiu123
127.0.0.1:6380 info replication
# Replication
role:master
connected_slaves:2
slave0:ip=182.92.189.235,port=6381,state=online,offset=261525,lag=0
slave1:ip=182.92.189.235,port=6382,state=online,offset=261525,lag=1
... 省略部分代码
127.0.0.1:6380 quit
# 杀掉 redis
[root@iZ2ze505h9bgsa1t9twojyZ redis]# kill -9 28998
# 查看日志
[root@iZ2ze505h9bgsa1t9twojyZ redis]# tail -f data/6380/sentinel.log
# 该哨兵认为主观下线
31686:X 12 Nov 2021 22:45:40.110 # +sdown master mymaster 182.92.189.235 6382
# 到达主观下线阙值 则客观下线
31686:X 12 Nov 2021 22:45:40.181 # +odown master mymaster 182.92.189.235 6382 #quorum 2/2
31686:X 12 Nov 2021 22:45:40.181 # +new-epoch 18
# 尝试故障转移
31686:X 12 Nov 2021 22:45:40.181 # +try-failover master mymaster 182.92.189.235 6382
# 投票选举主节点
31686:X 12 Nov 2021 22:45:40.189 # +vote-for-leader ba9eed52de8664c3fd8d76d9728b42a309c3401b 18
# 选择主节点 6381
31686:X 12 Nov 2021 22:45:41.362 # +switch-master mymaster 182.92.189.235 6382 182.92.189.235 6381
#查看新的主从节点信息 主节点 6381 从节点 6382
[root@iZ2ze505h9bgsa1t9twojyZ redis]# src/redis-cli -p 6381
127.0.0.1:6381 auth xiu123
127.0.0.1:6381 info replication
# Replication
role:master
connected_slaves:1
slave0:ip=182.92.189.235,port=6382,state=online,offset=469749,lag=0
3、Redis 高可用集群 3.1、高可用集群模式
3.2、Redis-Cluster 集群
redis 的哨兵模式基本已经可以实现高可用,读写分离,但是在这种模式下每台 redis 服务器都存储相同的数据,很浪费内存,所以在 redis3.0 上加入了 cluster 模式,实现的 redis 的分布式存储,也就是说每台 redis 节点上存储不同的内容。
Redis-Cluster 采用无中心结构, 它的特点如下:
所有的 redis 节点彼此互联(PING-PONG 机制), 内部使用二进制协议优化传输速度和带宽。
节点的 fail 是通过集群中超过半数的节点检测失效时才生效。
客户端与 redis 节点直连, 不需要中间代理层. 客户端不需要连接集群所有节点, 连接集群中任何一个可用节点即可。
工作方式:
在 redis 的每一个节点上,都有这么两个东西,一个是插槽(slot),它的的取值范围是:0-16383。还有一个就是 cluster,可以理解为是一个集群管理的插件。当我们的存取的 key 到达的时候,redis 会根据 crc16 的算法得出一个结果(hash 函数),然后把结果对 16384 求余数,这样每个 key 都会对应一个编号在 0-16383 之间的哈希槽,通过这个值,去找到对应的插槽所对应的节点,然后直接自动跳转到这个对应的节点上进行存取操作。
为了保证高可用,redis-cluster 集群引入了主从模式,一个主节点对应一个或者多个从节点,当主节点宕机的时候,就会启用从节点。当其它主节点 ping 一个主节点 A 时,如果半数以上的主节点与 A 通信超时,那么认为主节点 A 宕机了。如果主节点 A 和它的从节点 A1 都宕机了,那么该集群就无法再提供服务了。
redis 集群是一个由多个主从节点群组成的分布式服务器群,它具有复制、高可用和分片特性。Redis 集群不需要 sentinel 哨兵·也能完成节点移除和故障转移的功能。需要将每个节点设置成集群模式,这种集群模式没有中心节点,可水平扩展,据官方文档称可以线性扩展到上万个节点(官方推荐不超过 1000 个节点)。redis 集群的性能和高可用性均优于之前版本的哨兵模式,且集群配置非常简单
3.3、Redis 高可用集群搭建 3.3.1、redis 集群搭建
redis 集群需要至少三个 master 节点,我们这里搭建三个 master 节点,并且给每个 master 再搭建一个 slave 节点,总共 6 个 redis 节点,这里用三台机器部署 6 个 redis 实例,每台机器一主一从,搭建集群的步骤如下:
6383(主)6384(从)
6385(主)6386(从)
6387(主)6388(从)
节点配置
# 是否静默启动
daemonize yes
port 6383
# pid 进程文件
pidfile /var/run/redis_6383.pid
#数据存储
dir /usr/local/redis/data/redis-cluster/6383/
# 指定日志存放目录
logfile /usr/local/redis/data/cluster-6383.log
# 关闭保护模式
protected-mode no
创建集群
redis 集群配置好后,在 5.X 版本之前需要需要使用 ruby 脚本去创建集群,但是 5.x 之后可以通过 redis-cli 执行创建集群命令即可
# 分别启动 redis 实例
src/redis-server conf/cluster/638*/redis.conf
# 下面命令里的 1 代表为每个创建的主服务器节点创建一个从服务器节点
# 执行这条命令需要确认三台机器之间的 redis 实例要能相互访问,可以先简单把所有机器防火墙关掉,如果不关闭防火墙则需要打开 redis 服务端口和集群节点 gossip 通信端口 16379(默认是在 redis 端口号上加 1W)
# 关闭防火墙
# systemctl stop firewalld # 临时关闭防火墙
# systemctl disable firewalld # 禁止开机启动
# 注意:下面这条创建集群的命令大家不要直接复制,里面的空格编码可能有问题导致创建集群不成功
# 本次测试不远程连接 使用 127.0.0.1 如果涉及远程连接需要设置真实公网 ip
# -a 密码。 -- cluster create 创建集群 --cluster-replicas 1 每一个 master 建立一个从节点 6 个实例 中选择 3 个作为另外 3 个主节点的从节点,最终变成 3 主 3 从
src/redis-cli -a password --cluster create --cluster-replicas 1 127.0.0.1:6383 127.0.0.1:6384 127.0.0.1:6385 127.0.0.1:6386 127.0.0.1:6387 127.0.0.1:6388
问题:
#1、这是由于创建集群中的某一个服务中曾经插入过数据,并且已经产生了持久化文件,重新再进行创建集群 此时需要 flushall 命令清空所有数据
[ERR] Node 127.0.0.1:6383 is not empty. Either the node already knows other nodes (check with CLUSTER NODES) or contains some key in database 0
#测试使用 flush 不好使用 只要找到配置文件对应数据存储目录 暴力 rm 删除
# 2、登陆某个集群出现 出现 CLUSTERDOWN Hash slot not served 原因 启动集群实例后没有执行集群创建
验证集群
读写 key 需要 对 key 进行 hash 不使用集群模式登陆客户端,则我们只访问单独会提示让我们去对应的节点上进行操作
集群登陆
# 连接任意一个客户端即可:./redis-cli -c -h -p (- a 访问服务端密码,- c 表示集群模式,指定 ip 地址和端口号)# -a 密码 -c 集群模式 -h ip -p port
src/redis-cli -a password -c -h 127.0.0.1 -p 6383
# 进行验证: cluster info(查看集群信息)、cluster nodes(查看节点列表)#进行数据操作验证
#关闭集群则需要逐个进行关闭,使用命令:src/redis-cli -a password -c -h 127.0.0.1 -p 638* shutdown
3.3.2、集群故障转移
上述集群三主三从。6386、6387、6388 分别对应主节点 6383、6384、6385 的从,如果某个主节点宕机,则从节点会自动被选举为主节点继续对外提供服务,一定的容错机制保证高可用。注意存在从节点的情况下,主从节点不具备读写分离,读写都使用主节点
# 模拟 redis 的故障转移
#登陆节点 发现 name 这个 key 在 6384 上 age 这个 key 在 6383 上 wdih 这个 key 在 6385 上
[root@iZ2ze505h9bgsa1t9twojyZ redis]# src/redis-cli -a xiu123 -c -h 127.0.0.1 -p 6383
127.0.0.1:6384 get name
- Redirected to slot [5798] located at 127.0.0.1:6384
(nil)
127.0.0.1:6384 get age
- Redirected to slot [741] located at 127.0.0.1:6383
127.0.0.1:6383 get width
- Redirected to slot [15983] located at 127.0.0.1:6385
110
127.0.0.1:6385 quit
## 杀掉 6385 这个主节点
[root@iZ2ze505h9bgsa1t9twojyZ redis]# kill -9 14187
# 重新登陆集群 获取 age、name 还是原来的节点 获取 width 由 6385 转移到了 6388 查看 6380 节点信息发现其变为了主节点
[root@iZ2ze505h9bgsa1t9twojyZ redis]# src/redis-cli -a xiu123 -c -h 127.0.0.1 -p 6383
127.0.0.1:6383 get age
# 这里因该是在选举 master 节点 导致集群短暂不可用(猜测)
127.0.0.1:6383 get name
(error) CLUSTERDOWN The cluster is down
127.0.0.1:6383 get name
- Redirected to slot [5798] located at 127.0.0.1:6384
xieqx
127.0.0.1:6384 get width
- Redirected to slot [15983] located at 127.0.0.1:6388
110
127.0.0.1:6388 info replication
# Replication
role:master
# 杀掉 6388 则整个集群服务都不可用
127.0.0.1:6383 get name
(error) CLUSTERDOWN The cluster is down
3.3.3、集群动态扩缩容
# 复制之前 6383 节点配置 创建 6389、6390 节点 并启动实例
--- 集群扩容 ----
#1、 添加 master 节点
## add-node: 后面的分别跟着新加入的 ***master 和集群的某个节点 NODE_ID***
src/redis-cli --cluster add-node 127.0.0.1:6389 127.0.0.1:6383 -a password
# 2、为增加的主节点添加从节点
#--cluster-slave 表明添加的是 slave 节点
## add-node: 后面的分别跟着新加入的 ****slave 和 slave 对应的 master NODE_ID***
#--cluster-master-id:表示 slave 对应的 master 的 node ID
src/redis-cli --cluster add-node 127.0.0.1:6390 127.0.0.1:6389 --cluster-slave --cluster-master-id 353662f6868b187ad15bad9b7271b8f0848adf10 -a password
# 3、 重新分片 slot
#-cluster-from:表示 slot 目前所在的节点的 node ID,多个 ID 用逗号分隔
#--cluster-to:表示需要新分配节点的 node ID(貌似每次只能分配一个)# --cluster-slots:分配的 slot 数量
src/redis-cli --cluster reshard 127.0.0.1:6389 --cluster-from 47318cef1195f4281b7815bf66a41e31d68b6d16,0dbea2fff1554a3bbca70d28b81911e60c5bee6d,2fd29d61e867cb85e2e368ee62aebef33e7aaeb3 --cluster-to 353662f6868b187ad15bad9b7271b8f0848adf10 --cluster-slots 1024 -a password
#查看集群信息
--- 集群缩容 ----
#下线节点 127.0.0.1:6389(master)/127.0.0.1:6390(slave)#(1)首先删除 master 对应的 slave
#del-node 后面跟着 slave 节点的 ip:port 和 node ID
src/redis-cli --cluster del-node 127.0.0.1:6390 353662f6868b187ad15bad9b7271b8f0848adf10 -a password
#(2)清空 master 的 slot 将一个下线的节点的 slot 重新分配到其他三个节点中
#reshard 子命令前面已经介绍过了,这里需要注意的一点是,由于我们的集群一共有四个主节点,而每次 reshard 只能写一个目的节点,因此以上命令需要执行三次(--cluster-to 对应不同的目的节点)。#--cluster-yes:不回显需要迁移的 slot,直接迁移。src/redis-cli --cluster reshard 127.0.0.1:6389 --cluster-from 353662f6868b187ad15bad9b7271b8f0848adf10 --cluster-to 0dbea2fff1554a3bbca70d28b81911e60c5bee6d --cluster-slots 1024 --cluster-yes
#(3)下线(删除)节点 主节点
src/redis-cli --cluster del-node 127.0.0.1:6389 353662f6868b187ad15bad9b7271b8f0848adf10
到此,关于“redis 如何部署集群”的学习就结束了,希望能够解决大家的疑惑。理论与实践的搭配能更好的帮助大家学习,快去试试吧!若想继续学习更多相关知识,请继续关注丸趣 TV 网站,丸趣 TV 小编会继续努力为大家带来更多实用的文章!