使用keepalived实现redis高可用

一. 简介

在项目验收阶段, 单点Redis的问题被提出来, 参照诸位大神的博客(本文最下方), 最后确定使用keepalived实现redis高可用, 现将其记录下来, 大致思路如下:

  • 本项目前端部分使用PHP包Predis, redis主要用于保存Cache和Session, Predis包操作redis集群不支持del操作(实操报错), 遂考虑搭建双机热备Redis环境, 使用keepalived实现主备故障转移, 以及vip漂移, 环境如下:

初始backup1 : 192.168.203.129
初始Backup2 : 192.168.203.130
vip: 192.168.203.240

  • 不了解keepalived vrrp的同学可以参照如下博客:
    http://outofmemory.cn/wiki/keepalived-configuration
    http://hugnew.com/?p=745

  • keepalived安装后两台机器初始配置状态都是 BACKUP , 优先级都设置为100 , 分别启动两台机器的redis和keepalived, 最初时, 两个机器都是BACKUP状态, 最先启动keepalived机器由于路由组中只有自己一台机器, 会被推举成为master节点(自己推举自己成为master), 随后启动keepalived的机器由于优先级和前一台机器一致, 所以会成为backup节点

  • keepalived优先级有效范围为0-255(博客上都这么说, 原因未知), 超过255会被转成100

  • 启动keepalived前, 需要先启动两台机器的redis, 并且配置主从, 搭建方法参考上一篇博客https://www.jianshu.com/p/acd3281d9074, 配置主从:

# 在backup2上配置redis成为backup1 redis 的slave
./bin/redis-cli SLAVEOF 192.168.203.129 6379
  • 其中backup1需要先启动keepalived成为主节点, 抢占vip, (通过ip a 查看网卡ip)

二. 安装keepalived

  • yum -y install keepalived
  • 配置keepalived, 主节点和从节点都是BACKUP
    vim /etc/keepalived/keepalived.conf
! Configuration File for keepalived
global_defs {
    router_id redis
}
# keepalived监控脚本
vrrp_script chk_redis {
    #keepalived 健康检测执行脚本
    script /usr/local/redis/keepalived/scripts/redis-check.sh    
    #每隔几秒发一次健康检测请求
    interval 2  
    #自我确定健康异常, 优先级加多少, priority += weight
    #当脚本返回非0, 则认为健康异常, 优先级 + -10 
    weight -10  
    #检测失败几次,认为是redis 服务器挂了
    fall 3      
}
# 实例
vrrp_instance redis {
    # 主和从都是BACKUP
    state BACKUP 
    #eth0 表示监听哪块儿网卡    
    interface eth0
    #主从一致   
    virtual_router_id 51
    #优先级, backup1和backup2都设为100, 重要, 关系到vip漂移问题 
    priority 100
    # 发送vrrp通告间隔, 对比优先级     
    advert_int 1
    virtual_ipaddress {
        #虚拟的ip 是多少
       192.168.203.240  
    }
    # 健康检查脚本
    track_script {
       chk_redis
    }
    #keepalived 内部通信,本机ip 地址
    unicast_src_ip  192.168.203.129 
    unicast_peer {
       #指定其它keepalived 地址,如果这个不指定,可能出现,主从都虚拟出了192.168.203.240 ip地址
       192.168.203.130  
    }
    #keepalived 被推选为主服务器器时执行的脚本
    notify_master /usr/local/redis/keepalived/scripts/redis-master.sh  
    #keepalived 被降级为从服务器时执行的脚本
    notify_backup /usr/local/redis/keepalived/scripts/redis-backup.sh  
    #keepalived 运行出现错误的时候执行的脚本
    notify_fault /usr/local/redis/keepalived/scripts/redis-fault.sh    
    #keepalived 服务停止时执行脚本
    notify_stop /usr/local/redis/keepalived/scripts/redis-stop.sh      
}
  • backup2 keepalived配置和backup1区别如下:
vrrp_instance redis {
    unicast_src_ip  192.168.203.130
    unicast_peer {
       192.168.203.129
    }
}

三. 创建监控脚本

除redis-backup.sh外, 其他脚本在backup1 和2 上都保持一致

  • 创建脚本保存目录, 以及日志保存目录
mkdir -p /usr/local/redis/keepalived/scripts
mkdir -p /usr/local/redis/keepalived/logs
  • redis-check.sh 脚本: 用于检测redis 服务健康状态
    vim /usr/local/redis/keepalived/scripts/redis-check.sh
#!/bin/bash   

#日志文件位置  
logFile=/usr/local/redis/keepalived/logs/check.log

#ping 本机redis服务  
pingRS=`/usr/local/redis/bin/redis-cli PING`

#如果ping 的结果为PONG,那么返回0 ,否则返回1  
if [ "$pingRS"x == "PONG"x ]  ; then  
   exit 0
else
   echo "[`date`] ping is error !"  >> $logFile
   exit 1
fi
  • redis-master.sh 脚本: keepalived 被推选为主服务器时执行
    vim /usr/local/redis/keepalived/scripts/redis-master.sh
#!/bin/bash  

# redis-cli 命令绝对路径  
cliCmd=/usr/local/redis/bin/redis-cli

# keepalived 日志文件位置  
logFile=/usr/local/redis/keepalived/logs/master.log

echo "`[date]` master " >> $logFile

# 成为主节点则redis需要取消复制, 也成为主节点  
$cliCmd  SLAVEOF NO ONE &>>$logFile
  • redis-backup.sh 脚本: keepalived 被降级为从服务器时执行
    backup1 和 backup2 中$cliCmd SLAVEOF 192.168.203.130 6379不一致, 需要修改
    vim /usr/local/redis/keepalived/scripts/redis-backup.sh
#!/bin/bash  

#日志文件  
logFile=/usr/local/redis/keepalived/logs/backup.log

# redis-cli 命令绝对路径  
cliCmd=/usr/local/redis/bin/redis-cli
  
echo "[`date`] begin to slave ..." >> $logFile


# 成为从节点, 需要检测redis是否启动, 没有启动, 则启动redis
service redis-server start
# 设置0,5s睡眠, 重要, 不要大 , 也不要小, 
# 太小, 下一步设置主从不成功(原因还未知)
# 太大, 如5s, 在5s期间, 节点会由backup转成master, 5s后才会执行slaveof, redis出现问题
sleep 0.5

# 设置主从关系
# keepalived成为从节点后, redis需要后成为兄弟节点的从节点
# backup2 此行为$cliCmd  SLAVEOF 192.168.203.129 6379
$cliCmd  SLAVEOF 192.168.203.130 6379

echo  "[`date`] slave done !" $ >> $logFile
  • redis-fault.sh 脚本: keepalived 执行出现错误时执行
    vim /usr/local/redis/keepalived/scripts/redis-fault.sh
#!/bin/bash  
#Desc keepalived 发生错误时执行脚本   

# keepalived 日志文件位置  
logFile=/usr/local/redis/keepalived/logs/fault.log

# 向日志输出错误信息  
echo "[$(date)] *****  redis falut  ***" >> $logFile
  • redis-stop.sh 脚本: keepavlied 服务停止时执行
    vim /usr/local/redis/keepalived/scripts/redis-stop.sh
#!/bin/bash  
#Desc keepalived 停止时执行脚本  

#日志文件  
logFile=/usr/local/redis/keepalived/logs/stop.log

#输出日志信息  
echo "[`date`] stop ..." >> $logFile
  • 重要: 给脚本添加可执行权限
cd /usr/local/redis/keepalived/scripts
chmod u+x *`
  • 在/etc/rc.local中添加启动
    vim /etc/rc.local
service redis-server start
service keepalived start
  • 启动backup1(主节点)和backup2(从节点)的redis, 并通过slave of设置redis主从
  • 启动主节点的keepalived, 抢占vip
  • 启动从节点的keepalived, 成为从节点
  • ip a查看各机器ip, 是否绑定了vip
    ip a
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000
    link/ether 00:0c:29:f5:b3:41 brd ff:ff:ff:ff:ff:ff
    inet 192.168.203.130/24 brd 192.168.203.255 scope global eth0
    # vip绑定成功
    inet 192.168.203.240/32 scope global eth0

  • 在其他机器通过虚拟ip连接到redis进行检查, info查看redis当前状态
./bin/redis-cli -h 192.168.203.240

192.168.203.240:6379> info
# Replication
role:master
connected_slaves:1
slave0:ip=192.168.203.130,port=6379,state=online,offset=12071,lag=1
master_repl_offset:12071
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:11904
repl_backlog_histlen:168

四. 高可用原理分析

1. 主节点redis挂掉

  • 主节点redis挂掉后, 健康检查脚本ping不通过, 会返回1, weight设置为-10, 所以优先级会降低, 发送自己的vrrp通告为100-10
  • 从节点keepalived对比自己优先级, 发出vrrp通告宣誓自己优先级为100, 捍卫主权(其实一直在发送), 从而被推选成为master, 触发从节点机器的redis_master.sh脚本并执行, redis停止复制, 成为主节点, 向局域网内其他机器发出arp包, 说明自己是10.101.67.240 ip对应的机器, 各机器将backup2的MAC地址和10.101.67.240映射关系缓存起来, 通过ip a 查看ip地址
  • 主节点被降级成为backup节点, 触发redis_backup.sh脚本并执行, 脚本再次尝试启动redis, 并开启复制 slave of backup2, redis成为slave, vip发生漂移
  • 经过以上几步, 主节点redis挂掉发生故障转移.
  • 可以通过查看日志来监控状态切换
tail -f /usr/local/redis/keepalived/logs/backup.log
tail -f /usr/local/redis/keepalived/logs/master.log
  • 整个过程不需要人为干预

2. 主节点keepalived挂掉

  • 主节点keepalived挂掉后, vip直接发生漂移至备份节点, 触发备份节点成为主节点, 执行redis_master.sh, redis成为master, 应用通过vip直接访问该redis, 实现故障转移,
  • 发生故障的机器手动启动挂掉的keepalived, 由于优先级相同, 则成为backup节点. 不会抢占vip, 触发backup脚本, redis开启复制

3. 主节点机器宕机

  • 同主节点keepalived挂掉情况一致

4. 从节点redis挂掉

  • 可以通过重启keepalived, 重新开启复制, 不会抢占master

5. 从节点keepalived挂掉和从节点宕机情况一致, 启动即可

五. 总结

经过以上几部, 可以实现redis高可用和故障转移, 已在真机上验证
参考博客:
Redis + Keepalived主从集群的搭建及故障转移: https://blog.csdn.net/ECHO_FOLLOW_HEART/article/details/51595228
redis中文网: http://www.redis.cn/documentation.html
https://blog.csdn.net/ws891033655/article/details/39834457
http://blog.51cto.com/hao360/1435297

keepalived:
Keepalived原理与实战精讲--VRRP协议: https://blog.csdn.net/wngua/article/details/54668794
http://outofmemory.cn/wiki/keepalived-configuration
http://hugnew.com/?p=745
http://fengchj.com/?p=2156#respond

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 205,033评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,725评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,473评论 0 338
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,846评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,848评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,691评论 1 282
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,053评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,700评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 42,856评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,676评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,787评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,430评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,034评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,990评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,218评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,174评论 2 352
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,526评论 2 343

推荐阅读更多精彩内容