redis 运维讲解02

一、数据持久化 

1、为什么要持久化

redis 重启后,redis 存在内存数据中数据丢失,不管之前是多少G数据,秒丢,而且无法恢复,数据在内存中

[root@86-5-master ~]# redis-cli -p 6379
127.0.0.1:6379> MSET k1 v1 k2 v2 k3 v3
OK
127.0.0.1:6379> MGET k1 k2 k3
1) "v1"
2) "v2"
3) "v3"
127.0.0.1:6379> exit
[root@86-5-master ~]# redis-cli -p 6379
127.0.0.1:6379> MGET k1 k2 k3
1) "v1"
2) "v2"
3) "v3"
127.0.0.1:6379> exit
[root@86-5-master ~]# redis-cli -p 6379
127.0.0.1:6379> shutdown
not connected> exit
[root@86-5-master ~]# redis-server /opt/redis_cluster/redis_6379/conf/redis_6379.conf 
[root@86-5-master ~]# redis-cli -p 6379
127.0.0.1:6379> MGET k1 k2 k3
1) (nil)
2) (nil)
3) (nil)
127.0.0.1:6379> 

2、Redis持久的两种方式

RDB的持久化优缺点

可以在指定的时间间隔内升成数据集的 时间点快照
可以理解为rbd就是将当前进程数据生成快照保存到硬盘的过程,触发RBD持久化过程 分为手动触发和自动触发

优点:速度快,是一个压缩的二进制文件,适用于备份特别是全量备份,恢复很快,主从复制也是基于rdb持久化功能实现的,对性能影响最小 RDB文件进行数据恢复比使用AOF要快很多

缺点:会有数据丢失,如果数据集非常大且CPU不够强(比如单核 CPU),Redis在fork子进程时可能会消耗相对较长的时间,影响Redis对外提供服务的能力。bgsave是重量级的操作,因为要将内存中的数据完整复制一份到本地。新版本可以用老版本的RDB文件,老的不兼容新的

 

AOF的持久化优缺点

相当于mysql的 binlog,每一个记录都记录下来,这样只记录你的操作,而不是实际数据

缺点:无限制追加 binlog 会无限制增大,mysql 会设置 binlog 的最大大小,满足后会进行切割。而 Redis 会触发 rewrite进行压缩数据,但是还是比较大,恢复的时候没有RBD快

优点:最多只会损失1s内的数据

 

注意:RDB、AOF是可以同时并存的,完全没问题,而且不冲突

 

3、RDB 持久化配置

1、手动触发机制

Redis客户端直接通过命令BGSAVE或者SAVE来创建一个内存快照

  • BGSAVE 调用fork来创建一个子进程,子进程负责将快照写入磁盘,而父进程仍然继续处理命令。是一个全量复制。
  • SAVE 执行SAVE命令过程中,不再响应其他命令。

save和bgsave区别

save:

  优点:节约系统资源

  缺点:直接调用 rdbSave ,阻塞 Redis 主进程,直到保存完成为止。在主进程阻塞期间,服务器不能处理客户端的任何请求。

bgsave:

  优点:fork 出一个子进程,子进程负责调用 rdbSave ,并在保存完成之后向主进程发送信号,通知保存已完成。 Redis 服务器在BGSAVE 执行期间仍然可以继续处理客户端的请求

  缺点:由于会fork一个进程,因此更消耗内存

综上:

  还是推荐使用bgsave命令,毕竟save命令阻塞其他请求是我们无法接受的

 

在BGSAVE执行期间,再执行SAVE/BGSAVE/BGREWRITEAOF时的方式:
1、SAVE:会被服务器拒绝,服务器禁止SAVE和BGSAVE同时执行,防止竞争。
2、BGSAVE:会被服务器拒绝,同时执行两个BGSAVE也会产生竞争。
3、BGREWRITEAOF:会被延迟到BGSAVE执行完毕之后执行,如果BGREWRITEAOF在执行,那再发送BGSAVE命令会被服务器直接拒绝。
注:BGSAVE和BGREWRITEAOF其实都是子进程在执行,并不会冲突,但是他们同时执行会有大量的写入操作,影响性能

RDB对过期键的处理:

Redis 4.0 内核开始进行 RDB 导出逻辑修改,导出时不再判断键空间中的 key 是否过期,对于所有 key 都会导出到 RDB 中。

1.执行save或bgsave时,过期的键不会被保存到RDB文件里。
2.在Redis主服务器启动时会载入RDB文件,如果RDB文件里有过期的键,则会忽略过期的键。
3.在Redis从服务器启动时,如果RDB文件里有过期的键,那还是会载入,但是主从在数据同步时,从服务器的数据会被清空,所以不影响。

bgsave 案例

127.0.0.1:6379> BGSAVE
Background saving started
127.0.0.1:6379> 
[root@86-5-master ~]# ll /data/redis_cluster/redis_6379/redis_6379.rdb 
-rw-r--r-- 1 root root 16885 10月 23 04:41 /data/redis_cluster/redis_6379/redis_6379.rdb
[root@86-5-master ~]# 

# 将 redis 重启服务后,数据还在,因为有了redis_6379.rdb,重启后会重新导入到内存中

[root@86-5-master ~]# redis-cli -p 6379
127.0.0.1:6379> shutdown
not connected> exit

[root@86-5-master ~]# ps -ef |grep redis
root     16229 16093  0 04:44 pts/3    00:00:00 grep --color=auto redis

[root@86-5-master ~]# redis-server /opt/redis_cluster/redis_6379/conf/redis_6379.conf 
[root@86-5-master ~]# ps -ef |grep redis
root     16263     1  0 04:45 ?        00:00:00 redis-server 127.0.0.1:6379
root     16270 16093  0 04:45 pts/3    00:00:00 grep --color=auto redis

[root@86-5-master ~]# redis-cli -p 6379
127.0.0.1:6379> keys *
   1) "k_{829}"
   2) "k_{898}"
   3) "k_{628}"

# 问题:在插入一条,在重启 redis 服务后,新插入的数据是不会存在的,因为没有保存在redis_6379.rdb

 999) "k_{308}"
1000) "k_{120}"
127.0.0.1:6379> set k_{2000} v_{2000}

127.0.0.1:6379> keys *
1000) "k_{308}"
1001) "k_{120}"

127.0.0.1:6379> shutdown
not connected> exit
[root@86-5-master ~]# redis-server /opt/redis_cluster/redis_6379/conf/redis_6379.conf
[root@86-5-master ~]# redis-cli -p 6379
127.0.0.1:6379> keys *
 999) "k_{308}"
1000) "k_{120}"

bgsave 的存储流程:

执行bgsave 后,创建一个fork进程,由子进程生成rdb文件,原来的主进程继续处理自己的工作。所以当你持久化的时候还需要额外的空间,所以比如物理机器是30G内存,一般控制 redis 使用 15G 空间,剩下的15G,一部分是Linux自己的用的,另外一部不是用来bgsave 

315c3350e7ac4e05a0101fec403f94c4.png

2、配置文件自动触发

[root@86-5-master ~]# vim /etc/redis/6379.conf # 如下则是配置持久化配置

766089cb5d81466ba1145b9cb1094a61.png

官方配置

#   In the example below the behavior will be to save:
#   after 900 sec (15 min) if at least 1 key changed
    在900秒(15分钟)后,如果至少有1个键已更改
#   after 300 sec (5 min) if at least 10 keys changed
    300秒(5分钟)后,如果至少有10个钥匙更换
#   after 60 sec if at least 10000 keys changed
    60秒后,如果至少10000个密钥已更改

save 900 1  # 在距离上一次备份的900秒(15分钟)内,期间至少有1个键已更改,则保存
save 300 10 # 在距离上一次备份的300秒(5分钟)内,期间至少有10个钥匙更换,则保存
save 60 10000 # 在距离上一次备份的60秒内,期间至少有10000个钥匙更换,则保存

解释:

主要满足上述的一个条件,则就会触发bgsave,因为bgsave是重量级的操作,将内存持久化到本地,
如果每秒都这么操作,系统就会响应不过来

修改自己的配置文件

[root@86-5-master ~]# tail -n 4 /opt/redis_cluster/redis_6379/conf/redis_6379.conf 
### 配置RBD持久化参数
save 900 1
save 300 10
save 60 10000
[root@86-5-master ~]# 

重启 redis 服务

[root@86-5-master ~]# redis-cli -p 6379 shutdown
[root@86-5-master ~]# redis-server /opt/redis_cluster/redis_6379/conf/redis_6379.conf 

注意,如下我在短时间内插入一条数据,然后关闭了redis服务,为什么数据还保存了 ,并没有触发配置文件的 save?原因是执行shtudown后,执行了两条命令,先执行bgsave,在执行 shtudown。

[root@86-5-master ~]# ll /data/redis_cluster/redis_6379/redis_6379.rdb 
-rw-r--r-- 1 root root 35885 10月 23 05:42 /data/redis_cluster/redis_6379/redis_6379.rdb

[root@86-5-master ~]# redis-cli -p 6379
127.0.0.1:6379> set k_{3000} v_{3000}
OK
127.0.0.1:6379> shutdown
not connected> exit

[root@86-5-master ~]# ll /data/redis_cluster/redis_6379/redis_6379.rdb 
-rw-r--r-- 1 root root 35904 10月 23 05:47 /data/redis_cluster/redis_6379/redis_6379.rdb
[root@86-5-master ~]# redis-server /opt/redis_cluster/redis_6379/conf/redis_6379.conf 
[root@86-5-master ~]# redis-cli -p 6379
127.0.0.1:6379> get k_{3000}
"v_{3000}"
127.0.0.1:6379> 

注意

1、当通过 killall -9 redis 的 pid 后,是将redis的所有的进程,包括父进程都杀死调。这种情况,是不会执行shtudown,所以也不会执行bgsave,所以期间不会保存数据。 类似生产的断电、异常退出redis。所以工作中一点不要使用killall -9 ,特别是数据库redis mysql mongodb,数据丢失后,如果是固态硬盘数据很难恢复

2、当通过 killall  redis 和 killall -15 redis 的 pid 后,是能够 bgsave保存数据,因为 killall  和  killall -15 会给redis发送一个信号,告诉redis退出,redis会触发shutdown,故bgsave保存数据

3、案例,先将RDB文件dump.rdb删除后,在kill redis ,在启动数据库后,数据没清空。因redis 已经启动了,内存中已经有数据了,此时删除dump.rdb后,kill redis 就是 shutdown,会做一次bgsave,所以下次重启Redis数据不会丢失

 

 

4、AOF 持久化配置

AOF持久化,以独立日志的方式记录每次写的命令,重启时在执行AOF文件中的命令打道回府数据的的目的AOF的主要解决了数据 持久化的实时性,目前已经是Redis持久化的主流方式

相当于 mysql 的 binlog,每秒把你的更新的内容操作写入到文件中(只记录你的操作,而不是实际数据)

缺点:无限制追加 binlog 会无限制增大,mysql 会设置 binlog 的最大大小,满足后会进行切割。而 Redis 会触发 rewrite进行压缩数据,但是还是比较大,恢复的时候没有RBD快

优点:最多只会损失1s内的数据

 

1、工作流程

73bc9dc31aca42439ef776d44cdae27d.png

set k1
set k2
get k2
del k1

最总结果是只有k2
但是记录的是4条操作

1、AOF会先将写入操作做记录,将所有的写入命令追加到aof_buf 缓冲区
2、AOF缓冲区根据对应的策略向硬盘做同步操作
3、随着AOF文件越来越大,需要定期(满足触发条件,比如del k1)对AOF文件,执行一个重写的过程(rewrite),把当时记录的无效的过程删除(set k1 get k1),达到压缩目录
4、当Redis服务重启的时候,可以加载AOF文件进行数据恢复

重写机制

 dc20b16c62b94346abd466cd5f90ef2e.png

 

AOF对过期键的处理:

1.当服务器以AOF持久化模式运行时,如果某个键过期,但还没有被删除时,不会对AOF文件产生影响。
2.当过期键被删除之后,程序会向AOF文件追加一条DEL命令,显示地记录该键已被删除。

如果客户端使用GET message命令,试图通过客户端访问一个过期的键,服务器会执行以下步骤:
1.从数据库中删除该过期键
2.追加一条del key命令到AOF文件
3.向执行get命令的客户端返回空回复

AOF重写对过期键的处理:
1.已过期的键不会被保存到重写后的AOF文件中

复制对过期键的处理:(为了保证主从数据的一致性)
1.主服务器删除一个过期键之后,会显式地向从服务器发送一个DEL命令,告知从服务器删除这个过期键。
2.客户端通过从服务器获取某个过期键时,是把这个过期键当成正常键返回给客户端,而且不会把它删除。
3.从服务器只有在接收到主服务器发来的DEL命令之后,才会删除过期键。(主服务器通过惰性删除、定期删除或者get了这个过期键,会发送DEL命令)

 

2、开启AOF

### 是否打开AOF日志功能
appendonly yes

### 指定文件名
appendfilename "appendonly.aof"

### 每一个命令,都立即同步到aof
appendfsync always

### 每秒写入1次
appendfsync everysec

### 写入工作交给操作系统,由操作系统判断缓存区大小,统一写入到aof
appendfsync no
# no:重写时会阻塞appendfsync;
# yes:不会阻塞appendfsync,最多可能出现30秒的数据延迟,甚至丢失30秒数据

### 如果将主节点的no-appendfsync-on-rewrite 设置为yes,添加从节点。
no-appendfsync-on-rewrite no

### aof重写触发条件,生产环境一定要修改这两个值
auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64M
# 不要再配置文件中参数后面加注释,会报错
[root@86-5-master ~]# tail -n 5 /opt/redis_cluster/redis_6379/conf/redis_6379.conf 
### 配置AOF持久化参数
# 是否打开AOF日志功能
appendonly yes
# 每一个命令,都立即同步到aof
appendfsync always
# 每秒写入1次
appendfsync everysec
# 写入工作交给操作系统,由操作系统判断缓存区大小,统一写入到aof
appendfsync no
# 指定文件名
appendfilename "appendonly.aof"

重启 Redis 服务

[root@86-5-master ~]# redis-cli -p 6379
127.0.0.1:6379> flushdb
OK
127.0.0.1:6379> shutdown
[root@86-5-master ~]# redis-server /opt/redis_cluster/redis_6379/conf/redis_6379.conf

插入一些数据

[root@86-5-master ~]# cat redis.sh 
#! /bin/bash

for i in {1..100}
do 
  redis-cli -h 127.0.0.1 set k_{$i} v_{$i} &>/dev/null
done
[root@86-5-master ~]# ./redis.sh 
[root@86-5-master ~]# redis-cli -p 6379
127.0.0.1:6379> keys*
 98) "k_{6}"
 99) "k_{49}"
100) "k_{81}"
127.0.0.1:6379> 

[root@86-5-master ~]# ll /data/redis_cluster/redis_6379/appendonly.aof 
-rw-r--r-- 1 root root 7408 10月 23 06:59 /data/redis_cluster/redis_6379/appendonly.aof
[root@86-5-master ~]# head -n 10 /data/redis_cluster/redis_6379/appendonly.aof 
*2
$6
SELECT
$1
0
*3
$3
set
$5
k_{1}
....
[root@86-5-master ~]# 


问题:如果RBD跟AOF同时存在,重启Redis服务,Redis会无条件选择只读AOF的备份内容,因为AOF是1s内存储,而RBD只会小于等于此备份,不会读RBD。并且Redis不会判断两个文件的时间选择读哪个。

二、Redis 安全认证

Redis 安全认证,只要能访问 redis,后续没有阻拦。不像 mysql 还会限制使用哪个数据库、只能查询、只能修改等等。

redis 默认开启了保护模式,只允许本地回环地址登录并访问数据库

1、protected-mode  yes/no 保护模式,是否只允许本地访问

2、Bind 指定IP 监听

3、requirepass {password} 

在 redis.conf 中创建密码,在redis中使用 AUTH {password}  才可以访问 ,如果在外面执行命令 redis-cli -a {password}

[root@86-5-master ~]# grep "requirepass" /opt/redis_cluster/redis_6379/conf/redis_6379.conf 
requirepass 123456

[root@86-5-master ~]# redis-cli -p 6379 shutdown  # 重启redis服务
[root@86-5-master ~]# redis-server /opt/redis_cluster/redis_6379/conf/redis_6379.conf 
[root@86-5-master ~]# redis-cli -p 6379
127.0.0.1:6379> set k1 v1                         # 提示没有权限
(error) NOAUTH Authentication required.
127.0.0.1:6379> AUTH 123456                       # 输入密码
OK
127.0.0.1:6379> set k2 v2                         # 在没退出此redis-cli,后续不会在输入密码
OK
127.0.0.1:6379> 

# 如果在外面执行命令 -a 密码
[root@86-5-master ~]# redis-cli -p 6379 -a 123456 get k2
Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe
"v2"
[root@86-5-master ~]# 

Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe.警告:在命令行界面上使用带有“-a”或“-u”选项的密码可能不安全

 

三、Redis 主从复制

单节点Redis的并发能力是有上限的,要进一步提高Redis的并发能力,就需要搭建主从集群,实现读写分离

eab15b1f63654e70a6083b0da424a7ec.png

 mongodb 叫做副集,最少需要三台,要仲裁、要选举

Redis 的主从比较简单2步,第一步,把从库装好第二步,执行一条语句

 

1、备机安装Redis

192.168.78.5 为主,192.168.78.6 为备

[root@86-5-master ~]# tar zcvf redis_86.5.tar.gz /opt/redis_cluster/
[root@86-5-master ~]# scp redis_86.5.tar.gz root@192.168.86.6:/opt

[root@86-6-slave ~]# tar -zxvf redis_86.5.tar.gz
[root@86-6-slave ~]# ll /opt/
-rw-r--r-- 1 root root 36639584 10月 23 08:32 redis_86.5.tar.gz
drwxr-xr-x 4 root root       57 10月 22 10:30 redis_cluster

# 注意关闭备机的防火墙和SELinux

[root@86-6-slave ~]# ll /opt/redis_cluster/
lrwxrwxrwx 1 root root   13 10月 22 10:30 redis -> redis-6.0.16/
drwxrwxr-x 7 root root 4096 10月 22 11:18 redis-6.0.16
drwxr-xr-x 5 root root   41 10月 22 10:26 redis_6379

[root@86-6-slave ~]# yum -y install centos-release-scl
[root@86-6-slave ~]# yum -y install devtoolset-9-gcc devtoolset-9-gcc-c++ devtoolset-9-binutils 
[root@86-6-slave ~]# scl enable devtoolset-9 bash
[root@86-6-slave ~]# gcc --version

[root@86-6-slave ~]# cd /opt/redis_cluster/redis
[root@86-6-slave redis]# make install   # 不需要make安装了

[root@86-5-slave ~]# mkdir /data/redis_cluster/redis_6379 -p

[root@86-6-slave redis]# grep "^bind" /opt/redis_cluster/redis_6379/conf/redis_6379.conf 
bind 127.0.0.1 192.168.86.6

[root@86-6-slave redis]# redis-server /opt/redis_cluster/redis_6379/conf/redis_6379.conf 
[root@86-6-slave redis]# redis-cli -p 6379
127.0.0.1:6379> ping
PONG

2、建立主从

[root@86-5-master ~]# redis-cli -p 6379   # 主服务有10条数据
127.0.0.1:6379> keys *
 1) "k_{9}"
 2) "k_{10}"
 3) "k_{8}"
 4) "k_{3}"
 5) "k_{4}"
 6) "k_{5}"
 7) "k_{1}"
 8) "k_{2}"
 9) "k_{6}"
10) "k_{7}"
127.0.0.1:6379> 
[root@86-6-slave redis]# redis-cli -p 6379  # 备服务器没有数据
127.0.0.1:6379> keys *
(empty array)
127.0.0.1:6379> 

同步命令 SLAVEOF,备机执行,格式(SLAVEOF  主机地址   端口号)

[root@86-6-slave redis]# redis-cli -p 6379
127.0.0.1:6379> keys *
(empty array)
127.0.0.1:6379> SLAVEOF 192.168.86.5 6379   # 其中192.168.86.5可以写域名,别忘记配置hosts
OK
127.0.0.1:6379> keys *  # 已经同步过来
 1) "k_{2}"
 2) "k_{4}"
 3) "k_{9}"
 4) "k_{6}"
 5) "k_{8}"
 6) "k_{10}"
 7) "k_{7}"
 8) "k_{1}"
 9) "k_{5}"
10) "k_{3}"
127.0.0.1:6379> 

3、查看主、从日志分析过程

第一次同步此过程是全量同步

a2cff5a39cdb4f1db7e31bea1b0a0b01.png

1、从库发起同步请求
2、主库收到请求后执行bgsave保存当前内存里的数据到磁盘
3、将持久化的RDB文件发送给从库
4、从库收到主库的持久化数据,清空从的内存/备的持久化数据清空
5、从库使用主的持久化数据并加载到内存中

redis 的 copy-on-write 机制  https://blog.csdn.net/Jerry00713/article/details/127471248?spm=1001.2014.3001.5502

4、同步是实时的

同步之后,主从的同步是实时的

[root@86-5-master ~]# redis-cli -p 6379
127.0.0.1:6379> set k1 v1
OK
127.0.0.1:6379> keys *
 1) "k_{10}"
 2) "k_{6}"
 3) "k_{4}"
 4) "k_{7}"
 5) "k_{2}"
 6) "k_{9}"
 7) "k_{8}"
 8) "k1"
 9) "k_{1}"
10) "k_{5}"
11) "k_{3}"
127.0.0.1:6379> 

[root@86-6-slave ~]# redis-cli -p 6379
127.0.0.1:6379> keys *
 1) "k1"
 2) "k_{3}"
 3) "k_{8}"
 4) "k_{1}"
 5) "k_{6}"
 6) "k_{7}"
 7) "k_{2}"
 8) "k_{4}"
 9) "k_{5}"
10) "k_{9}"
11) "k_{10}"
127.0.0.1:6379> 

5、全量同步原理

第一次是全量同步,主节点把RDB发送给从节点,从节点获取主节点

aef72b58f0dd4c46ab6e5f9a579df5fa.png

这里有两个很重要的概念:

Replication ld:简称replid,是数据集的标记,id一致则说明是同一数据集。每一个master都有唯一的replid,slave则会继承master节点的replid
offset:偏移量,随着记录在repl_baklog中的数据增多而逐渐增大。slave完成同步时也会记录当前同步的offset。如果slive的offset小于master的offset,说明slave数据落后于master,需要更新。
因此slave做数据同步,必须向master声明自己的replication id和offset,master才可以判断到底需要同步哪些数据

那么怎么判断slave是不是第一次来同步数据呢,可以用Replication ld,下图是上图的详细描述,slave建立连接后,向master发送自己的replid和offset,如果slave的replid和master的不一致,则为第一次同步数据,并返回master的replid和offsetfc0120d3583a422a971dd3aabf7f3001.png

 

简述全量同步的流程:

slave节点请求增量同步
master节点判断replid,发现不一致,拒绝增量同步
master将完整内存数据生成RDB,发送RDB到slave
slave清空本地数据,加载master的RDB
master将RDB期间的命令记录在repl_baklog,并持续将log中的命令发送给slave
slave执行接收到的命令,保持与master之间的同步

6、增量同步原理

主从第一次同步是全量同步,后续都是增量同步,即使slave重启后同步,也是执行增量同步(主备数据差异不大的情况下)

c7abb502be224232a798a94f7aa8c06d.png

需要注意的是,repl_baklog大小有上限,写满后会覆盖最早的数据。如果slave断开时间过久,导致尚未备份的数据被覆盖,则无法基于log做增量同步,只能再次全量同步。

可以从以下几个方面来优化Redis主从就集群:

在master中配置repl-diskless-sync yes启用无磁盘复制,避免全量同步时的磁盘IO
Redis单节点上的内存占用不要太大,减少RDB导致的过多磁盘IO
适当提高repl_baklog的大小,发现slave宕机时尽快实现故障恢复,尽可能避免全量同步
限制一个master上的slave节点数量,如果实在是太多slave,则可以采用主-从-从链式结构,减少master压力

 

 

 

  • 在master中配置repl-diskless-sync yes启用无磁盘复制,避免全量同步时的磁盘IO
  • Redis单节点上的内存占用不要太大,减少RDB导致的过多磁盘IO
  • 适当提高repl_baklog的大小,发现slave宕机时尽快实现故障恢复,尽可能避免全量同步
  • 限制一个master上的slave节点数量,如果实在是太多slave,则可以采用主-从-从链式结构,减少master压力

10d0e6438d2f42c0a915483b231f6c59.png

简述全量同步和增量同步区别?

全量同步:master将完整内存数据生成RDB,发送RDB到slave。后
续命令则记录在repl_baklog,逐个发送给slave。
增量同步:slave提交自己的offset到master, master获取repl_baklog中从offset之后的命令给slave
什么时候执行全量同步?

slave节点第一次连接master节点时
slave节点断开时间太久,repl_baklog中的offset已经被覆盖时
什么时候执行增量同步?

slave节点断开又恢复,并且在repl baklog中能找到offset时

7、从库只读不能写

从库:变成只能读,不能写的库。因为要保证主从的数据一致性,主可以写可以读,从库只能读。不像 mysql 可以配置互相为主互为从。

[root@86-6-slave ~]# redis-cli -p 6379
127.0.0.1:6379> set k10 v10
(error) READONLY You can't write against a read only replica.
127.0.0.1:6379> get k_{10}
"v_{10}"
127.0.0.1:6379> 


(error) READONLY You can't write against a read only replica.
(错误)只读您不能对只读副本进行写入。

8、配置文件加载主从

从库重启服务后,会断开主从关系,故从库可继续写入数据

[root@86-6-slave ~]# redis-cli -p 6379 shutdown
[root@86-6-slave ~]# ps -ef |grep redis
root      2420  2384  0 10:25 pts/0    00:00:00 grep --color=auto redis

[root@86-6-slave ~]# redis-server /opt/redis_cluster/redis_6379/conf/redis_6379.conf 
[root@86-6-slave ~]# redis-cli -p 6379
127.0.0.1:6379> keys *
 1) "k_{3}"
 2) "k_{8}"
 3) "k_{1}"
 4) "k_{6}"
 5) "k_{7}"
 6) "k_{4}"
 7) "k_{2}"
 8) "k_{5}"
 9) "k_{9}"
10) "k_{10}"
127.0.0.1:6379> set k10 v10
OK
127.0.0.1:6379> 

如何重启 redis 服务,继续保证主从关系,在配置文件中加上主从语句,但注意,重启 redis 服务就会触发全量同步

[root@86-6-slave ~]# tail -n 1 /opt/redis_cluster/redis_6379/conf/redis_6379.conf
slaveof 192.168.86.5 6379

9、主从复制全量同步的问题

主从复制过程中,从库发起同步请求、清空从的内存、备的持久化数据,清空都是很快的。但是主库收到请求后执行bgsave保存如果数据量很大几十个G、将持久化的RDB文件几十个G发送给从库、从库将bgsave导入到内存中,这个时间将会很大,所以如果第一次同步,会走全量同步,建议业务低峰期操作主从同步

 

10、查看主从状态、主动关闭主从

info replication # 查看主从状态

127.0.0.1:6379> info replication
# Replication
role:master
connected_slaves:1
slave0:ip=192.168.86.6,port=6379,state=online,offset=8914,lag=1
master_replid:c6341fb0674a5968d85bb7f78c06f2af4f2ab642
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:8914
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:1
repl_backlog_histlen:8914
127.0.0.1:6379> 

127.0.0.1:6379> info replication
# Replication
role:slave
master_host:192.168.86.5
master_port:6379
master_link_status:up
master_last_io_seconds_ago:8
master_sync_in_progress:0
slave_repl_offset:8900
slave_priority:100
slave_read_only:1
connected_slaves:0
master_replid:c6341fb0674a5968d85bb7f78c06f2af4f2ab642
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:8900
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:5895
repl_backlog_histlen:3006
127.0.0.1:6379> 

SLAVEOF no one # 主动关闭主从,在从节点 slave 上执行,因为默认redis认为自己是主

127.0.0.1:6379> SLAVEOF no one
OK
127.0.0.1:6379> info replication
# Replication
role:master
connected_slaves:0
master_replid:f8cc746686053bc20c85352f7d92232b129ee10b
master_replid2:c6341fb0674a5968d85bb7f78c06f2af4f2ab642
master_repl_offset:9236
second_repl_offset:9237
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:5895
repl_backlog_histlen:3342
127.0.0.1:6379> 

11、主从不能自动完成主从切换

主库宕机后,从库依旧尝试连接,不会停止

[root@86-5-master ~]# redis-cli -p 6379
127.0.0.1:6379> shutdown
not connected> exit
[root@86-5-master ~]# 
[root@86-6-slave ~]# tail -f /opt/redis_cluster/redis_6379/logs/redis_6379.log
2422:S 23 Oct 2022 11:40:40.873 * Non blocking connect for SYNC fired the event.
2422:S 23 Oct 2022 11:40:40.873 * Master replied to PING, replication can continue...
2422:S 23 Oct 2022 11:40:40.873 * Trying a partial resynchronization (request f8cc746686053bc20c85352f7d92232b129ee10b:9237).
2422:S 23 Oct 2022 11:40:40.873 * Master is currently unable to PSYNC but should be in the future: -NOMASTERLINK Can't SYNC while not connected with my master
2422:S 23 Oct 2022 11:40:41.882 * Connecting to MASTER 192.168.86.6:6379
2422:S 23 Oct 2022 11:40:41.882 * MASTER <-> REPLICA sync started
2422:S 23 Oct 2022 11:40:41.882 * Non blocking connect for SYNC fired the event.
2422:S 23 Oct 2022 11:40:41.882 * Master replied to PING, replication can continue...
2422:S 23 Oct 2022 11:40:41.882 * Trying a partial resynchronization (request f8cc746686053bc20c85352f7d92232b129ee10b:9237).
2422:S 23 Oct 2022 11:40:41.882 * Master is currently unable to PSYNC but should be in the future: -NOMASTERLINK Can't SYNC while not connected with my master
2422:S 23 Oct 2022 11:40:42.892 * Connecting to MASTER 192.168.86.6:6379
2422:S 23 Oct 2022 11:40:42.892 * MASTER <-> REPLICA sync started
2422:S 23 Oct 2022 11:40:42.892 * Non blocking connect for SYNC fired the event.
2422:S 23 Oct 2022 11:40:42.892 * Master replied to PING, replication can continue...

而且从库还不能写入数据,还是只能读数据,必须手动执行主从关系SLAVEOF no one,从库才能使用,但是代码连接的地址还是主的库,这就是主从复制的一些局限性

 

四、Redis 哨兵

主从复制问题:资源利用率低,主宕机,备也不能继续写只能读,故障转移需要人工介入。为了解决这个问题,官方推出哨兵技术。

1、介绍

1、Redis 主从模式下,主节点一旦发生故障不能提供服务,需要人工介入,将从节点晋升为主节点,同时 还需要修改客户端的配置,对于很多应用 场景这种方式无法接受。
Sentinel 哨兵架构解决了Redis主从人工干预问题
Redis Sentinel 是Redis 的高可用实现方案,实际生产环境中,对提高整体系统可用性非常有帮助

2、主要功能
Redis Sentinel 是一个分布式系统,Redis Sentinel 为Redis 提供高可用性,可以在没有人为干预的情况下组织某种类型的故障
Redis 的哨兵系统用于 管理多个 Redis 服务器,该系统执行以下三个任务:
1、监控:哨兵 会不断定期检查你的主服务器和从服务器是否运行正常
2、提醒:当某个监控的某个Redis 服务器出现问题,哨兵可以通过API 向管理员或者 其他应用程序发送通知

3、自动故障迁移
当一个服务器不能正常工作时,哨兵会开始一次故障迁移操作,他会将失效主服务器的其中一个从服务器升级为主服务器,并让失效主服务器的其他从服务器改为复制新的主服务器;当客户端试图连接失效的主服务器时,集群也会向客户端返回新主服务器的地址,使的集群可以使用新服务器代替失效服务器

4、哨兵也是一个redis节点,只不过不负监控,只负责通告处理故障节点转移的动作

5、代码直接连接哨兵,哨兵返回的主的IP,一旦master节点故障,返回的哨兵是下一次的master的IP。哨兵可以有多个,同时他们信息互相

2、节点规划

三台物理节点做redis一主两从端口6379
每台物理节点启动一个哨兵,三台物理节点组成哨兵集群端口26379

c6e08be2aa0c42fdb3e9da4a76b0939c.png

 a15ec167662b4f729f0d3727359eac59.png

3、部署

确定主从

slave01:

[root@db02 conf]# head -n 2 /opt/redis_cluster/redis_6379/conf/redis_6379.conf
### bind的意思不是绑定外部服务器的IP,而是redis规定允许哪些IP访问redis
bind 192.168.86.6 127.0.0.1

[root@db02 redis_cluster]# tail -n 2 /opt/redis_cluster/redis_6379/conf/redis_6379.conf 
# 主从
slaveof 192.168.86.5 6379 

[root@db02 redis_cluster]# redis-cli -p 6379 shutdown
[root@db02 redis_cluster]# redis-server /opt/redis_cluster/redis_6379/conf/redis_6379.conf
[root@db02 redis_cluster]# redis-cli -p 6379
127.0.0.1:6379> info replication
# Replication
role:slave
master_host:192.168.86.5
master_port:6379
master_link_status:up
master_last_io_seconds_ago:5

slave02:

[root@86-7-slave conf]# head -n 2 /opt/redis_cluster/redis_6379/conf/redis_6379.conf
### bind的意思不是绑定外部服务器的IP,而是redis规定允许哪些IP访问redis
bind 192.168.86.7 127.0.0.1

[root@db02 redis_cluster]# tail -n 2 /opt/redis_cluster/redis_6379/conf/redis_6379.conf 
# 主从
slaveof 192.168.86.5 6379 

[root@db02 redis_cluster]# redis-cli -p 6379 shutdown
[root@db02 redis_cluster]# redis-server /opt/redis_cluster/redis_6379/conf/redis_6379.conf
[root@86-7-slave conf]# redis-cli -p 6379
127.0.0.1:6379> info replication
# Replication
role:slave
master_host:192.168.86.5
master_port:6379
master_link_status:up
master_last_io_seconds_ago:6

哨兵也是依赖于主从架构

# mymaster 主节点别名 主节点 ip 和 端口 ,判断主节点失败,两个sentinel节点同意
# 定义谁是主节点,如果主节点失败,需要有2个哨兵决定谁是下一个主
sentinel monitor mymaster 192.168.86.5 6379 2
# 选项指定了 Sentinel 认为服务器已经断线所需的毫秒数
sentinel down-after-milliseconds mymaster 30000
# 向新的主节点发起复制操作的从节点个数,1轮训发起复制
# 发生复制的时候,一个一个进行复制
sentinel parallel-syncs mymaster 1
# 故障转移超时时间
sentinel failover-timeout mymaster 180000

master01:

[root@k8s-master ~]# mkdir -p /data/redis_cluster/redis_26379/
[root@k8s-master ~]# mkdir -p /opt/redis_cluster/redis_26379/{conf,pid,logs}
[root@k8s-master ~]# cat /opt/redis_cluster/redis_26379/conf/redis_26379.conf
bind 192.168.86.5
port 26379
daemonize yes
logfile /opt/redis_cluster/redis_26379/logs/redis_26379.log
dir /opt/redis_cluster/redis_26379
sentinel monitor mymaster 192.168.86.5 6379 2
sentinel down-after-milliseconds mymaster 3000
sentinel parallel-syncs mymaster 1
sentinel failover-timeout mymaster 18000

slave01:

[root@k8s-master ~]# mkdir -p /data/redis_cluster/redis_26379/
[root@k8s-master ~]# mkdir -p /opt/redis_cluster/redis_26379/{conf,pid,logs}
[root@k8s-master ~]# cat /opt/redis_cluster/redis_26379/conf/redis_26379.conf
bind 192.168.86.6
port 26379
daemonize yes
logfile /opt/redis_cluster/redis_26379/logs/redis_26379.log
dir /opt/redis_cluster/redis_26379
sentinel monitor mymaster 192.168.86.5 6379 2
sentinel down-after-milliseconds mymaster 3000
sentinel parallel-syncs mymaster 1
sentinel failover-timeout mymaster 18000

slave02:

[root@k8s-master ~]# mkdir -p /data/redis_cluster/redis_26379/
[root@k8s-master ~]# mkdir -p /opt/redis_cluster/redis_26379/{conf,pid,logs}
[root@k8s-master ~]# cat /opt/redis_cluster/redis_26379/conf/redis_26379.conf
bind 192.168.86.7
port 26379
daemonize yes
logfile /opt/redis_cluster/redis_26379/logs/redis_26379.log
dir /opt/redis_cluster/redis_26379
sentinel monitor mymaster 192.168.86.5 6379 2
sentinel down-after-milliseconds mymaster 3000
sentinel parallel-syncs mymaster 1
sentinel failover-timeout mymaster 18000

启动哨兵

master01:

[root@k8s-master ~]# redis-sentinel /opt/redis_cluster/redis_26379/conf/redis_26379.conf 
[root@k8s-master ~]# ps -ef |grep redis
root      1036     1  0 04:31 ?        00:00:01 redis-server 192.168.86.5:6379
root      1053     1  0 04:46 ?        00:00:00 redis-sentinel 192.168.86.5:26379 [sentinel]
root      1059   915  0 04:46 pts/0    00:00:00 grep --color=auto redis
[root@k8s-master ~]# 

slave01:

[root@db02 redis_cluster]# redis-sentinel /opt/redis_cluster/redis_26379/conf/redis_26379.conf 
[root@db02 redis_cluster]# ps -ef |grep redis
root      1219     1  0 04:39 ?        00:00:00 redis-server 192.168.86.6:6379
root      1232     1  0 04:46 ?        00:00:00 redis-sentinel 192.168.86.6:26379 [sentinel]
root      1238  1078  0 04:47 pts/0    00:00:00 grep --color=auto redis
[root@db02 redis_cluster]# 

slave02:

[root@86-7-slave conf]# redis-sentinel /opt/redis_cluster/redis_26379/conf/redis_26379.conf 
[root@86-7-slave conf]# ps -ef |grep redis
root      1011     1  0 04:40 ?        00:00:00 redis-server 192.168.86.7:6379
root      1022     1  0 04:46 ?        00:00:00 redis-sentinel 192.168.86.7:26379 [sentinel]
root      1028   907  0 04:47 pts/0    00:00:00 grep --color=auto redis
[root@86-7-slave conf]# 

查看哨兵配置文件

master01:

[root@k8s-master ~]# cat /opt/redis_cluster/redis_26379/conf/redis_26379.conf
bind 192.168.86.5
sentinel myid 944e241a003f80ac289e095b4789a4f0c5ed640f
# Generated by CONFIG REWRITE
protected-mode no
pidfile "/var/run/redis.pid"
user default on nopass ~* +@all
sentinel failover-timeout mymaster 18000
sentinel config-epoch mymaster 0
sentinel leader-epoch mymaster 0
sentinel known-replica mymaster 192.168.86.6 6379
sentinel known-replica mymaster 192.168.86.7 6379
sentinel known-sentinel mymaster 192.168.86.6 26379 be307b68008f3cded9d877a9f6648361546877b8
sentinel known-sentinel mymaster 192.168.86.7 26379 096cef202e0dd83944497b325fdf34202c952168
sentinel current-epoch 0
 

slave01:

[root@db02 redis_cluster]# cat /opt/redis_cluster/redis_26379/conf/redis_26379.conf
bind 192.168.86.6
sentinel myid be307b68008f3cded9d877a9f6648361546877b8
# Generated by CONFIG REWRITE
protected-mode no
pidfile "/var/run/redis.pid"
user default on nopass ~* +@all
sentinel failover-timeout mymaster 18000
sentinel config-epoch mymaster 0
sentinel leader-epoch mymaster 0
sentinel known-replica mymaster 192.168.86.7 6379
sentinel known-replica mymaster 192.168.86.6 6379
sentinel known-sentinel mymaster 192.168.86.5 26379 944e241a003f80ac289e095b4789a4f0c5ed640f
sentinel known-sentinel mymaster 192.168.86.7 26379 096cef202e0dd83944497b325fdf34202c952168
sentinel current-epoch 0
 

slave02:

[root@86-7-slave conf]# cat /opt/redis_cluster/redis_26379/conf/redis_26379.conf 
bind 192.168.86.7
sentinel myid 096cef202e0dd83944497b325fdf34202c952168
# Generated by CONFIG REWRITE
protected-mode no
pidfile "/var/run/redis.pid"
user default on nopass ~* +@all
sentinel failover-timeout mymaster 18000
sentinel config-epoch mymaster 0
sentinel leader-epoch mymaster 0
sentinel known-replica mymaster 192.168.86.6 6379
sentinel known-replica mymaster 192.168.86.7 6379
sentinel known-sentinel mymaster 192.168.86.6 26379 be307b68008f3cded9d877a9f6648361546877b8
sentinel known-sentinel mymaster 192.168.86.5 26379 944e241a003f80ac289e095b4789a4f0c5ed640f
sentinel current-epoch 0
[root@86-7-slave conf]# 

 

登录

redis-cli -p 26379 -h 192.168.86.5  # 指定端口号26379

 

查看状态

master:

[root@k8s-master ~]# redis-cli -p 26379 -h 192.168.86.5
192.168.86.5:26379> info Sentinel
# Sentinel
sentinel_masters:1   # 有一个master
sentinel_tilt:0
sentinel_running_scripts:0
sentinel_scripts_queue_length:0
sentinel_simulate_failure_flags:0
master0:name=mymaster,status=ok,address=192.168.86.5:6379,slaves=2,sentinels=3

slave01:

[root@db02 redis_cluster]# redis-cli -p 26379 -h 192.168.86.6
192.168.86.6:26379> info Sentinel
# Sentinel
sentinel_masters:1  # 有一个master
sentinel_tilt:0
sentinel_running_scripts:0
sentinel_scripts_queue_length:0
sentinel_simulate_failure_flags:0
master0:name=mymaster,status=ok,address=192.168.86.5:6379,slaves=2,sentinels=3
192.168.86.6:26379> 
# master01:name=mymaster代表的是此哨兵属于mymaster组下的成员,意味着可以存在多个组
# status=ok 状态无问题
# address=192.168.86.5:6379 目前的redis主节点192.168.86.5:6379
# slaves=2 有两个从节点,3个哨兵

显示组信息

192.168.86.6:26379> Sentinel masters  # 显示所有组中master节点相关的信息
1)  1) "name"
    2) "mymaster"
    3) "ip"
    4) "192.168.86.5"
    5) "port"
    6) "6379"
    7) "runid"
    8) "8702547eca7721ef088c666031dd1eb6810d44bb"
    9) "flags"
   10) "master"
   11) "link-pending-commands"
   12) "0"
   13) "link-refcount"


192.168.86.6:26379> Sentinel masters mymaster   # 显示mymaster组中master节点相关的信息

192.168.86.6:26379> Sentinel slaves mymaster   # 显示mymaster组中slaves节点相关的信息

简易信息

192.168.86.6:26379> Sentinel get-master-addr-by-name mymaster
1) "192.168.86.5"
2) "6379"
192.168.86.6:26379> 

代码通过 redis 的 Sentinel get-master-addr-by-name mymaster 中的 api 接口的信息,得知现在谁是 master

 

4、模拟redis主故障转移

关闭主节点 redis

[root@k8s-master ~]# redis-cli -p 6379 shutdown

查看哨兵日志

[root@db02 redis_cluster]# tail -f /opt/redis_cluster/redis_26379/
conf/ logs/ pid/  
[root@db02 redis_cluster]# tail -f /opt/redis_cluster/redis_26379/logs/redis_26379.log 
1232:X 31 Oct 2022 04:46:45.338 # Configuration loaded
1232:X 31 Oct 2022 04:46:45.339 * Increased maximum number of open files to 10032 (it was originally set to 1024).
1232:X 31 Oct 2022 04:46:45.339 * Running mode=sentinel, port=26379.
1232:X 31 Oct 2022 04:46:45.339 # WARNING: The TCP backlog setting of 511 cannot be enforced because /proc/sys/net/core/somaxconn is set to the lower value of 128.
1232:X 31 Oct 2022 04:46:45.345 # Sentinel ID is be307b68008f3cded9d877a9f6648361546877b8
1232:X 31 Oct 2022 04:46:45.345 # +monitor master mymaster 192.168.86.5 6379 quorum 2
1232:X 31 Oct 2022 04:46:45.350 * +slave slave 192.168.86.6:6379 192.168.86.6 6379 @ mymaster 192.168.86.5 6379
1232:X 31 Oct 2022 04:46:45.371 * +slave slave 192.168.86.7:6379 192.168.86.7 6379 @ mymaster 192.168.86.5 6379
1232:X 31 Oct 2022 04:46:47.229 * +sentinel sentinel 944e241a003f80ac289e095b4789a4f0c5ed640f 192.168.86.5 26379 @ mymaster 192.168.86.5 6379
1232:X 31 Oct 2022 04:46:49.713 * +sentinel sentinel 096cef202e0dd83944497b325fdf34202c952168 192.168.86.7 26379 @ mymaster 192.168.86.5 6379
1232:X 31 Oct 2022 05:17:58.195 # +sdown master mymaster 192.168.86.5 6379
1232:X 31 Oct 2022 05:17:58.306 # +new-epoch 1
1232:X 31 Oct 2022 05:17:58.310 # +vote-for-leader 096cef202e0dd83944497b325fdf34202c952168 1
1232:X 31 Oct 2022 05:17:58.662 # +config-update-from sentinel 096cef202e0dd83944497b325fdf34202c952168 192.168.86.7 26379 @ mymaster 192.168.86.5 6379
1232:X 31 Oct 2022 05:17:58.662 # +switch-master mymaster 192.168.86.5 6379 192.168.86.7 6379
1232:X 31 Oct 2022 05:17:58.662 * +slave slave 192.168.86.6:6379 192.168.86.6 6379 @ mymaster 192.168.86.7 6379
1232:X 31 Oct 2022 05:17:58.662 * +slave slave 192.168.86.5:6379 192.168.86.5 6379 @ mymaster 192.168.86.7 6379
1232:X 31 Oct 2022 05:18:01.671 # +sdown slave 192.168.86.5:6379 192.168.86.5 6379 @ mymaster 192.168.86.7 6379

查看哨兵配置文件

[root@k8s-master ~]# cat /opt/redis_cluster/redis_26379/conf/redis_26379.conf 
bind 192.168.86.5
port 26379
daemonize yes
logfile "/opt/redis_cluster/redis_26379/logs/redis_26379.log"
dir "/opt/redis_cluster/redis_26379"
sentinel myid 944e241a003f80ac289e095b4789a4f0c5ed640f
sentinel deny-scripts-reconfig yes
sentinel monitor mymaster 192.168.86.7 6379 2   # redis的master节点已经切换
sentinel down-after-milliseconds mymaster 3000
# Generated by CONFIG REWRITE
protected-mode no
pidfile "/var/run/redis.pid"
user default on nopass ~* +@all
sentinel failover-timeout mymaster 18000
sentinel config-epoch mymaster 1
sentinel leader-epoch mymaster 1
sentinel known-replica mymaster 192.168.86.6 6379
sentinel known-replica mymaster 192.168.86.5 6379
sentinel known-sentinel mymaster 192.168.86.6 26379 be307b68008f3cded9d877a9f6648361546877b8
sentinel known-sentinel mymaster 192.168.86.7 26379 096cef202e0dd83944497b325fdf34202c952168
sentinel current-epoch 1
[root@k8s-master ~]# 

[root@db02 redis_cluster]# cat /opt/redis_cluster/redis_26379/conf/redis_26379.conf 
bind 192.168.86.6
port 26379
daemonize yes
logfile "/opt/redis_cluster/redis_26379/logs/redis_26379.log"
dir "/opt/redis_cluster/redis_26379"
sentinel myid be307b68008f3cded9d877a9f6648361546877b8
sentinel deny-scripts-reconfig yes
sentinel monitor mymaster 192.168.86.7 6379 2
sentinel down-after-milliseconds mymaster 3000
# Generated by CONFIG REWRITE
protected-mode no

启动master01 节点,已经成为从节点

[root@k8s-master ~]# redis-server /opt/redis_cluster/redis_6379/conf/redis_6379.conf 
[root@k8s-master ~]# redis-cli -p 6379
127.0.0.1:6379> info replication
# Replication
role:slave
master_host:192.168.86.7
master_port:6379
master_link_status:up
master_last_io_seconds_ago:0
master_sync_in_progress:0
slave_repl_offset:445622
slave_priority:100
slave_read_only:1
connected_slaves:0
master_replid:259591fc8f84d8e52dea2cd62a6d3c38d561a04f
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:445622
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:436370
repl_backlog_histlen:9253
127.0.0.1:6379> 

对应的从节点么有插入的权限

[root@k8s-master ~]# redis-cli -p 6379
127.0.0.1:6379> get key
(nil)
127.0.0.1:6379> set key v1
(error) READONLY You can't write against a read only replica.
127.0.0.1:6379> 

在配置文件的最后末尾,自动添加主节点是192.168.86.7 6379

5.0版本使用REPLICAOF代替了之前版本的SLAVEOF,如果使用5.0及之后版本,则建议新命令REPLICAOF。
登录 Slave Redis 命令行,执行以下命令(重启后失效),此时在 master 中的任何数据变化都会自动地同步到 slave 中

[root@k8s-master ~]# tail -n 3 /opt/redis_cluster/redis_6379/conf/redis_6379.conf 
# Generated by CONFIG REWRITE
user default on nopass ~* +@all
replicaof 192.168.86.7 6379
[root@k8s-master ~]# 

5、模拟主机点redis、哨兵宕机

主节点的哨兵宕机后,不会影响故障的迁移,因为哨兵是一个主从的集群

[root@86-7-slave conf]# redis-cli -p 26379 -h 192.168.86.7
192.168.86.7:26379> Sentinel get-master-addr-by-name mymaster
1) "192.168.86.7"
2) "6379"
192.168.86.7:26379> exit
[root@86-7-slave conf]# redis-cli -p 26379 -h 192.168.86.7 shutdown
[root@86-7-slave conf]# ps -ef |grep redis
root      1011     1  0 04:40 ?        00:00:10 redis-server 192.168.86.7:6379
root      1059   907  0 05:34 pts/0    00:00:00 grep --color=auto redis
[root@86-7-slave conf]# redis-cli -p 6379 shutdown
[root@86-7-slave conf]# ps -ef |grep redis
root      1062   907  0 05:34 pts/0    00:00:00 grep --color=auto redis
[root@db02 redis_cluster]# redis-cli -p 26379 -h 192.168.86.6
192.168.86.6:26379> Sentinel get-master-addr-by-name mymaster
1) "192.168.86.5"
2) "6379"
192.168.86.6:26379> exit
[root@db02 redis_cluster]# redis-cli -p 6379
127.0.0.1:6379> info replication
# Replication
role:slave
master_host:192.168.86.5
master_port:6379
master_link_status:up
master_last_io_seconds_ago:1
master_sync_in_progress:0
slave_repl_offset:595550
slave_priority:100
slave_read_only:1
connected_slaves:0
master_replid:6fc3d8aa6354704bd1ff9e20f3eb3408e3dfbdd4
master_replid2:259591fc8f84d8e52dea2cd62a6d3c

6、故障迁移分析哨兵日志

[root@k8s-master ~]# redis-cli -p 26379 -h 192.168.86.5
192.168.86.5:26379> Sentinel get-master-addr-by-name mymaster
1) "192.168.86.5"
2) "6379"
192.168.86.5:26379> exit

[root@k8s-master ~]# ps -ef |grep redis
root      1053     1  0 04:46 ?        00:00:15 redis-sentinel 192.168.86.5:26379 [sentinel]
root      1085     1  0 05:21 ?        00:00:04 redis-server 192.168.86.5:6379
root      1106   915  0 05:44 pts/0    00:00:00 grep --color=auto redis
[root@k8s-master ~]# pkill redis
[root@k8s-master ~]# ps -ef |grep redis
root      1109   915  0 05:45 pts/0    00:00:00 grep --color=auto redis
[root@k8s-master ~]# 
[root@db02 redis_cluster]# echo "" >/opt/redis_cluster/redis_26379/logs/redis_26379.log 
[root@db02 redis_cluster]# tail -f /opt/redis_cluster/redis_26379/logs/redis_26379.log 

1232:X 31 Oct 2022 05:45:31.216 # +sdown master mymaster 192.168.86.5 6379   # redis主机点宕机
1232:X 31 Oct 2022 05:45:31.217 # +sdown sentinel 944e241a003f80ac289e095b4789a4f0c5ed640f 192.168.86.5 26379 @ mymaster 192.168.86.5 6379  #  redis主机点的192.168.86.5 26379哨兵宕机
1232:X 31 Oct 2022 05:45:31.305 # +new-epoch 3
1232:X 31 Oct 2022 05:45:31.307 # +vote-for-leader 096cef202e0dd83944497b325fdf34202c952168 3
1232:X 31 Oct 2022 05:45:32.304 # +odown master mymaster 192.168.86.5 6379 #quorum 2/2
1232:X 31 Oct 2022 05:45:32.304 # Next failover delay: I will not start a failover before Mon Oct 31 05:46:07 2022
1232:X 31 Oct 2022 05:45:32.318 # +config-update-from sentinel 096cef202e0dd83944497b325fdf34202c952168 192.168.86.7 26379 @ mymaster 192.168.86.5 6379
1232:X 31 Oct 2022 05:45:32.318 # +switch-master mymaster 192.168.86.5 6379 192.168.86.7 6379   # 切换master ,192.168.86.5 6379 变成 86.7 作为主节点
1232:X 31 Oct 2022 05:45:32.319 * +slave slave 192.168.86.6:6379 192.168.86.6 6379 @ mymaster 192.168.86.7 6379
1232:X 31 Oct 2022 05:45:32.319 * +slave slave 192.168.86.5:6379 192.168.86.5 6379 @ mymaster 192.168.86.7 6379
1232:X 31 Oct 2022 05:45:35.382 # +sdown slave 192.168.86.5:6379 192.168.86.5 6379 @ mymaster 192.168.86.7 6379

另一个86.6节点

config-update-from sentinel 096cef202e0dd83944497b325fdf34202c952168 192.168.86.7 26379 @ mymaster 192.168.86.5 6379   # 意思是更新自己的哨兵文件

看redis日志,就是redis主从复制的过程

[root@db02 redis_cluster]# tail -f /opt/redis_cluster/redis_6379/logs/redis_6379.log
1219:S 31 Oct 2022 05:45:32.317 * REPLICAOF 192.168.86.7:6379 enabled (user request from 'id=27 addr=192.168.86.7:45553 fd=15 name=sentinel-096cef20-cmd age=140 idle=0 flags=x db=0 sub=0 psub=0 multi=4 qbuf=353 qbuf-free=32415 argv-mem=4 obl=45 oll=0 omem=0 tot-mem=61468 events=r cmd=exec user=default')
1219:S 31 Oct 2022 05:45:32.320 # CONFIG REWRITE executed with success.
1219:S 31 Oct 2022 05:45:33.244 * Connecting to MASTER 192.168.86.7:6379
1219:S 31 Oct 2022 05:45:33.244 * MASTER <-> REPLICA sync started
1219:S 31 Oct 2022 05:45:33.245 * Non blocking connect for SYNC fired the event.
1219:S 31 Oct 2022 05:45:33.245 * Master replied to PING, replication can continue...
1219:S 31 Oct 2022 05:45:33.246 * Trying a partial resynchronization (request 6fc3d8aa6354704bd1ff9e20f3eb3408e3dfbdd4:688863).
1219:S 31 Oct 2022 05:45:33.246 * Successful partial resynchronization with master.
1219:S 31 Oct 2022 05:45:33.246 # Master replication ID changed to a6fb19db9d8f68801d2b90922d062f2fba1a3648
1219:S 31 Oct 2022 05:45:33.246 * MASTER <-> REPLICA sync: Master accepted a Partial Resynchronization.

7、手动故障转移

master01是一个 高性能物理机,由于宕机后,redis主节点转移到了slave02,在修复master01节点后,自动为备节点,如何实现再次切换为 master01 还是为主节点

权重:

哨兵的选举方式是,谁的ID大,选择谁为主

f80a4453e27e47cca1ac69cf663ea727.png

默认权重都是100,所以说他们的选举是随机的

[root@k8s-master ~]# redis-cli -p 6379 CONFIG GET slave-priority
1) "slave-priority"
2) "100"

[root@db02 redis_cluster]# redis-cli -p 6379 CONFIG GET slave-priority
1) "slave-priority"
2) "100"

[root@86-7-slave conf]# redis-cli -p 6379 CONFIG GET slave-priority
1) "slave-priority"
2) "100"

如果修改权重,选举就会偏向ID大的,所以我将slave01 和 slave02 的权重设置为0,这样master01权重还是100

[root@db02 redis_cluster]# redis-cli -p 6379 CONFIG SET slave-priority 0
OK
[root@db02 redis_cluster]# redis-cli -p 6379 CONFIG GET slave-priority
1) "slave-priority"
2) "0"

[root@86-7-slave conf]# redis-cli -p 6379 CONFIG SET slave-priority 0
OK
[root@86-7-slave conf]# redis-cli -p 6379 CONFIG GET slave-priority
1) "slave-priority"
2) "0"

手动强制发生故障转移sentinel failover mymaster,这样就会让权重高的作为 redis 的主

[root@k8s-master ~]# redis-cli -p 26379 -h 192.168.86.5 sentinel failover mymaster
OK
[root@k8s-master ~]# redis-cli -p 26379 -h 192.168.86.5 Sentinel get-master-addr-by-name mymaster
1) "192.168.86.5"
2) "6379"

注意:将slave01 和 slave02 的权重设置回来,否则下次master节点宕机,无法选举,因为master01的权重是100,依旧在master01

[root@db02 redis_cluster]# redis-cli -p 6379 CONFIG SET slave-priority 100
OK

[root@86-7-slave conf]# redis-cli -p 6379 CONFIG SET slave-priority 100
OK

五、redis的集群

 

 

 

 

 

 

 

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值