1. 主从复制概述
主从复制,是指将一台Redis服务器的数据,复制到其他的Redis服务器。前者称为主节点(master),后者称为从节点(slave);数据的复制是单向的,只能由主节点到从节点。
默认情况下,每台Redis服务器都是主节点;且一个主节点可以有多个从节点(或没有从节点),但一个从节点只能有一个主节点。
主从复制的作用
主从复制的作用主要包括:
- 数据冗余:主从复制实现了数据的热备份,是持久化之外的一种数据冗余方式。
- 故障恢复:当主节点出现问题时,可以由从节点提供服务,实现快速的故障恢复;实际上是一种服务的冗余。
- 负载均衡:在主从复制的基础上,配合读写分离,可以由主节点提供写服务,由从节点提供读服务(即写Redis数据时应用连接主节点,读Redis数据时应用连接从节点),分担服务器负载;尤其是在写少读多的场景下,通过多个从节点分担读负载,可以大大提高Redis服务器的并发量。
- 高可用基石:除了上述作用以外,主从复制还是哨兵和集群能够实施的基础,因此说主从复制是Redis高可用的基础
2. 实验环境
[root@k8s-master docker]# systemctl status firewalld iptables ● firewalld.service - firewalld - dynamic firewall daemon Loaded: loaded (/usr/lib/systemd/system/firewalld.service; disabled; vendor preset: enabled) Active: inactive (dead) Docs: man:firewalld(1) ● iptables.service - IPv4 firewall with iptables Loaded: loaded (/usr/lib/systemd/system/iptables.service; disabled; vendor preset: disabled) Active: inactive (dead) [root@k8s-master docker]# sestatus SELinux status: disabled [root@k8s-master docker]# docker -v Docker version 18.06.1-ce, build e68fc7a [root@k8s-master docker]# docker inspect redis:3.2.9|grep REDIS_VERSION "REDIS_VERSION=3.2.9",
主机说明 | 主机IP | 端口 | 哨兵端口 |
master | 192.168.12.222 | 6379 | 26379 |
slave1 | 192.168.12.223 | 6379 | 26379 |
slave2 | 192.168.12.224 | 6379 | 26379 |
3. 架构
典型的哨兵架构图如下所示:
它由两部分组成,哨兵节点和数据节点:
- 哨兵节点:哨兵系统由一个或多个哨兵节点组成,哨兵节点是特殊的redis节点,不存储数据。
- 数据节点:主节点和从节点都是数据节点。
4. 部署主从
目的:1个主节点、2个从节点和3个哨兵节点
4.1 准备
所有主从服务器上操作
①下载redis镜像
# 下载redis 3.2.9版本镜像 docker pull redis:3.2.9
②配置master redis.conf文件
[root@k8s-master docker]# mkdir /home/docker/redis/conf -p && vi /home/docker/redis/conf/redis.conf
#redis-6379.conf bind 0.0.0.0 port 6379 daemonize no #requirepass 123456 #masterauth 123456 logfile "6379.log" dbfilename "dump-6379.rdb" # AOF 数据持久化 appendonly yes appendfilename aof-6379.aof appendfsync everysec no-appendfsync-on-rewrite yes auto-aof-rewrite-percentage 100 auto-aof-rewrite-min-size 64mb
③配置slave redis.conf文件(两台slave配置一样)
[root@k8s-node1 redis]# mkdir /home/docker/redis/conf -p && vi /home/docker/redis/conf/redis.conf
#redis-6379.conf bind 0.0.0.0 port 6379 daemonize no logfile "6379.log" dbfilename "dump-6379.rdb" slaveof 192.168.12.222 6379 # AOF 数据持久化 appendonly yes appendfilename aof-6379.aof appendfsync everysec no-appendfsync-on-rewrite yes auto-aof-rewrite-percentage 100 auto-aof-rewrite-min-size 64mb
redis.conf配置介绍
bind 0.0.0.0 # 指定redis只接收来自于该IP地址的请求,如果不进行设置,那么将处理所有请求 port 6379 # redis监听的端口号 daemonize no # 是否在后台执行 logfile "6379.log" # 日志文件命名及路径 dbfilename "dump-6379.rdb" # 数据文件命名及路径 slaveof 192.168.12.222 6379 # 复制选项,slave复制对应的master appendonly yes # AOF数据持久化 appendfilename aof-6379.aof # AOF数据文件命名 appendfsync everysec # 写入策略,默认值everysec,每秒写一次(调用flush)。另外两个值,always | no,分别表示每次redis写命令之外就写文件,和由操作系统保证。always对硬盘压力大,everysec是一个平衡值,no对硬盘压力最小,但调度由系统控制,丢失数据风险最大. no-appendfsync-on-rewrite yes # 是否在后台写时同步单写,默认值no(表示需要同步).这里的后台写,表示后台正在重写文件(包括bgsave和bgrewriteaof.bgrewriteaof网上很多资料都没有涉及到。其实关掉bgsave之后,主要的即是aof重写文件了).no表示新的主进程的set操作会被阻塞掉,而yes表示新的主进程的set不会被阻塞,待整个后台写完成之后再将这部分set操作同步到aof文件中。但这可能会存在数据丢失的风险(机率很小),如果对性能有要求,可以设置为yes,仅在后台写时会异步处理命令. auto-aof-rewrite-percentage 100 aof文件增长比例,指当前aof文件比上次重写的增长比例大小。aof重写即在aof文件在一定大小之后,重新将整个内存写到aof文件当中,以反映最新的状态(相当于bgsave)。这样就避免了,aof文件过大而实际内存数据小的问题(频繁修改数据问题). auto-aof-rewrite-min-size 64mb aof文件重写最小的文件大小,即最开始aof文件必须要达到这个文件时才触发,后面的每次重写就不会根据这个变量了(根据上一次重写完成之后的大小).此变量仅初始化启动redis有效.如果是redis恢复时,则lastSize等于初始aof文件大小.
4.2 启动容器
启动master、slave容器
[root@k8s-master docker]# docker run -e TZ="Asia/Shanghai" --network=host --name redis -v /home/docker/redis/data:/data -v /home/docker/redis/conf/redis.conf:/usr/local/etc/redis/redis.conf -d --restart=always redis:3.2.9 redis-server /usr/local/etc/redis/redis.conf
4.3 测试主从复制
在master上创建key value
[root@k8s-master ~]# docker exec -it redis bash root@k8s-master:/data# redis-cli 127.0.0.1:6379> set user cmdb OK 127.0.0.1:6379> save OK 127.0.0.1:6379> get user "cmdb"
在slave上查看
[root@k8s-node2 redis]# docker exec -it redis bash root@k8s-node2:/data# redis-cli 127.0.0.1:6379> get user "cmdb"
至此,主从复制成功,另外一台slave就不看了,自信。
5. 部署哨兵
5.1 配置sentinel.conf文件
(哨兵配置都一样)
[root@k8s-node2 redis]# mkdir /home/docker/redis-sentinel -p && vi /home/docker/redis-sentinel/sentinel.conf port 26379 daemonize no protected-mode no
dir "/data" logfile "26379.log" sentinel monitor mymaster 192.168.12.222 6379 2 sentinel down-after-milliseconds mymaster 30000 sentinel parallel-syncs mymaster 1 sentinel failover-timeout mymaster 15000 bind 0.0.0.0
sentinel.conf配置介绍
daemonize yes # 后台执行
protected-mode no
# 关闭保护模式,即不使用密码就可以访问
dir "/data"
# 数据写入目录 logfile "26379.log" # 日志文件命名及路径 sentinel monitor mymaster 192.168.12.222 6379 2 # 该哨兵节点监控192.168.12.222 6379名称为mymaster的主节点,2代表需要2个哨兵节点同意才能判定主节点故障及开始故障转移 sentinel down-after-milliseconds mymaster 30000 # 指定30000毫秒后mymaster主节点被sentinel判定为不可用。默认30毫秒。 sentinel parallel-syncs mymaster 1 # 这个配置项指定了在发生failover主备切换时最多可以有多少个slave同时对新的master进行同步 # 这个数字越小,完成failover所需的时间就越长,但是如果这个数字越大,就意味着越多的slave因为replication而不可用。 # 可以通过将这个值设为 1 来保证每次只有一个slave 处于不能处理命令请求的状态。 sentinel failover-timeout mymaster 15000 #1.同一个sentinel对同一个master两次failover之间的间隔时间。 #2.当一个slave从一个错误的master那里同步数据开始计算时间。直到slave被纠正为向正确的master那里同步数据时。 #3.当想要取消一个正在进行的failover所需要的时间。 #4.当进行failover时,配置所有slaves指向新的master所需的最大时间。不过,即使过了这个超时,slaves依然会被正确配置为指向master,但是就不按parallel-syncs所配置的规则来了。
5.2 启动redis哨兵容器
docker run -e TZ="Asia/Shanghai" --name sentinel -idt --net=host -p 26379:26379 -v /home/docker/redis-sentinel/sentinel.conf:/data/sentinel.conf redis:3.2.9 redis-sentinel sentinel.conf
# 启动容器 [root@k8s-master redis]# docker run -e TZ="Asia/Shanghai" --network=host --name sentinel -v /home/docker/redis-sentinel/sentinel.conf:/data/sentinel.conf -d redis:3.2.9 --restart=always redis-sentinel sentinel.conf # 启动哨兵 [root@k8s-master redis]# docker exec -it sentinel bash root@a87dc8289c09:/data# redis-sentinel /usr/local/etc/redis/sentinel.conf root@a9bef93a1905:~# cat 26379.log _._ _.-``__ ''-._ _.-`` `. `_. ''-._ Redis 3.2.9 (00000000/0) 64 bit .-`` .-```. ```/ _.,_ ''-._ ( ' , .-` | `, ) Running in sentinel mode |`-._`-...-` __...-.``-._|'` _.-'| Port: 26379 | `-._ `._ / _.-' | PID: 21 `-._ `-._ `-./ _.-' _.-' |`-._`-._ `-.__.-' _.-'_.-'| | `-._`-._ _.-'_.-' | http://redis.io `-._ `-._`-.__.-'_.-' _.-' |`-._`-._ `-.__.-' _.-'_.-'| | `-._`-._ _.-'_.-' | `-._ `-._`-.__.-'_.-' _.-' `-._ `-.__.-' _.-' `-._ _.-' `-.__.-' 21:X 04 Jun 12:42:41.361 # WARNING: The TCP backlog setting of 511 cannot be enforced because /proc/sys/net/core/somaxconn is set to the lower value of 128. 21:X 04 Jun 12:42:41.363 # Sentinel ID is 6a0effebcae4cb8472fecb5ed939c6ca92b834cf 21:X 04 Jun 12:42:41.363 # +monitor master mymaster 192.168.12.222 6379 quorum 2 21:X 04 Jun 12:42:41.365 * +slave slave 192.168.12.223:6379 192.168.12.223 6379 @ mymaster 192.168.12.222 6379 21:X 04 Jun 12:42:41.367 * +slave slave 192.168.12.224:6379 192.168.12.224 6379 @ mymaster 192.168.12.222 6379 21:X 04 Jun 12:42:41.688 * +sentinel sentinel 93602dabb047bfd8e6559fc7f9ebb6349ef920b8 172.17.0.2 26379 @ mymaster 192.168.12.222 6379 21:X 04 Jun 12:42:42.622 * +sentinel-invalid-addr sentinel 93602dabb047bfd8e6559fc7f9ebb6349ef920b8 172.17.0.2 26379 @ mymaster 192.168.12.222 6379 21:X 04 Jun 12:42:42.622 * +sentinel sentinel 4841041d1d97f915463b33f19909e58d3678b0e0 172.17.0.2 26379 @ mymaster 192.168.12.222 6379 21:X 04 Jun 12:42:42.625 # +new-epoch 3 21:X 04 Jun 12:42:43.728 * +sentinel-address-switch master mymaster 192.168.12.222 6379 ip 172.17.0.2 port 26379 for 93602dabb047bfd8e6559fc7f9ebb6349ef920b8 21:X 04 Jun 12:42:44.680 * +sentinel-invalid-addr sentinel 4841041d1d97f915463b33f19909e58d3678b0e0 172.17.0.2 26379 @ mymaster 192.168.12.222 6379 21:X 04 Jun 12:42:44.680 * +sentinel sentinel 6a0effebcae4cb8472fecb5ed939c6ca92b834cf 172.17.0.2 26379 @ mymaster 192.168.12.222 6379 21:X 04 Jun 12:42:46.648 * +sentinel-address-switch master mymaster 192.168.12.222 6379 ip 172.17.0.2 port 26379 for 4841041d1d97f915463b33f19909e58d3678b0e0
5.3 测试
现在停止当前redis master主节点,查看哨兵是否判定故障并迁移
[root@k8s-master docker]# docker stop redis redis
[root@k8s-node1 docker]# docker exec -it sentinel bash root@a5d8273bb3a2:/data# tailf 26379.log 36:X 04 Jun 12:50:16.241 # +sdown master mymaster 192.168.12.222 6379 36:X 04 Jun 12:50:16.317 # +odown master mymaster 192.168.12.222 6379 #quorum 4/2 36:X 04 Jun 12:50:16.317 # +new-epoch 4 36:X 04 Jun 12:50:16.317 # +try-failover master mymaster 192.168.12.222 6379 36:X 04 Jun 12:50:16.318 # +vote-for-leader 93602dabb047bfd8e6559fc7f9ebb6349ef920b8 4 36:X 04 Jun 12:50:16.319 # 6a0effebcae4cb8472fecb5ed939c6ca92b834cf voted for 93602dabb047bfd8e6559fc7f9ebb6349ef920b8 4 36:X 04 Jun 12:50:16.319 # 4841041d1d97f915463b33f19909e58d3678b0e0 voted for 93602dabb047bfd8e6559fc7f9ebb6349ef920b8 4 36:X 04 Jun 12:50:16.319 # 93602dabb047bfd8e6559fc7f9ebb6349ef920b8 voted for 93602dabb047bfd8e6559fc7f9ebb6349ef920b8 4 36:X 04 Jun 12:50:16.386 # +elected-leader master mymaster 192.168.12.222 6379 36:X 04 Jun 12:50:16.386 # +failover-state-select-slave master mymaster 192.168.12.222 6379 36:X 04 Jun 12:50:16.487 # +selected-slave slave 192.168.12.223:6379 192.168.12.223 6379 @ mymaster 192.168.12.222 6379 36:X 04 Jun 12:50:16.487 * +failover-state-send-slaveof-noone slave 192.168.12.223:6379 192.168.12.223 6379 @ mymaster 192.168.12.222 6379 36:X 04 Jun 12:50:16.621 * +failover-state-wait-promotion slave 192.168.12.223:6379 192.168.12.223 6379 @ mymaster 192.168.12.222 6379 36:X 04 Jun 12:50:16.797 # +promoted-slave slave 192.168.12.223:6379 192.168.12.223 6379 @ mymaster 192.168.12.222 6379 36:X 04 Jun 12:50:16.817 # +failover-state-reconf-slaves master mymaster 192.168.12.222 6379 36:X 04 Jun 12:50:16.879 * +slave-reconf-sent slave 192.168.12.224:6379 192.168.12.224 6379 @ mymaster 192.168.12.222 6379 36:X 04 Jun 12:50:17.868 * +slave-reconf-inprog slave 192.168.12.224:6379 192.168.12.224 6379 @ mymaster 192.168.12.222 6379 36:X 04 Jun 12:50:17.868 * +slave-reconf-done slave 192.168.12.224:6379 192.168.12.224 6379 @ mymaster 192.168.12.222 6379 36:X 04 Jun 12:50:17.944 # +failover-end master mymaster 192.168.12.222 6379 36:X 04 Jun 12:50:17.944 # +switch-master mymaster 192.168.12.222 6379 192.168.12.223 6379 36:X 04 Jun 12:50:17.944 * +slave slave 192.168.12.224:6379 192.168.12.224 6379 @ mymaster 192.168.12.223 6379 36:X 04 Jun 12:50:17.944 * +slave slave 192.168.12.222:6379 192.168.12.222 6379 @ mymaster 192.168.12.223 6379 36:X 04 Jun 12:50:47.985 # +sdown slave 192.168.12.222:6379 192.168.12.222 6379 @ mymaster 192.168.12.223 6379
我们发现,哨兵已将 192.168.12.223:6379 升级为master主节点,成功。
现在恢复192.168.12.222的redis看看日志会打印什么?
[root@k8s-master docker]# docker start redis redis [root@k8s-node2 redis]# docker exec -it sentinel bash root@b4d1a95cc49f:/data# tailf 26379.log 21:X 04 Jun 12:53:59.503 # -sdown slave 192.168.12.222:6379 192.168.12.222 6379 @ mymaster 192.168.12.223 6379
192.168.12.222已经成为192.168.12.223的从节点。那么本次部署结束。
参考文章:https://www.cnblogs.com/guolianyu/p/10239913.html
https://www.cnblogs.com/kismetv/p/9236731.html
https://blog.csdn.net/qq_24641227/article/details/93520057