Redis M/S + Keepalived 主从备份高可用
目录
文章目录
- 目录
- 高可用
- Redis 的高可用
- Redis 主从复制配置
- Redis 主从切换(手动方式)
- SLAVEOF 指令
- Redis M/S + Keepalived
- 故障的 3 种情况
- 主节点配置 keepalived.conf
- 从节点配置 keepalived.conf
- redis_check.sh
- redis_master.sh
- redis_backup.sh
- redis_fault.sh
- redis_stop.sh
高可用
高可用是指服务器可以正常访问的时间,衡量的标准是在多长时间内可以提供正常服务(99.9%、99.99%、99.999% 等等)。而在 Redis 的语境中,高可用的含义似乎要更宽泛一些,除了保证提供正常服务(如:主从分离、快速容灾技术等),还需要考虑数据容量的扩展、数据安全不会丢失等。
Redis 的高可用
在 Redis 中,实现高可用的技术主要包括持久化、复制、哨兵和集群:
- 持久化:即将数据存储在硬盘,保证数据不会因进程退出而丢失,主要作用是数据备份。
- 复制:主要实现了数据的多机备份以及对于读操作的负载均衡和简单的故障恢复。缺陷是故障恢复无法自动化、写操作无法负载均衡、存储能力受到单机的限制。
- 哨兵:在复制的基础上,哨兵实现了自动化的故障恢复。缺陷是写操作无法负载均衡、存储能力受到单机的限制。
- 集群:通过集群,Redis 解决了写操作无法负载均衡以及存储能力受到单机限制的问题,实现了较为完善的高可用方案。
本文主要讨论通过 Redis 的 “复制” 技术支撑的高可用方案。
Redis 主从复制配置
Redis 主从复制实际上就是将 MASTER 节点的数据,复制到其他 SLAVE 节点去进行存储。
修改关键配置:
- MASTER
bind 0.0.0.0
port 6379
slave-serve-stale-data yes
slave-read-only no
...
- SLAVE
bind 0.0.0.0
port 6379
slave-serve-stale-data yes
slave-read-only no
slaveof 172.16.81.140 6379
...
可以看见,Redis 主从配置中最主要的一个项目就是 slaveof,他指定了 SLAVE 节点与 MASTER 节点的从属关系。
重启 Redis Daemon 之后,查看配合是否有生效:
- MASTER
$ redis-cli
127.0.0.1:6379> INFO
...
# Replication
role:master
connected_slaves:1
slave0:ip=172.18.22.202,port=6379,state=online,offset=108458,lag=0
master_repl_offset:108458
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:22541
repl_backlog_histlen:85918
- SLAVE
$ redis-cli
127.0.0.1:6379> INFO
...
# Replication
role:slave
master_host:172.18.22.204
master_port:6379
master_link_status:up
master_last_io_seconds_ago:1
master_sync_in_progress:0
slave_repl_offset:108654
slave_priority:100
slave_read_only:0
connected_slaves:0
master_repl_offset:0
repl_backlog_active:0
repl_backlog_size:1048576
repl_backlog_first_byte_offset:0
repl_backlog_histlen:0
可以看见 MASTER 和 SLAVE 当前是互相认证的:在 MASTER 上可以查看分别由哪些 SLAVE,状态如何,复制(Replication)的配置如何;在 SLAVE 上可以查看自己的 MASTER 是谁,状态如何,自己的权重是多少,是否只读。如果是只读的话,SLAVE 将无法写入任何数据:
127.0.0.1:6379> SET test2 123
(error) READONLY You can't write against a read only slave.
下面进行一次同步测试:
- MASTER
$ redis-cli
127.0.0.1:6379> SET test1 123
OK
- SLAVE
$ redis-cli
127.0.0.1:6379> GET test1
"123"
Redis 主从切换(手动方式)
当 MASTER 宕机时,最简单的恢复方式就是使用手动切换的方式,手动的将一台从节点切换成主节点。手动方式显然是不推荐的,但我们不放了解一下。
- 关闭 MASTER。
systemctl stop redis
- 手动将 SLAVE 设置成主节点。
$ redis-cli
127.0.0.1:6379> slaveof no one
127.0.0.1:6379> INFO
...
# Replication
role:master
connected_slaves:0
master_repl_offset:1177
repl_backlog_active:0
repl_backlog_size:1048576
repl_backlog_first_byte_offset:0
repl_backlog_histlen:0
- 新的数据写入到 SLAVE。
127.0.0.1:6379> SET test4 123
OK
127.0.0.1:6379> SET test5 123
OK
127.0.0.1:6379> SET test6 123
OK
下面为执行数据恢复的步骤:
- 持久化 SLAVE 的数据。
127.0.0.1:6379> save
OK
- 拷贝从节点的 dump.rdb 文件到主节点中。
scp /var/lib/redis/dump.rdb root@<master>:/var/lib/redis/dump.rdb
- 重启 MASTER 和 SLAVE,发现 MASTER 和 SLAVE 的数据又保持了同步,而且身份角色也恢复到了初始状态。这是因为:当 Redis 重启时,手动执行的主从切换设置将会失效,还原为初始状态,因为我们在上面已写入了 SLAVE 的配置文件。
SLAVEOF 指令
SLAVEOF 指令指定了当前 Redis 实例是从属于某个 MASTER 的 SLAVE。如果这个指令在配置文件中写死,那么实例重启后就永远是 SLAVE,除非有哨兵将它提升为 MASTER,或手动执行指令 SLAVEOF NO ONE。
在本文讨论的 M/S 场景中,则需要脚本或手动执行。而在哨兵模式的场景中,这个指令会被哨兵动态地从配置文件中添加或删除,它的存在与否最好交由哨兵决定。需要注意的是,该指令不应该写死在 “子文件” 中,因为子文件中写死的指令是无法被哨兵移除的,这将导致 SLAVE 每次重启后都是 SLAVE。这个问题很难排查。
Redis M/S + Keepalived
M/S + Keepalived 是一个非常经典的 Redis 高可用方案,是哨兵模式出现之前的主流方案。现在常见与双节点的 Redis 高可用需求场景(哨兵模式需要三节点)。此方案使用了 Redis 原生的主从复制机制结合 Keepalived 的 VRRP 技术:Redis M/S 提供数据持久化和备份策略,Keepalived 提供了健康检查、监控告警、故障切换以及统一的 VIP 访问接口。
优点:
- 高可靠性。双机主备架构、数据持久化以及备份策略。
- 秒级切换。
- 故障切换对应用透明。
- 部署简单,维护成本低。
缺点:
- Redis 主从切换需要自定义脚本实现。
- Keepalived 存在主从脑裂风险。
故障的 3 种情况
Keepalived 挂了,同时 Redis 也挂了,这样的话 VIP 飘走之后,是不需要进行 Redis 数据同步的,因为 Redis 已经挂了,你也无法去 MASTER 上同步,会损失已经写在 MASTER 上但还没同步到 SLAVE 上面的这部分数据。
Keepalived 挂了,Redis 没挂,这时 VIP 飘走后,Redis 的 MASTER/SLAVE 还是老的对应关系。默认情况下,会把数据写入 Redis SLAVE 中,而不会同步到 MASTER 上去,这时就要借助监控脚本反转 Redis 的身份关系了。并且需要预留一点时间里进行数据同步,然后切换主从关系。
Keepalived 没挂,Redis 挂了,这时根据监控脚本检测到 Redis 挂了,马上降低 Keepalived Master 的优先级,导致 VIP 飘走,情况和第二种一样,也是需要进行数据同步,然后 Redis 主从切换。
主节点配置 keepalived.conf
! Configuration File for keepalivedglobal_defs {notification_email {acassen@firewall.locfailover@firewall.locsysadmin@firewall.loc}notification_email_from Alexandre.Cassen@firewall.locsmtp_server 192.168.200.1smtp_connect_timeout 30router_id redis01
}vrrp_script chk_redis {script "/etc/keepalived/script/redis_check.sh"interval 2
}vrrp_instance VI_1 {state MASTERinterface eno16777984virtual_router_id 51priority 100advert_int 1authentication {auth_type PASSauth_pass 1111}track_script {chk_redis}virtual_ipaddress {172.16.81.139}notify_master /etc/keepalived/script/redis_master.shnotify_backup /etc/keepalived/script/redis_backup.shnotify_fault /etc/keepalived/script/redis_fault.sh notify_stop /etc/keepalived/script/redis_stop.sh
}
- notify_master:Keepalived 切换为主节点时执行的脚本。
- notify_backup:Keepalived 切换为从节点时执行的脚本。
- notify_fault:Keepalived 进程故障时执行的脚本。
- notify_stop:keepalived 进程停止前执行的脚本。
- nopreempt:设置不抢占,这里只能设置在 state 为 backup 的节点上,而且这个节点的优先级必须别另外的高。
从节点配置 keepalived.conf
! Configuration File for keepalivedglobal_defs {notification_email {acassen@firewall.locfailover@firewall.locsysadmin@firewall.loc}notification_email_from Alexandre.Cassen@firewall.locsmtp_server 192.168.200.1smtp_connect_timeout 30router_id redis02
}vrrp_script chk_redis {script "/etc/keepalived/script/redis_check.sh"interval 2
}vrrp_instance VI_1 {state BACKUPinterface eno16777984virtual_router_id 51priority 99advert_int 1authentication {auth_type PASSauth_pass 1111}track_script {chk_redis}virtual_ipaddress {172.16.81.139}notify_master /etc/keepalived/script/redis_master.shnotify_backup /etc/keepalived/script/redis_backup.shnotify_fault /etc/keepalived/script/redis_fault.sh notify_stop /etc/keepalived/script/redis_stop.sh
}
redis_check.sh
#!/bin/bashCHECK=`/usr/local/bin/redis-cli PING`
if [ "$CHECK" == "PONG" ] ;thenecho $CHECKexit 0
else echo $CHECKservice keepalived stop # 确保让出 MASTERexit 1
fi
keepalived 会根据该监控脚本的返回码来调整优先级:
- 如果脚本返回码为 0,并且 weight > 0,则优先级相应的增加;
- 如果脚本返回码为非 0,并且 weight < 0,则优先级相应的减少;
- 其他情况,原本配置的优先级不变,即配置文件中 priority 对应的值。
NOTE:
- 优先级不会不断的提高或者降低;
- 可以编写多个检测脚本并为每个检测脚本设置不同的 weight(在配置中列出就行);
- 不管提高优先级还是降低优先级,最终优先级的范围是在 [1, 254],不会出现优先级小于等于 0 或者优先级大于等于 255 的情况;
- 配置 nopreempt ,避免正常情况下做无谓的切换。
redis_master.sh
#!/bin/bash
REDISCLI="/usr/local/redis/bin/redis-cli -a 123456"
LOGFILE="/var/log/keepalived-redis-state.log"sleep 15echo "[master]" >> $LOGFILE
date >> $LOGFILE
echo "Being master...." >>$LOGFILE 2>&1
echo "Run SLAVEOF cmd ...">> $LOGFILE$REDISCLI SLAVEOF 172.16.81.141 6379 >>$LOGFILE 2>&1 # 先同步数据
if [ $? -ne 0 ];thenecho "data rsync fail." >>$LOGFILE 2>&1
elseecho "data rsync OK." >> $LOGFILE 2>&1
fisleep 10 # 延迟 10 秒以后待数据同步完成后再取消同步状态 echo "Run SLAVEOF NO ONE cmd ...">> $LOGFILE$REDISCLI SLAVEOF NO ONE >> $LOGFILE 2>&1 # 切换为 MASTER
if [ $? -ne 0 ];thenecho "Run SLAVEOF NO ONE cmd fail." >>$LOGFILE 2>&1
elseecho "Run SLAVEOF NO ONE cmd OK." >> $LOGFILE 2>&1
fi
redis_backup.sh
#!/bin/bash
REDISCLI="/usr/local/redis/bin/redis-cli -a 123456"
LOGFILE="/var/log/keepalived-redis-state.log"echo "[backup]" >> $LOGFILE
date >> $LOGFILEecho "Being slave...." >>$LOGFILE 2>&1
sleep 15 # 延迟 15 秒待数据被对方同步完成之后再切换主从角色
echo "Run SLAVEOF cmd ...">> $LOGFILE$REDISCLI SLAVEOF 172.16.81.141 6379 >>$LOGFILE 2>&1 # 切换为 BACKUP
redis_fault.sh
#!/bin/bash LOGFILE=/var/log/keepalived-redis-state.logecho "[fault]" >> $LOGFILE
date >> $LOGFILE
redis_stop.sh
#!/bin/bash LOGFILE=/var/log/keepalived-redis-state.logecho "[stop]" >> $LOGFILE
date >> $LOGFILE
Redis M/S + Keepalived 主从备份高可用相关推荐
- mysql keepalived主从_mysql高可用架构之(一)基于自身主从复制&keepalived实现
系统环境及架构 #主机名 系统版本 mysql版本 ip地址 mysqlMaster centos7.4 mysql5.7 192.168.1.42 mysqlSlave centos7.4 mysq ...
- 路由器snmp配置_基于keepalived配置数据库主从实现高可用
基于keepalived配置数据库主从实现高可用 使用keepalived来监听端口,实现数据库的高可用.实现效果,其中一台数据库服务器突然出故障或关机时,应该不影响应用正常运行,等待服务器启动之后, ...
- 【7W字长文】使用LVS+Keepalived实现Nginx高可用,一文搞懂Nginx
往期文章一览 分布式会话与单点登录SSO系统CAS,包含完整示例代码实现 [15W字长文]主从复制高可用Redis集群,完整包含Redis所有知识点 使用LVS+Keepalived实现Nginx高可 ...
- 【Keepalived】开源高可用的Keepalived
Keepalived 一.What is Keepalived? 二.什么是高可用? 三.keepalived故障转移实现高可用 四.keepalived运行环境 1.下载安装 2.启动keepali ...
- MySQL共享存储主备模式利用Keepalived实现双机高可用
简单介绍 先简单说下MySQL主从复制与keepalived模式和MySQL共享存储与Keepalived模式 MySQL共享存储主备模式不同于MySQL主主复制模式,MySQL主主是利用MySQL自 ...
- Keepalived实现mysql高可用
文章目录 0.参考资料 1.实现mysql双主高可用 1.1.高可用方案选择 1.2.双主基础上实现高可用 1.2.1.安装 1.2.2.主从配置文件 2.原理介绍(整理自网络) 0.参考资料 官方地 ...
- Nginx+Keepalived实现站点高可用
2019独角兽企业重金招聘Python工程师标准>>> Nginx+Keepalived实现站点高可用 seanlook 2016-05-18 14:56:23 浏览2407 评论2 ...
- oracle 实现HA,使用KeepAlived实现HAProxy高可用
使用KeepAlived实现HAProxy高可用 在以前的文章中我们实现了使用HAProxy来转发读请求到后端多台mysql从库上,但是对于HAProxy的高可用(HA)需 求没有配置,本文在以前的基 ...
- Keepalived+Nginx实现高可用,反向代理---Keepalived安装及相关配置
[前言] 在博文<智能一代云平台(十五):Keepalived+Nginx实现高可用,反向代理---Nginx安装及配置>中介绍了Nginx的安装及相关配置的信息,由于篇幅原因不能用一篇博 ...
最新文章
- Android Websites
- IDEA中快捷键修改成和eclipse一样
- python可以做什么项目-适合Python 新手的5大练手项目,你练了么?
- Core Text 入门
- 内核初始化kernel.asm
- linux——利用脚本实现虚拟机半自动安装及快照
- 华为笔试题 简答错误记录(字符串处理,好题!!!)
- oracle服务器文件有哪些,Oracle服务器参数文件维护的技巧有哪些呢?
- ubtunu开机黑屏无桌面解决方法
- java截取文件名.后的字符串
- Python---PDF转JPG图片
- 实验|trunk的配置
- 阿里云虚拟主机备案期间网站调试
- 成长,从你发现自己写的代码很LOW开始
- The Simplest Classifier: Histogram Comparison (最简单的分类器:直方图比较)
- VUE+ElementUI实现div滚动条替换
- GameCenter 使用指南
- 利用Excel动态图表----------使用offset(),match()多种控件,实现筛选作图
- ‘’和“”区别和使用
- 【花雕动手做】有趣好玩的音乐可视化系列项目(27)--磁搅LED水旋灯
热门文章
- Playmaker Input篇教程之Playmaker购买下载和导入
- 明明白白学C#第0章准备工作
- C#游戏开发快速入门 2.1 构建游戏场景
- php 自留地,重蔚自留地php基本语法-函数(附代码)
- 自定义变量 配置文件_跟我一起学.NetCore之自定义配置源热更新对象绑定
- centos7 docker-compose安装_Docker Compose 搭建 Redis Cluster 集群环境
- pythonsys模块介绍_sys 模块介绍 - Clarkhedi的个人空间 - OSCHINA - 中文开源技术交流社区...
- java gui 选项_【Java-GUI】04 菜单
- 基于连通域字符分割的流程_基于改进连通域算法的车牌字符分割方法
- mysql 中lock wait_应用中MYSQL 报错Lock wait timeout exceeded; try restarting transaction