redis高可用:keepalived+redis主从部署

Dear 丶 2022-06-10 05:58 290阅读 0赞

1 Redis高可用的可选方案

Redis的高可用方案目前主要5种方式。
1) Redis Master-Slave + Keepalived + VIP。
这是很经典的db架构,也可以用与mysql的主从切换。基本原理是:Keepalive通过脚本检测master的存活,然后通过漂移VIP(Virtual IP)完成主从切换。
2) Redis Master-Slave + DNS Service + Sentinel。
基本原理是Sentinel集群进行Redis的存活检测和Redis M-S状态切换。完成切换之后,sentinel调用notification-script参数制定的配置文件,通知DNS Server更改DNS配置,master dns解析执行新的master。
3) Redis Master-Slave + Configure Center(Zookeeper) + Sentinel.
基本原理和第三种方案相似,只是notification-script通知的是配置中心完成redis连接配置的修改,比如Zookeeper实现的配置中心。
4) Redis Master-Slave + Sentinel + Twemproxy + Lvs.
这种方案层次比较多,sentinel通知twemproxy进行redis m-s的配置更改。
5)Redis Cluster,redis3.0发布了该功能,稳定性还待市场检验。

本文演示第一种方案:Redis Master-Slave + Keepalived + VIP.

  1. 基本构建与原理

1)Keepalived + VIP : 在redis master-slave上部署keepalived、redis instance存活检测脚本、以及告警通知脚本。

2)当redis master失效的时候,VIP从master上漂移到slave上,完成m-s角色和配置更改。3)客户端连接redis的参数中host设置的是VIP,整个切换过程对客户端透明。

  1. 优缺点与适用场景。

优点:实现简单,成本低,整个切换过程对客户端透明。

缺点:整个集群的最大吞吐量受限于redis单实例的处理能力,除非一个应用使用多套这种Keepalived+VIP方案。因而扩展能力较差,而且不适合目前单机部署多个redis实例的部署场景。

适合场景:并发请求不是很高的应用。

  1. 2 安装keepalived 1. tar zxf keepalived-1.3.5.tar.gz
  2. 2. cd keepalived-1.3.5 3. ./configure --prefix=/usr/local/keepalived/
  3. 4. make
  4. 5. make install
  5. 拷贝需要的文件:
  6. $ cp /usr/local/src/keepalived-1.3.5/keepalived/etc/init.d/keepalived /etc/init.d/keepalived
  7. $ cp /usr/local/keepalived/sbin/keepalived /usr/sbin/
  8. $ cp /usr/local/keepalived/etc/sysconfig/keepalived /etc/sysconfig/
  9. $ mkdir -p /etc/keepalived/
  10. $ cp /usr/local/keepalived/etc/keepalived/keepalived.conf /etc/keepalived/keepalived.conf
  11. /etc/keepalived/keepalived.conf是默认的配置文件 第一步,安装基础库 yum -y install openssl-devel libnl3-devel ipset-devel iptables-devel libnfnetlink-devel net-snmp-devel
  12. 第二步,源码安装keepalived 3 keepalived + Redis主从部署 3.1 部署拓补图 基于如下的拓扑图:
  13. 3.2 Redis主从配置 3.2.1 Redis安装 步骤1
  14. 首先从官网(http://download.redis.io/releases/)下载redis正式版的压缩包redis-2.8.19.tar.gz
  15. 步骤2:编译源码安装:
  16. cd /usr/local/src/
  17. tar zxvf redis-2.8.19.tar.gz
  18. cd redis-2.8.19
  19. make
  20. make install 3.2.2 修改redis配置文件 cd redis-2.8.19
  21. vim redis.conf 修改相关配置项,这里仅做DOME演示,其他配置项默认。
  22. 修改redis masterredis.conf
  23. daemonize yes
  24. logfile /var/log/redis.log
  25. 修改redis backupredis.conf
  26. daemonize yes
  27. logfile /var/log/redis.log
  28. slaveof 172.30.1.22 6379 3.2.3 启动Redis 分别启动主从redis-server:
  29. cd redis-2.8.19
  30. ./src/redis-server ./redis.conf
  31. 3.2.3 测试主从功能
  32. 在主机器上执行set key value [root@localhost redis-2.8.19]# ./src/redis-cli -p 6379
  33. 127.0.0.1:6379> set nosql redis
  34. OK
  35. 127.0.0.1:6379>
  36. 在从机器上执行get key [root@localhost redis-2.8.19]# ./src/redis-cli -p 6379
  37. 127.0.0.1:6379> get nosql
  38. "redis"
  39. 127.0.0.1:6379>
  40. OK,测试正常。 3.2 主从公共脚本 3.2.1 Redis监控脚本 该脚本检测redis的运行状态,并在nginx进程不存在时尝试重新启动ngnix,如果启动失败则停止keepalived,准备让其它机器接管。 /etc/keepalived/scripts/check_redis.sh #!/bin/bash
  41. CHECK=`/usr/local/bin/redis-cli PING`
  42. if [ "$CHECK" == "PONG" ] ;then
  43. echo $CHECK
  44. exit 0
  45. else
  46. echo $CHECK
  47. service keepalived stop #可确保让出MASTER
  48. exit 1
  49. fi
  50. keepalived根据监控脚本的返回码调整优先级: ☉如果脚本返回码为0,并且weight配置的值大于0,则优先级相应的增加; ☉如果脚本返回码为非0,并且weight配置的值小于0,则优先级相应的减少; ☉其他情况,原本配置的优先级不变,即配置文件中priority对应的值。 提示: 优先级不会不断的提高或者降低; 可以编写多个检测脚本并为每个检测脚本设置不同的weight(在配置中列出就行); 不管提高优先级还是降低优先级,最终优先级的范围是在[1,254],不会出现优先级小于等于0或者优先级大于等于255的情况; MASTER节点的 vrrp_instance 配置 nopreempt ,当它异常恢复后,即使它 prio 更高也不会抢占,这样可以避免正常情况下做无谓的切换。 以上可以做到利用脚本检测业务进程的状态,并动态调整优先级从而实现主备切换。 3.2.2 redis_fault.sh vim /etc/keepalived/scripts/redis_fault.sh # !/bin/bash
  51. LOGFILE=/usr/local/src/redis-2.8.19/keepalived-redis-state.log
  52. echo "[fault]" >> $LOGFILE
  53. date >> $LOGFILE
  54. 3.2.3 redis_stop.sh
  55. # !/bin/bash
  56. LOGFILE=/usr/local/src/redis-2.8.19/keepalived-redis-state.log
  57. echo "[stop]" >> $LOGFILE
  58. date >> $LOGFILE vim /etc/keepalived/scripts/redis_stop.sh # !/bin/bash
  59. LOGFILE=/usr/local/src/redis-2.8.19/keepalived-redis-state.log
  60. echo "[stop]" >> $LOGFILE
  61. date >> $LOGFILE
  62. 3.3 keepalived scripts for redis redis配置keepalived所需要的脚本。 3.3.1 Redis Master scripts redis master配置: vim/etc/keepalived/scripts/redis_master.sh #!/bin/bash
  63. REDISCLI="/usr/local/bin/redis-cli"
  64. LOGFILE="/usr/local/src/redis-2.8.19/keepalived-redis-state.log"
  65. echo "[master]" >> $LOGFILE
  66. date >> $LOGFILE
  67. echo "Being master...." >> $LOGFILE 2>&1
  68. echo "Run SLAVEOF cmd ..." >> $LOGFILE
  69. $REDISCLI SLAVEOF 172.30.1.23 6379 >> $LOGFILE 2>&1
  70. sleep 10 #延迟10秒以后待数据同步完成后再取消同步状态
  71. echo "Run SLAVEOF NO ONE cmd ..." >> $LOGFILE
  72. $REDISCLI SLAVEOF NO ONE >> $LOGFILE 2>&1 vim /etc/keepalived/scripts/redis_backup.sh #!/bin/bash
  73. REDISCLI="/usr/local/bin/redis-cli"
  74. LOGFILE="/usr/local/src/redis-2.8.19/keepalived-redis-state.log"
  75. echo "[backup]" >> $LOGFILE
  76. date >> $LOGFILE
  77. echo "Being slave...." >> $LOGFILE 2>&1
  78. sleep 15 #延迟15秒待数据被对方同步完成之后再切换主从角色
  79. echo "Run SLAVEOF cmd ..." >> $LOGFILE
  80. $REDISCLI SLAVEOF 172.30.1.23 6379 >> $LOGFILE 2>&1 3.3.2 Redis Backup scripts 3.3.1节的配置基本一样,只是脚本中redisIP为原master主机的IP redis backup配置: vim/etc/keepalived/scripts/redis_master.sh #!/bin/bash
  81. REDISCLI="/usr/local/bin/redis-cli"
  82. LOGFILE="/usr/local/src/redis-2.8.19/keepalived-redis-state.log"
  83. echo "[master]" >> $LOGFILE
  84. date >> $LOGFILE
  85. echo "Being master...." >> $LOGFILE 2>&1
  86. echo "Run SLAVEOF cmd ..." >> $LOGFILE
  87. $REDISCLI SLAVEOF 172.30.1.22 6379 >> $LOGFILE 2>&1
  88. sleep 10 #延迟10秒以后待数据同步完成后再取消同步状态
  89. echo "Run SLAVEOF NO ONE cmd ..." >> $LOGFILE
  90. $REDISCLI SLAVEOF NO ONE >> $LOGFILE 2>&1 vim /etc/keepalived/scripts/redis_backup.sh #!/bin/bash
  91. REDISCLI="/usr/local/bin/redis-cli"
  92. LOGFILE="/usr/local/src/redis-2.8.19/keepalived-redis-state.log"
  93. echo "[backup]" >> $LOGFILE
  94. date >> $LOGFILE
  95. echo "Being slave...." >> $LOGFILE 2>&1
  96. sleep 15 #延迟15秒待数据被对方同步完成之后再切换主从角色
  97. echo "Run SLAVEOF cmd ..." >> $LOGFILE
  98. $REDISCLI SLAVEOF 172.30.1.22 6379 >> $LOGFILE 2>&1 3.4 配置keepalived.conf keepalived.conf样例 global_defs {
  99. router_id redis
  100. }
  101. vrrp_script chk_redis {
  102. script "/etc/keepalived/scripts/check_redis.sh"
  103. interval 4
  104. weight -5
  105. fall 3
  106. rise 2
  107. }
  108. vrrp_instance VI_REDIS {
  109. state MASTER
  110. interface eth1
  111. virtual_router_id 51
  112. priority 100
  113. advert_int 1
  114. nopreempt
  115. authentication {
  116. auth_type PASS
  117. auth_pass 1111
  118. }
  119. virtual_ipaddress {
  120. 172.30.1.15
  121. }
  122. track_script {
  123. chk_redis
  124. }
  125. notify_master /etc/keepalived/scripts/redis_master.sh
  126. notify_backup /etc/keepalived/scripts/redis_backup.sh
  127. notify_fault /etc/keepalived/scripts/redis_fault.sh
  128. notify_stop /etc/keepalived/scripts/redsi_stop.sh
  129. }
  130. 注意,在同一个网段内的,若为不同的应用做高可用,不同应用使用不同的VIP,那么vrrp_instance的名字(这里是VI_REDIS)、virtual_router_id在不同的高可用实例必须设置不同的值区分开。否则keepalived会报如下错误: Aug 11 11:28:36 localhostKeepalived_vrrp[16958]: (VI_1): received an invalid ip number count 1, expected2! Aug 11 11:28:36 localhostKeepalived_vrrp[16958]: bogus VRRP packet received on eth1 !!! Aug 11 11:28:36 localhostKeepalived_vrrp[16958]: VRRP_Instance(VI_1) Dropping received VRRP packet... 以上是keepalived MASTER节点配置文件/etc/keepalived/keepalived.conf的配置信息。在BACKUP节点,只需把vrrp_instance->state改为BACKUPvrrp_instance->priority改为99即可。 在默认的keepalive.conf里面还有 virtual_server,real_server 这样的配置,我们这用不到,它是为lvs准备的。 notify 可以定义在切换成MASTERBACKUP时执行的脚本,如有需求请自行google 配置选项说明 global_defs notification_email keepalived在发生诸如切换操作时需要发送email通知地址,后面的 smtp_server 相比也都知道是邮件服务器地址。也可以通过其它方式报警,毕竟邮件不是实时通知的。 router_id 机器标识,通常可设为hostname。故障发生时,邮件通知会用到 vrrp_instance state 指定instance(Initial)的初始状态,就是说在配置好后,这台服务器的初始状态就是这里指定的,但这里指定的不算,还是得要通过竞选通过优先级来确定。如果这里设置为MASTER,但如若他的优先级不及另外一台,那么这台在发送通告时,会发送自己的优先级,另外一台发现优先级不如自己的高,那么他会就回抢占为MASTER interface 实例绑定的网卡,因为在配置虚拟IP的时候必须是在已有的网卡上添加的,可以用ifconfig命令查看网卡。 mcast_src_ip 发送多播数据包时的源IP地址,这里注意了,这里实际上就是在那个地址上发送VRRP通告,这个非常重要,一定要选择稳定的网卡端口来发送,这里相当于heartbeat的心跳端口,如果没有设置那么就用默认的绑定的网卡的IP,也就是interface指定的IP地址 virtual_router_id 这里设置VRID,这里非常重要,相同的VRID为一个组,他将决定多播的MAC地址 priority 设置本节点的优先级,优先级高的为master advert_int 检查间隔,默认为1秒。这就是VRRP的定时器,MASTER每隔这样一个时间间隔,就会发送一个advertisement报文以通知组内其他路由器自己工作正常 authentication 定义认证方式和密码,主从必须一样,样例用的是密码方式。 virtual_ipaddress 这里设置的就是VIP,也就是虚拟IP地址,他随着state的变化而增加删除,当statemaster的时候就添加,当statebackup的时候删除,这里主要是有优先级来决定的,和state设置的值没有多大关系。这里可以设置多个虚拟IP地址,类似于一个域名可以解析对应多个IP地址。 track_script 引用VRRP脚本,即在 vrrp_script 部分指定的名字。每隔vrrp_script->interval时间运行脚本,如果监控服务有异常则改变优先级,并最终引发主备切换。 vrrp_script 告诉 keepalived 在什么情况下切换,所以尤为重要。可以有多个 vrrp_script script 自己写的检测脚本。也可以是一行命令如killall-0 nginx interval4 4s检测一次,这里要大于监控脚本执行的时间,监控脚本会执行超时,☉keepalived会发送SIGTERM信号结束监控脚本的执行。 weight-5 检测失败(脚本返回非0)则优先级 -5 fall 2 检测连续 2 次失败才算确定是真失败。会用weight减少优先级(1-255之间) rise 1 检测 1 次成功就算成功。但不修改优先级 4.1启动keepalived Redis MasterRedis Backup上将keepalived启动 启动keepalived service keepalived start 或者 /etc/init.d/keepalived start 或者 /usr/local/keepalived/sbin/keepalived -f/etc/keepalived/keepalived.conf -D 查看进程,正常会有三个进程 [root@localhost ~]# ps -ef | grepkeepalived root 3870 1 0 14:46 ? 00:00:00 keepalived -D root 3872 3870 0 14:46 ? 00:00:00 keepalived -D root 3873 3870 0 14:46 ? 00:00:00 keepalived -D root 3887 18774 0 14:46 pts/1 00:00:00 grep keepalived [root@localhost ~]# ip命令查看VIPifconfig命令不能查看虚拟IP [root@localhost ~]# ip a | grep eth1 2: eth1:<BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen1000 inet 172.30.1.22/24 brd 172.30.1.255scope global eth1 inet 172.30.1.15/32 scope global eth1 [root@localhost ~]# 可以看到现在是172.30.1.22接管着VIP 至此,Keppalived+Redis主从高可用环境已经搭建完成。客户端访问Redis使用VIP,或者将redis的域名解析指向VIP 4 测试 测试时可以用命令tail -f /var/log/messages查看keepalived的日志,查看主从机器状态的变化,VIP的漂移等。 4.1 客户端用VIP访问Redis 在另一台客户端机器,比如172.30.1.20,用VIP登录redis,并使用get命令获取之前设置的[key,value].
  131. [root@localhost redis-2.8.19]# redis-cli -h 172.30.1.15 -p 6379
  132. 172.30.1.15:6379> get nosql
  133. "redis"
  134. 172.30.1.15:6379>
  135. 再设置一个新的[key,value].
  136. 172.30.1.15:6379> set movie ZhanLang2
  137. OK
  138. 172.30.1.15:6379> get movie
  139. "ZhanLang2"
  140. 172.30.1.15:6379>
  141. 测试结果正常。 4.2 测试VIP漂移 测试之前,先看下那台机器接管这VIP
  142. 172.30.1.22机器查看
  143. [root@localhost ~]# ip a | grep eth1
  144. 2: eth1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000
  145. inet 172.30.1.22/24 brd 172.30.1.255 scope global eth1
  146. inet 172.30.1.15/32 scope global eth1
  147. [root@localhost ~]#
  148. 172.30.1.23查看
  149. [root@localhost ~]# ip a | grep eth1
  150. 2: eth1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000
  151. inet 172.30.1.23/24 brd 172.30.1.255 scope global eth1
  152. [root@localhost ~]#
  153. 可见,VIP172.30.1.22机器接管着。
  154. 现在,把172.30.1.22机器上的redis-server干掉,再查看VIP是否还接管着:
  155. [root@localhost ~]# pkill redis-server
  156. [root@localhost ~]# ps -ef | grep redis-server | grep -v grep
  157. root 7372 30964 0 13:57 pts/0 00:00:00 grep redis-server
  158. [root@localhost ~]# ip a | grep eth1
  159. 2: eth1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000
  160. inet 172.30.1.22/24 brd 172.30.1.255 scope global eth1
  161. [root@localhost ~]#
  162. 可见,172.30.1.22已经没有接管VIP了。
  163. 172.30.1.23查看下是否接管了VIP
  164. [root@localhost ~]# ip a | grep eth1
  165. 2: eth1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000
  166. inet 172.30.1.23/24 brd 172.30.1.255 scope global eth1
  167. inet 172.30.1.15/32 scope global eth1
  168. [root@localhost ~]#
  169. 可见172.30.1.23已经接管了VIP,进入MASTER状态了。
  170. 继续测试在VIP下的redis读写:
  171. 还是在客户端172.30.1.20下执行
  172. 172.30.1.15:6379> get movie
  173. "ZhanLang2"
  174. 172.30.1.15:6379> set director WuJing
  175. OK
  176. 172.30.1.15:6379>
  177. 测试正常,注意,刚刚设置了一个新的[key,value],待会把172.30.1.22上的redis-server起来后,再查询这个新的[key,value]——[director,WuJing].
  178. 现在把172.30.1.22上的redis-server启动,keepalived也需要启动,以为检测脚本check_redis.sh检测到redis-server不在时,把keepalived也退出了,确保MASTER角色的让出。
  179. [root@localhost redis-2.8.19]# cd /usr/local/src/redis-2.8.19
  180. [root@localhost redis-2.8.19]# ./src/redis-server redis.conf
  181. [root@localhost redis-2.8.19]# ps -ef | grep redis-server | grep -v grep
  182. root 7841 1 0 14:25 ? 00:00:00 ./src/redis-server *:6379
  183. [root@localhost redis-2.8.19]# service keepalived start
  184. Starting keepalived: [ OK ]
  185. [root@localhost redis-2.8.19]# ip a | grep eth1
  186. 2: eth1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000
  187. inet 172.30.1.22/24 brd 172.30.1.255 scope global eth1
  188. inet 172.30.1.15/32 scope global eth1
  189. [root@localhost redis-2.8.19]#
  190. 可见,启动redis-serverkeepalived后,172.30.1.22又重新接管了VIP,因为172.30.1.22设置的优先级是100172.30.1.23的优先级99要高。
  191. 在客户端172.30.1.20下继续测试redis的读写
  192. 先查询刚刚设置的[director,WuJing]
  193. 172.30.1.15:6379> get director
  194. "WuJing"
  195. 172.30.1.15:6379>
  196. 可以查询到,说明数据已经同步过来了
  197. 再测试下写数据
  198. 172.30.1.15:6379> set piaofang 4billion
  199. OK
  200. 172.30.1.15:6379>
  201. 可见,写redis也是正常的。
  202. OK,现在高可用的基本功能测试已经完成。
  203. 参考 官网 http://www.keepalived.org/ https://github.com/acassen/keepalived 博客 http://redisdoc.com/topic/sentinel.html http://blog.csdn.net/l1028386804/article/details/52578080 http://mdba.cn/2015/03/06/redis%E9%AB%98%E5%8F%AF%E7%94%A8%E6%9E%B6%E6%9E%84-keepalivevip/

发表评论

表情:
评论列表 (有 0 条评论,290人围观)

还没有评论,来说两句吧...

相关阅读

    相关 Redis

    高可用 高可用(High Availability),是当一台服务器停止服务后,对于业务及用户毫无影响。 停止服务的原因可能由于网卡、路由器、机房、CPU负载过高、内存溢