Redis-20190225-Ubuntu Redis 主从 HA with KeepAlived

Intro

继续上一篇文章的数据库 HA,这次做的是 Redis 主从模式。

Problem & Mark

Redis 有很多种 HA 的模式:

  • Redis Sentinel 集群 + 内网 DNS + 自定义脚本
  • Redis Sentinel 集群 + VIP + 自定义脚本
  • 封装客户端直连 Redis Sentinel 端口
    JedisSentinelPool,适合 Java
    PHP 基于 phpredis 自行封装
  • Redis Sentinel 集群 + Keepalived/Haproxy
  • Redis M/S + Keepalived
  • Redis Cluster
  • Twemproxy
  • Codis

以上参考:Redis 高可用性实践

选择最简单的主从两台加 KeepAlived 进行控制,只有两台机器可以玩,姑且先这么设计吧。

Solution

以下安装方式主要参考:Redis+Keepalived高可用环境部署记录

# 安装 redis
	apt-get -y install redis-server
# 更改 master 节点的配置文件 /etc/redis/redis.conf
	.......
	port 6379
	.......
	daemonize yes              #这个修改为yes
	.......
	bind 0.0.0.0               #绑定的主机地址。说明只能通过这个ip地址连接本机的redis。最好绑定0.0.0.0;注意这个不能配置成127.0.0.1,否则复制会失败!用0.0.0.0或者本机ip地址都可以
    ......
# 更改 slave 节点的配置文件 /etc/redis/redis.conf
	port 6379
	daemonize yes
	bind 0.0.0.0
	slaveof master_ip 6379
# 重启 redis 服务
	systemctl restart redis
# 查看 redis 的主从状态
	# master
		root@master:~# redis-cli info|grep ^role
		role:master
		root@master:~# redis-cli info replication
		# Replication
		role:master
		connected_slaves:1
		slave0:ip=slave_ip,port=6379,state=online,offset=1275,lag=1
		master_repl_offset:1275
		repl_backlog_active:1
		repl_backlog_size:1048576
		repl_backlog_first_byte_offset:2
		repl_backlog_histlen:1274
	# slave
		root@slave:/var/log/mysql# redis-cli info|grep ^role
		role:slave
		root@slave:/var/log/mysql# redis-cli info replication
		# Replication
		role:slave
		master_host:master_ip
		master_port:6379
		master_link_status:up
		master_last_io_seconds_ago:9
		master_sync_in_progress:0
		slave_repl_offset:1275
		slave_priority:100
		slave_read_only:1
		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

以下 KeepAlived 部分主要参考:Redis+Keepalived高可用方案详细分析

# master 节点上的 keepalived 配置
	global_defs {
	    router_id master
	} 
	vrrp_script check_redis_run {
	    script "/opt/redis_ha/redis_check.sh"
	    interval 30
	}
	
	vrrp_instance redis {
	    state BACKUP
	    interface eth0  
	    virtual_router_id 52
	    priority 100  
	    advert_int 1
	    nopreempt
	    authentication {
	        auth_type PASS
	        auth_pass 2222
	    }
	    track_script {
	        check_redis_run
	    }
	 
	    notify_master /opt/redis_ha/master.sh
	    notify_backup /opt/redis_ha/backup.sh
	    notify_stop /opt/redis_ha/stop.sh
	
	    virtual_ipaddress {
	        vip_x.x.x.x
	    }
	}
# slave 节点上的 keepalived 配置
	global_defs {
	    router_id slave
	}
	
	vrrp_script check_redis_run {
	    script "/opt/redis_ha/redis_check.sh"
	    interval 30
	}
	
	vrrp_instance redis {
	    state BACKUP
	    interface eth0  
	    virtual_router_id 52
	    priority 90
	    advert_int 1
	    nopreempt
	    authentication {
	        auth_type PASS
	        auth_pass 2222
	    }
	    track_script {
	        check_redis_run
	    }
	 
	    notify_master /opt/redis_ha/master.sh
	    notify_backup /opt/redis_ha/backup.sh
	    notify_stop /opt/redis_ha/stop.sh
	
	    virtual_ipaddress {
	        vip_x.x.x.x
	    }
	}
# redis_check.sh
	#!/bin/bash
	###/etc/keepalived/scripts/redis_check.sh
	
	. /root/.bash_profile
	
	HOST="local_ip"
	
	ALIVE=`/usr/bin/redis-cli -h $HOST -p 6379 ping`
	
	if [ "$ALIVE" == "PONG" ]; then
	  exit 0
	else
	  systemctl stop keepalived
	  exit 1
	fi
# master.sh
	#!/bin/bash
	REDISCLI="redis-cli"
	LOGFILE="/var/keepalived/log/redis-state.log"
	pid=$$
	master="another_ip"
	
	echo "`date +'%Y-%m-%d:%H:%M:%S'`|$pid|state:[slaver]" >> $LOGFILE
	echo "`date +'%Y-%m-%d:%H:%M:%S'`|$pid|state:[slaver] Run 'SLAVEOF $master 6379'" >> $LOGFILE
	$REDISCLI SLAVEOF $master 6379 >> $LOGFILE  2>&1
	echo "`date +'%Y-%m-%d:%H:%M:%S'`|$pid|state:[slaver] wait 10 sec for data sync from old master" >> $LOGFILE
	sleep 10 
	echo "`date +'%Y-%m-%d:%H:%M:%S'`|$pid|state:[slaver] data rsync from old mater ok..." >> $LOGFILE
	echo "`date +'%Y-%m-%d:%H:%M:%S'`|$pid|state:[master] Run slaveof no one,close master/slave" >> $LOGFILE
	$REDISCLI SLAVEOF NO ONE >> $LOGFILE 2>&1
	echo "`date +'%Y-%m-%d:%H:%M:%S'`|$pid|state:[master] wait other slave connect...." >> $LOGFILE
# backup.sh / fault.sh / stop.sh 全部一致
	#!/bin/bash
	REDISCLI="redis-cli"
	LOGFILE="/var/keepalived/log/redis-state.log"
	pid=$$
	master="another_ip"
	
	echo "`date +'%Y-%m-%d:%H:%M:%S'`|$pid|state:[master]" >> $LOGFILE
	echo "`date +'%Y-%m-%d:%H:%M:%S'`|$pid|state:[master] Being slave state..." >> $LOGFILE 2>&1
	echo "`date +'%Y-%m-%d:%H:%M:%S'`|$pid|state:[master] wait 10 sec for data sync from old master" >> $LOGFILE
	sleep 10
	echo "`date +'%Y-%m-%d:%H:%M:%S'`|$pid|state:[master] data rsync from old mater ok..." >> $LOGFILE
	echo "`date +'%Y-%m-%d:%H:%M:%S'`|$pid|state:[slaver] Run 'SLAVEOF $master 6379'" >> $LOGFILE
	$REDISCLI SLAVEOF $master 6379 >> $LOGFILE  2>&1
	echo "`date +'%Y-%m-%d:%H:%M:%S'`|$pid|state:[slaver] slave connect to $master ok..." >> $LOGFILE
# 重启 KeepAlived 即可,进一步查看日志,/var/log/messages 可看出绑定情况;或者 systemctl status keepalived -l
	systemctl restart keepalived
	
	2月 23 14:47:46 hostname Keepalived_vrrp[11203]: VRRP_Instance(mysql) Entering BACKUP STATE
	2月 23 14:47:46 hostname Keepalived_vrrp[11203]: Opening script file /opt/mysql_ha/backup.sh
	2月 23 14:47:46 hostname Keepalived_vrrp[11203]: VRRP_Instance(redis) Entering BACKUP STATE
	2月 23 14:47:46 hostname Keepalived_vrrp[11203]: Opening script file /opt/redis_ha/backup.sh
	2月 23 14:47:46 hostname Keepalived_healthcheckers[11202]: Registering Kernel netlink reflector
	2月 23 14:47:46 hostname Keepalived_healthcheckers[11202]: Registering Kernel netlink command channel
	2月 23 14:47:46 hostname Keepalived_healthcheckers[11202]: Opening file '/etc/keepalived/keepalived.conf'.
	2月 23 14:47:46 hostname Keepalived_healthcheckers[11202]: Using LinkWatch kernel netlink reflector...
	2月 23 14:47:46 hostname Keepalived_vrrp[11203]: VRRP_Script(check_redis_run) succeeded
	2月 23 14:47:46 hostname Keepalived_vrrp[11203]: VRRP_Script(check_mysql_run) succeeded	

你可能感兴趣的:(Linux,ubuntu,运维,bin,中间件,架构,基础知识)