# redis高可用 **Repository Path**: iq_java/redisHA ## Basic Information - **Project Name**: redis高可用 - **Description**: redis高可用 - **Primary Language**: Shell - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2019-08-14 - **Last Updated**: 2021-11-02 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README 本次Redis使用4.0.11版本来配置主从,并使用keepalived软件实现高可用部分。 使用两台服务器: hostname IP地址 redis01 192.0.2.81 redis02 192.0.2.82 安装文件是二进制的tar包:redis-4.0.11.tar.gz 请提前关闭 防火墙和selinux 一、数据库主从配置 1、主库redis01操作: 安装gcc [root@redis01 ~]# yum install gcc -y 创建redis安装目录 [root@redis01 ~]# mkdir /redis [root@redis01 ~]# cd /redis/ 解压redis安装文件 [root@redis01 redis]# tar -zxvf /root/redis-4.0.11.tar.gz 编译安装 [root@redis01 redis]# cd redis-4.0.11/ [root@redis01 redis]# make && make install 初始化服务 [root@redis01 redis-4.0.11]# cd utils/ [root@redis01 utils]# ./install_server.sh Welcome to the redis service installer This script will help you easily set up a running redis server Please select the redis port for this instance: [6379] Selecting default: 6379 Please select the redis config file name [/etc/redis/6379.conf] Selected default - /etc/redis/6379.conf Please select the redis log file name [/var/log/redis_6379.log] Selected default - /var/log/redis_6379.log Please select the data directory for this instance [/var/lib/redis/6379] Selected default - /var/lib/redis/6379 Please select the redis executable path [/usr/local/bin/redis-server] Selected config: Port : 6379 Config file : /etc/redis/6379.conf Log file : /var/log/redis_6379.log Data dir : /var/lib/redis/6379 Executable : /usr/local/bin/redis-server Cli Executable : /usr/local/bin/redis-cli Is this ok? Then press ENTER to go on or Ctrl-C to abort. Copied /tmp/6379.conf => /etc/init.d/redis_6379 Installing service... Successfully added to chkconfig! Successfully added to runlevels 345! Starting Redis server... Installation successful! 修改配置文件 [root@redis01 ~]# vi /etc/redis/6379.conf bind 0.0.0.0 重新关闭再启动redis [root@redis01 ~]# /etc/init.d/redis_6379 stop Stopping ... Redis stopped [root@redis01 ~]# /etc/init.d/redis_6379 start Starting Redis server… 2、从库redis02操作,跟主库基本一致: 安装gcc [root@redis02 ~]# yum install gcc -y 创建redis安装目录 [root@redis02 ~]# mkdir /redis [root@redis02 ~]# cd /redis/ 解压redis安装文件 [root@redis02 redis]# tar -zxvf /root/redis-4.0.11.tar.gz 编译安装 [root@redis02 redis]# cd redis-4.0.11/ [root@redis02 redis]# make && make install 初始化服务 [root@redis02 redis-4.0.11]# cd utils/ [root@redis02 utils]# ./install_server.sh Welcome to the redis service installer This script will help you easily set up a running redis server Please select the redis port for this instance: [6379] Selecting default: 6379 Please select the redis config file name [/etc/redis/6379.conf] Selected default - /etc/redis/6379.conf Please select the redis log file name [/var/log/redis_6379.log] Selected default - /var/log/redis_6379.log Please select the data directory for this instance [/var/lib/redis/6379] Selected default - /var/lib/redis/6379 Please select the redis executable path [/usr/local/bin/redis-server] Selected config: Port : 6379 Config file : /etc/redis/6379.conf Log file : /var/log/redis_6379.log Data dir : /var/lib/redis/6379 Executable : /usr/local/bin/redis-server Cli Executable : /usr/local/bin/redis-cli Is this ok? Then press ENTER to go on or Ctrl-C to abort. Copied /tmp/6379.conf => /etc/init.d/redis_6379 Installing service... Successfully added to chkconfig! Successfully added to runlevels 345! Starting Redis server... Installation successful! 配置主从参数配置 [root@redis02 ~]# vi /etc/redis/6379.conf slaveof 192.0.2.81 6379 重新启动redis [root@redis02 ~]# /etc/init.d/redis_6379 restart Stopping ... Redis stopped Starting Redis server... 3、测试验证主从正确性 在主库操作,插入测试数据: [root@redis01 ~]# redis-cli 127.0.0.1:6379> get name (nil) 127.0.0.1:6379> set user1 whc OK 127.0.0.1:6379> get name (nil) 127.0.0.1:6379> get user1 "whc" 在主库redis01查看主从状态 127.0.0.1:6379> info replication # Replication role:master connected_slaves:1 slave0:ip=192.0.2.82,port=6379,state=online,offset=616,lag=1 master_replid:3b52a9e13d1bbeac1be441665fa1ade7167064a9 master_replid2:0000000000000000000000000000000000000000 master_repl_offset:616 second_repl_offset:-1 repl_backlog_active:1 repl_backlog_size:1048576 repl_backlog_first_byte_offset:1 repl_backlog_histlen:616 在备库查看,测试数据都同步过来了: [root@redis02 ~]# redis-cli 127.0.0.1:6379> get name (nil) 127.0.0.1:6379> get user1 "whc" 在从库redis02查看主从状态 127.0.0.1:6379> info replication # Replication role:slave master_host:192.0.2.81 master_port:6379 master_link_status:up master_last_io_seconds_ago:4 master_sync_in_progress:0 slave_repl_offset:616 slave_priority:100 slave_read_only:1 connected_slaves:0 master_replid:3b52a9e13d1bbeac1be441665fa1ade7167064a9 master_replid2:0000000000000000000000000000000000000000 master_repl_offset:616 second_repl_offset:-1 repl_backlog_active:1 repl_backlog_size:1048576 repl_backlog_first_byte_offset:1 repl_backlog_histlen:616 至此,redis的主从就搭建完毕了 二、配置keepalived 1、keepalived配置文件 主库2.81配置: 安装keepalived [root@redis01 ~]# yum install -y keepalived.x86_64 修改主库keepalived配置文件: [root@redis01 ~]# vi /etc/keepalived/keepalived.conf ! Configuration File for keepalived global_defs { router_id redis01 } vrrp_script chk_redis { script "/etc/keepalived/script/redis_check.sh" interval 5 timeout 6 weight -20 } vrrp_instance VI_1 { state MASTER nopreempt interface ens33 virtual_router_id 56 priority 100 advert_int 1 authentication { auth_type PASS auth_pass 1111 } track_script { chk_redis } virtual_ipaddress { 192.0.2.99 } notify_master /etc/keepalived/script/redis_master.sh notify_backup /etc/keepalived/script/redis_backup.sh notify_fault /etc/keepalived/script/redis_fault.sh notify_stop /etc/keepalived/script/redis_stop.sh } 备库2.82配置: 安装keepalived [root@redis02 ~]# yum install -y keepalived.x86_64 修改备库keepalived配置文件: [root@redis02 ~]# vi /etc/keepalived/keepalived.conf ! Configuration File for keepalived global_defs { router_id redis02 } vrrp_script chk_redis { interval 5 timeout 6 weight -20 } vrrp_instance VI_1 { state BACKUP interface ens33 virtual_router_id 56 priority 99 advert_int 1 authentication { auth_type PASS auth_pass 1111 } virtual_ipaddress { 192.0.2.99 } notify_master /etc/keepalived/script/redis_master.sh notify_backup /etc/keepalived/script/redis_backup.sh notify_fault /etc/keepalived/script/redis_fault.sh notify_stop /etc/keepalived/script/redis_stop.sh } 2、配置脚本 主库2.81配置: [root@redis01 ~]# mkdir -p /etc/keepalived/script/ [root@redis01 ~]# cd /etc/keepalived/script/ keepalive触发条件 [root@redis01 script]# vi redis_check.sh #!/bin/bash CHECK=`/usr/local/bin/redis-cli PING` ping 192.0.2.66 -c5 if [ $? == 0 ]&&[ "$CHECK" == "PONG" ];then echo $CHECK exit 0 else echo $CHECK exit 1 fi VIP到本机的时候,执行的脚本 [root@redis01 script]# vi redis_master.sh #!/bin/bash REDISCLI="/usr/local/bin/redis-cli" LOGFILE="/var/log/keepalived-redis-state.log" sleep 5 echo "[master]" >> $LOGFILE date >> $LOGFILE echo "Being master...." >>$LOGFILE 2>&1 echo "Run SLAVEOF cmd ...">> $LOGFILE $REDISCLI SLAVEOF 192.0.2.82 6379 >>$LOGFILE 2>&1 if [ $? -ne 0 ];then echo "data rsync fail." >>$LOGFILE 2>&1 else echo "data rsync OK." >> $LOGFILE 2>&1 fi sleep 10 #延迟10秒以后待数据同步完成后再取消同步状态 echo "Run SLAVEOF NO ONE cmd ...">> $LOGFILE $REDISCLI SLAVEOF NO ONE >> $LOGFILE 2>&1 if [ $? -ne 0 ];then echo "Run SLAVEOF NO ONE cmd fail." >>$LOGFILE 2>&1 else echo "Run SLAVEOF NO ONE cmd OK." >> $LOGFILE 2>&1 fi VIP漂移走的时候,执行的脚本 [root@redis01 script]# vi redis_backup.sh #!/bin/bash REDISCLI="/usr/local/bin/redis-cli" LOGFILE="/var/log/keepalived-redis-state.log" echo "[backup]" >> $LOGFILE date >> $LOGFILE echo "Being slave...." >>$LOGFILE 2>&1 sleep 15 #延迟15秒待数据被对方同步完成之后再切换主从角色 echo "Run SLAVEOF cmd ...">> $LOGFILE $REDISCLI SLAVEOF 192.0.2.82 6379 >>$LOGFILE 2>&1 [root@redis01 script]# vi redis_fault.sh #!/bin/bash LOGFILE=/var/log/keepalived-redis-state.log echo "[fault]" >> $LOGFILE date >> $LOGFILE [root@redis01 script]# vi redis_stop.sh #!/bin/bash LOGFILE=/var/log/keepalived-redis-state.log echo "[stop]" >> $LOGFILE date >> $LOGFILE 增加执行权限: [root@redis01 script]# chmod +x * 备库2.82配置: [root@redis02 ~]# mkdir -p /etc/keepalived/script/ [root@redis02 ~]# cd /etc/keepalived/script/ VIP到本机的时候,执行的脚本 [root@redis02 script]# vi redis_master.sh #!/bin/bash REDISCLI="/usr/local/bin/redis-cli" LOGFILE="/var/log/keepalived-redis-state.log" echo "[master]" >> $LOGFILE date >> $LOGFILE echo "Being master...." >>$LOGFILE 2>&1 echo "Run SLAVEOF cmd ...">> $LOGFILE $REDISCLI SLAVEOF 192.0.2.81 6379 >>$LOGFILE 2>&1 sleep 10 #延迟10秒以后待数据同步完成后再取消同步状态 echo "Run SLAVEOF NO ONE cmd ...">> $LOGFILE $REDISCLI SLAVEOF NO ONE >> $LOGFILE 2>&1 VIP漂移走的时候,执行的脚本 [root@redis02 script]# vi redis_backup.sh #!/bin/bash REDISCLI="/usr/local/bin/redis-cli" LOGFILE="/var/log/keepalived-redis-state.log" echo "[backup]" >> $LOGFILE date >> $LOGFILE echo "Being slave...." >>$LOGFILE 2>&1 sleep 15 #延迟15秒待数据被对方同步完成之后再切换主从角色 echo "Run SLAVEOF cmd ...">> $LOGFILE $REDISCLI SLAVEOF 192.0.2.81 6379 >>$LOGFILE 2>&1 [root@redis02 script]# vi redis_fault.sh #!/bin/bash LOGFILE=/var/log/keepalived-redis-state.log echo "[fault]" >> $LOGFILE date >> $LOGFILE [root@redis02 script]# vi redis_stop.sh #!/bin/bash LOGFILE=/var/log/keepalived-redis-state.log echo "[stop]" >> $LOGFILE date >> $LOGFILE 增加执行权限: [root@redis02 script]# chmod +x * 3、主从都启动服务 [root@redis01 ~]# systemctl start keepalived [root@redis02 ~]# systemctl start keepalived [root@redis01 ~]# systemctl enable keepalived [root@redis02 ~]# systemctl enable keepalived 4、测试服务是否正常 查看VIP地址,此时VIP在主库redis01上 [root@redis01 ~]# ip addr | grep ens 2: ens33: mtu 1500 qdisc pfifo_fast state UP qlen 1000 inet 192.0.2.81/24 brd 192.0.2.255 scope global ens33 inet 192.0.2.99/32 scope global ens33 [root@redis02 script]# ip a | grep ens 2: ens33: mtu 1500 qdisc pfifo_fast state UP qlen 1000 inet 192.0.2.82/24 brd 192.0.2.255 scope global ens33 使用VIP,测试连接redis是否正常 [root@mongo ~]# redis-cli -h 192.0.2.99 192.0.2.99:6379> keys * 1) "1008" 2) "sex" 3) "test" 4) "name" 192.0.2.99:6379> info replication # Replication role:master connected_slaves:1 slave0:ip=192.0.2.82,port=6379,state=online,offset=2562,lag=0 至此,Keepalived搭建完成!! 5、测试故障转移情况(主库关闭,实例不存在) 关闭主redis服务,查看从redis是否会接管VIP变成主?然后在新的主库 82上插入测试数据 newdb 1、主 81 关闭redis [root@redis01 ~]# /etc/init.d/redis_6379 stop Stopping ... Redis stopped 2、查看备库 82的状态,此时82已变为主库 [root@redis02 ~]# redis-cli 127.0.0.1:6379> info replication # Replication role:master connected_slaves:0 master_replid:73c7e992880d32cd32636b79a901754986e430d9 master_replid2:af85572f49c6aab9ce5ce22f55c76f0e8a60a5ce master_repl_offset:3682 second_repl_offset:3683 repl_backlog_active:1 repl_backlog_size:1048576 repl_backlog_first_byte_offset:141 repl_backlog_histlen:3542 VIP已经飘到82上了 [root@redis02 script]# ip a | grep ens 2: ens33: mtu 1500 qdisc pfifo_fast state UP qlen 1000 inet 192.0.2.82/24 brd 192.0.2.255 scope global ens33 inet 192.0.2.99/32 scope global ens33 3、通过VIP访问查看数据库状态,和82的状态一致 [root@mongo ~]# redis-cli -h 192.0.2.99 192.0.2.99:6379> info replication # Replication role:master connected_slaves:0 master_replid:73c7e992880d32cd32636b79a901754986e430d9 master_replid2:af85572f49c6aab9ce5ce22f55c76f0e8a60a5ce master_repl_offset:3682 second_repl_offset:3683 repl_backlog_active:1 repl_backlog_size:1048576 repl_backlog_first_byte_offset:141 repl_backlog_histlen:3542 4、新主库82插入数据 newdb 127.0.0.1:6379> set newdb newdb OK 127.0.0.1:6379> keys * 1) "newdb" 2) "name" 3) "test" 4) "1008" 5) "sex" 6、恢复原状,最终结果是81为主库,82为备库 1、启动原来的主库81的redis [root@redis01 ~]# /etc/init.d/redis_6379 start Starting Redis server… 2、查看81数据库的状态信息 VIP没有飘回81 [root@redis01 ~]# ip addr | grep ens 2: ens33: mtu 1500 qdisc pfifo_fast state UP qlen 1000 inet 192.0.2.81/24 brd 192.0.2.255 scope global ens33 查看81数据库主从信息,当前81数据库是个独立的主库 [root@redis01 ~]# redis-cli 127.0.0.1:6379> info replication # Replication role:master connected_slaves:0 查看81数据库内容,数据还是关闭时的值 127.0.0.1:6379> keys * 1) "test" 2) "1008" 3) "sex" 4) "name" 3、查看82数据库的状态信息 VIP还在82上 [root@redis02 script]# ip a | grep ens 2: ens33: mtu 1500 qdisc pfifo_fast state UP qlen 1000 inet 192.0.2.82/24 brd 192.0.2.255 scope global ens33 inet 192.0.2.99/32 scope global ens33 查看82数据库主从信息,当前82数据库也是个独立的主库 [root@redis02 ~]# redis-cli 127.0.0.1:6379> info replication # Replication role:master connected_slaves:0 查看82数据库内容,newdb这条数据存在 127.0.0.1:6379> 127.0.0.1:6379> keys * 1) "newdb" 2) "name" 3) "test" 4) "1008" 5) "sex" 4、将 81 数据库 变为 82 数据库的从库,让其自动同步数据 [root@redis01 ~]# /usr/local/bin/redis-cli SLAVEOF 192.0.2.82 6379 OK 81数据库查看主从信息,已经是82的备库 [root@redis01 ~]# redis-cli 127.0.0.1:6379> info replication # Replication role:slave master_host:192.0.2.82 master_port:6379 master_link_status:up 查看81数据库内容,newdb这条数据同步过来了 127.0.0.1:6379> keys * 1) "1008" 2) "sex" 3) "name" 4) "test" 5) "newdb" 5、关闭备库 82 的keepalived,让VIP漂移到 81 ,然后再启动备库 82 的keepalived [root@redis02 ~]# systemctl stop keepalived [root@redis02 ~]# systemctl start keepalived 6、查看81数据库的状态信息 VIP此时在81上 [root@redis01 ~]# ip addr | grep ens 2: ens33: mtu 1500 qdisc pfifo_fast state UP qlen 1000 inet 192.0.2.81/24 brd 192.0.2.255 scope global ens33 inet 192.0.2.99/32 scope global ens33 查看81数据库主从信息,当前81数据库是主库,82是备库 [root@redis01 ~]# redis-cli 127.0.0.1:6379> info replication # Replication role:master connected_slaves:1 slave0:ip=192.0.2.82,port=6379,state=online,offset=4972,lag=1 插入一条测试数据 8181 127.0.0.1:6379> set 8181 8181 OK 127.0.0.1:6379> keys * 1) "1008" 2) "sex" 3) "name" 4) "test" 5) "newdb" 6) "8181" 7、查看82数据库的状态信息 VIP已经不在82上 [root@redis02 ~]# ip a | grep ens 2: ens33: mtu 1500 qdisc pfifo_fast state UP qlen 1000 inet 192.0.2.82/24 brd 192.0.2.255 scope global ens33 查看82数据库主从信息,82是备库,主库是81 [root@redis02 ~]# redis-cli 127.0.0.1:6379> info replication # Replication role:slave master_host:192.0.2.81 master_port:6379 master_link_status:up master_last_io_seconds_ago:1 master_sync_in_progress:0 查看测试数据 8181 ,已经同步到了备库82 127.0.0.1:6379> keys * 1) "newdb" 2) "name" 3) "test" 4) "8181" 5) "1008" 6) "sex" 至此,数据库环境恢复原状,主库81(VIP在这里),备库82