1. 热备方案
硬件:server两台,分别用于master-redis及slave-redis
软件:redis、keepalived
实现目标:
- 由keepalived对外提供虚拟IP(VIP)进行redis访问
- 主从redis正常工作,主负责处理业务,从进行数据备份
- 当主出现故障时,从切换为主,接替主的业务进行工作
- 当主恢复后,拷贝从的数据,恢复主身份,从恢复从身份
数据采用aof方式进行持久化存储,秒级备份,当出现故障后,损失数据不超过1s
Keepalived提供以下服务:
- 对用户提供VIP访问,屏蔽redis实际IP,当主机出现故障,仍可用VIP访问到从。
- 对redis状态进行监控,将监控频率设置在1s。当主出现故障后能及时处理,切换从机提供业务。
2. 环境准备
利用虚拟机进行测试,安装ubuntu,安装完成后克隆ubuntu,利用两个虚拟机来构造服务器环境。
在两台虚拟机分别执行sudo apt-get redis-server和sudo apt-get keepalived安装redis和keepalived软件。
配置两个虚拟机的redis主从关系:
1. 保证两个虚拟机ip不一致且能互相ping通
2. 打开slave下/etc/redis/redis.conf文件
3. 找到slaveof配置项配置指定的master ip port,有密码则还需配置masterauth
4. Save “”取消注释,关闭RDB方式,配置appendonly项,配置为yes,持久化采用AOF方式
5. 主从执行service redis restart重启下redis服务。
6. redis-cli info查看主从redis信息。
Maste:
Slave:
测试主从环境:
Master:
Slave:
查看默认db目录/var/lib/redis/
3. keepalived配置
keepalived配置包含两部分,一部分是keepalived配置文件,另一部分是脚本。
主从/etc/keepalived/目录下新建keepalived.conf文件。
Keepalived配置文件
Master:
1 vrrp_script chk_redis { 2 3 script "/etc/keepalived/scripts/redis_check.py" ###监控脚本 4 5 interval 1 ###监控时间设置为1s 6 7 } 8 9 vrrp_instance VI_1 { 10 11 state MASTER ###设置为MASTER 12 13 interface ens33 ###监控网卡 14 15 virtual_router_id 51 16 17 priority 101 ###权重值 18 19 authentication { 20 21 auth_type PASS ###加密 22 23 auth_pass redis ###密码 24 25 } 26 27 track_script { 28 29 chk_redis ###调用上面定义的chk_redis 30 31 } 32 33 virtual_ipaddress { 34 35 192.168.133.188 ###对外的虚拟IP 36 37 } 38 39 notify_master /etc/keepalived/scripts/redis_master.py 40 41 notify_backup /etc/keepalived/scripts/redis_backup.py 42 43 notify_fault /etc/keepalived/scripts/redis_fault.py 44 45 notify_stop /etc/keepalived/scripts/redis_stop.py 46 47 }Slave:
与master基本一致,修改以下两项即可
1 state MASTER ###设置为MASTER 2 3 state BACKUP ###设置为BACKUP 4 5 priority 101 ###权重值 6 7 priority 100 ###slave权重值比master小监控脚本包含5个,主要关注redis_check.py 、redis_master.py和redis_backup.py。
- redis_check.py用于监控redis运行状态,反馈redis是否运行正常信息。
- redis_master.py将当前redis切换为master
- redis_backup.py将当前redis切换为slave
keepalived根据配置的监控时间,执行redis_check.py查看redis运行状态,出现异常则主从依次调用脚本完成主从倒换。将这些脚本放在/etc/keepalived/scripts/目录下,并且给所有脚本加上执行权限chmod +x *
redis_check.py主从内容一致:
1 #!/usr/bin/python 2 3 import os 4 5 import sys 6 7 import time 8 9 PING = ‘redis-cli ping‘ #redis ping command, observe network state 10 11 os.chdir("/etc/redis/") #set log file path 12 13 fp = open("redis_dump.log",‘a‘) #open log file with append mode 14 15 result = os.system(PING) #exec command 16 17 if 0 == result: #network state ok 18 19 logtime = time.strftime("%Y-%m-%d %H:%M:%S",time.localtime()) 20 21 fp.write("[check]" + logtime + ":" + ‘redis running!\n‘) 22 23 sys.exit(0) 24 25 else: 26 27 logtime = time.strftime("%Y-%m-%d %H:%M:%S",time.localtime()) 28 29 fp.write("[check]" + logtime + ":" + ‘redis stop service!\n‘) 30 31 sys.exit(1) 32 33 fp.close()网络状态良好时表示redis运行正常,日志记录可以注释,防止日志打印过多。在redis配置鉴权需修改所有的命令执行脚本内容,带上鉴权信息。
当网络不通,即redis服务挂掉后,可以增加os.system(“service redis start”)或者os.system(“service redis restart”)尝试重启redis服务。
redis_master.py主机配置:
1 #!/usr/bin/python 2 3 import os 4 5 import time 6 7 SLAVEOF = ‘redis-cli slaveof 192.168.133.131 6379‘ #backup data form slave 8 9 SLAVENO = ‘redis-cli slaveof no one‘ #being master 10 11 os.chdir("/etc/redis/") #set log file path 12 13 fp = open("redis_dump.log",‘a‘) #open log file with append mode 14 15 result = os.system(SLAVEOF) #exec command 16 17 logtime = time.strftime("%Y-%m-%d %H:%M:%S",time.localtime()) #get time info 18 19 if 0 == result: #backup data from slave 20 21 fp.write("[master]" + logtime + ":" + ‘start copy data from slave!\n‘) 22 23 else: 24 25 fp.write("[master]" + logtime + ":" + ‘copy data from slave falue!\n‘) 26 27 time.sleep(10) #set backup time 28 29 result = os.system(SLAVENO) #being master 30 31 logtime = time.strftime("%Y-%m-%d %H:%M:%S",time.localtime()) 32 33 if 0 == result: 34 35 fp.write("[master]" + logtime + ":" + ‘stop copy data, being master!\n‘) 36 37 else: 38 39 fp.write("[master]" + logtime + ":" + ‘being master falue!\n‘) 40 41 fp.close()从机redis_master.py内容与主机基本一致,修改备份数据对端地址为master ip即可。
1 SLAVEOF = ‘redis-cli slaveof 192.168.133.131 6379‘ #backup data form slave 2 3 SLAVEOF = ‘redis-cli slaveof 192.168.133.130 6379‘ #backup data form master执行这个脚本,redis状态将从主机变为从机,先从指定的ip对端进行数据备份,备份完成后切换自身状态为主机。
redis_backup.py主机配置
#!/usr/bin/python import os import time time.sleep(15) #set data backup time SLAVEOF = ‘redis-cli slaveof 192.168.133.131 6379‘ os.chdir("/etc/redis/") #set log file path fp = open("redis_dump.log",‘a‘) #open log file with append mode result = os.system(SLAVEOF) #exec command logtime = time.strftime("%Y-%m-%d %H:%M:%S",time.localtime()) if 0 == result: fp.write("[backup]" + logtime + ":" + ‘being slave!\n‘) else: fp.write("[backup]" + logtime + ":" + ‘being slave falue!\n‘) fp.close()从机redis_master.py内容与主机基本一致,修改备份数据对端地址为master ip即可。
1 SLAVEOF = ‘redis-cli slaveof 192.168.133.131 6379‘ #backup data form slave 2 3 SLAVEOF = ‘redis-cli slaveof 192.168.133.130 6379‘ #backup data form master执行这个脚本,redis将从主机状态变为从机,先从指定的对端ip进行数据备份,备份完成后切换状态为该对端从机。
上述用到的所有keepalived配置文件及脚本:
4. 热备测试
1. 主从启动所有服务
Service redis start
Service keepalived start
2. 在master执行ip a查看虚拟IP是否绑定成功
3. 查看日志,keepalived运行是否正常
4. 停止master的redis服务
Service redis stop,查看从机ip a,虚拟IP已经在1秒内切换到从机绑定了。
5. 查看从机信息
从机已经切换为主机
6. 重启主机redis服务
虚拟IP重新与主机绑定,主从恢复状态
7. 查看数据是否丢失