redis 运维讲解02

news2024/11/15 22:39:44

一、数据持久化 

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的集群

 

 

 

 

 

 

 

 

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

浏览器相关知识

本文主要进行浏览器相关知识的整理总结。 一、浏览器的存储 浏览器的存储包括cookie&#xff0c;session&#xff0c;LocalStorage&#xff0c;sessionStorage&#xff0c;indexedDB。 作用cookiesessionsessionStorageLocalStorageindexedDB储存时间设置或不设置默认30分钟仅…

就只有这么简单?全自动加药装置远程维护解决方案

一、行业背景说起工业生产&#xff0c;给人们的普遍印象都是浓烟&#xff0c;废水&#xff0c;环境污染。尤其是石油、化工、发电厂等一些具有大型设备的地方&#xff0c;确实常常都会有浓烟和污水产出&#xff0c;让人看了恨不得离得越远越好&#xff01;但是随着现代科技的发…

java和vue开发的电子书系统自动检测敏感词小说网站

简介 电子书系统&#xff0c;注册用户上传txt&#xff0c;系统自动检测敏感词汇并且自动生成章节。管理员审核电子书&#xff0c;管理电子书分类和用户&#xff0c;评论等。注册用户可以搜索浏览电子书&#xff0c;在线阅读和下载电子书。 演示视频&#xff1a;https://www.b…

Java设计模式-单例模式Singleton

介绍 所谓类的单例设计模式&#xff0c;就是采取一定的方法保证在整个的软件系统中&#xff0c;对某个类只能存在一个对象实例&#xff0c;并且该类只提供一个取得其对象实例的方法(静态方法)。 比如 Hibernate 的 SessionFactory&#xff0c;它充当数据存储源的代理&#xff0…

系分 - 案例分析 - 系统规划

个人总结&#xff0c;仅供参考&#xff0c;欢迎加好友一起讨论 文章目录系分 - 案例分析 - 系统规划典型例题 1题目描述参考答案典型例题 2题目描述参考答案典型例题 3题目描述参考答案系分 - 案例分析 - 系统规划 典型例题 1 题目描述 某软件开发企业受对外贸易公司委托开发…

STM32F429连接USB飞行摇杆

本文介绍如何使用stm32连接usb接口的飞行摇杆。开发环境硬件: STM32F429IGT6开发板&#xff0c;USB接口的飞行摇杆。软件&#xff1a;STM32CubeIDE 1.11仿真器&#xff1a;stlink参考书&#xff1a;《圈圈教你玩USB》USB设备描述符一个USB设备只有一个设备描述符。USB主机通过不…

springboot3.0+GraalVM搭建云原生环境

1.首先下载安装GraalVM 选择java17.windows(amd64),最好选择VPN下载 下载完成以后解压&#xff0c;如图 然后配置环境变量 配置GRAALVM_HOME&#xff0c;如图 然后在PATH里面添加 %GRAALVM_HOME%\bin 配置完成以后&#xff0c;在cmd里面执行java -version,可以看到jdk已经是…

Apache Shiro教程(2)

Shiro实战教程 1、权限的管理 1.1、什么是权限管理 1、基本上涉及到用户参与的系统都需要进行权限管理&#xff0c;权限管理属于系统安全的范畴&#xff0c;权限管理实现对用户访问系统的控制&#xff0c;按照安全规则或者安全策略控制用户可以访问而且只能访问自己被授权的资…

【 uniapp - 黑马优购 | 加入购物车】如何配置 vuex、加入购物车功能并持久化

个人名片&#xff1a; &#x1f43c;作者简介&#xff1a;一名大二在校生&#xff0c;讨厌编程&#x1f38b; &#x1f43b;‍❄️个人主页&#x1f947;&#xff1a;小新爱学习. &#x1f43c;个人WeChat&#xff1a;hmmwx53 &#x1f54a;️系列专栏&#xff1a;&#x1f5bc…

ABP VNext 的日志机制 + SeriLog

** ABP VNext 的日志机制 ** 正用ABP VNext做个系统&#xff0c;由于框架默认带来日志处理机制&#xff0c;开发阶段基本能用&#xff0c;也一直没有去动它&#xff0c;快要上线了&#xff0c;思考了一下正式环境的日志管理流程&#xff0c;由于系统不大&#xff0c;预计访问…

第一章.机器学习基本概念

第一章.机器学习基本概念 1.1 第一章.机器学习基本概念 机器学习的本质就是&#xff1a;寻找一个函数。 1.不同种类的函数 1).Regression&#xff1a;The function outputs a scalar 说明:根据今天的PM2.5的一些参数来预测明天PM2.5值 2).Classification:Given option(classes…

STL vector 模拟实现

vector 概述 vector 的数据结构安排及操作方式&#xff0c;与原生数组十分相似&#xff0c;两者唯一的差别在于空间运用的灵活性。原生数组是静态空间&#xff0c;一旦配置了就不能改变大小&#xff1b;vector 是动态空间&#xff0c;可以在插入过程中动态调整空间大小。vecto…

Pivoting跳板攻击

跳板攻击&#xff08;Pivoting&#xff09;是Meterpreter提供的一种攻击方法&#xff0c;允许从Meterpreter终端攻击网络中的其他系统。假如攻击者成功的入侵了一台主机&#xff0c;他就可以任意的利用这台机器作为跳板攻击网络中的其他系统&#xff0c;或者访问由于路由问题而…

【ROS】tf2_geometry_msgs 出现 No module named ‘PyKDL‘

参考文章&#xff1a; PyCharm单独安装PyKDL 如何在基于python3的conda虚拟环境中从头编译PyKDL 1. 问题描述 import PyKDL ModuleNotFoundError: No module named PyKDL这是由于使用的环境中不存在 PyKDL 导致的&#xff0c;实际上 PyKDL 在装 ROS 的时候是一起装上了&#x…

基于Springboot搭建java项目(十八)——Java线程池原理和运用

​ 在上一篇博客中有说到线程的基本原理和用法&#xff0c;其实Java中开辟出了一种管理线程的概念&#xff0c;这个概念叫做线程池&#xff0c;线程池的好处&#xff0c;就是可以方便的管理线程&#xff0c;也可以减少内存的消耗。那么&#xff0c;我们应该如何创建一个线程池&…

JAVASE 基础知识点回顾

1.关键字Static static 有三个特点&#xff0c;这边先阐述一下&#xff0c;后面代码也会展示 static 可以修饰方法(静态方法)、成员变量(静态变量)&#xff0c;修饰不了类请注意&#xff01;随着类的加载而加载&#xff0c;优先于对象存在&#xff0c;说人话就是不new 对象也…

电机专用SVPWM算法实现

SH33F2811包含三相电机的空间矢量脉宽调制&#xff08;Space Vector Pulse Width Modulation&#xff0c;SVPWM&#xff09;算法&#xff0c;对应于交流感应电机或永磁同步电机中的三相电压源逆变器的功率器件的一种特殊的开关触发顺序和脉宽大小的组合。这种开关触发顺序和组合…

k8s部署 wiki.js ,带中文分词

官网 https://js.wiki/ https://docs.requarks.io/install/docker-desktop k8s postgres 安装 因为包含中文分词&#xff0c;要在原版的基础上增加分词插件。 这里直接使用别人已经 制作好的镜像 github 地址 : https://github.com/abcfy2/docker_zhparser 镜像地址&#x…

【 java 集合】Map 接口常用方法总结

&#x1f4cb; 个人简介 &#x1f496; 作者简介&#xff1a;大家好&#xff0c;我是阿牛&#xff0c;全栈领域优质创作者。&#x1f61c;&#x1f4dd; 个人主页&#xff1a;馆主阿牛&#x1f525;&#x1f389; 支持我&#xff1a;点赞&#x1f44d;收藏⭐️留言&#x1f4d…

【面试】70道Spring Boot面试题答案

文章目录PartAPartB更多请参考来源PartA 1 什么是springboot &#xff1f; 用来简化spring应用的初始搭建以及开发过程 使用特定的方式来进行配置&#xff08;properties或yml文件&#xff09; 创建独立的spring引用程序 main方法运行 嵌入的Tomcat 无需部署war文件 简化m…