简述Redis的主从复制及哨兵(sentinel)机制实例

应用场景说明:

  1. 基于Linux CentOS 7下搭建了一个“1主2从”的简易集群环境。
  2. master的ip地址为:192.168.206.100。
  3. slave1的ip地址为:192.168.206.101。
  4. slave2的ip地址为:192.168.206.102。
  5. 3台服务器的redis的监听端口都为:6379。
  6. 3台服务器的redis sentinel监听端口都为:26379。
  7. 这里我演示的redis版本是5.0.5

一、关于主从复制

redis的主从复制相对简单,只要简单的配置的即可实现。并且redis支持多级复制,即主服务器(写)的从属服务器也可以作为其他redis的服务器的主服务器,如:192.168.206.100是192.168.206.101的主服务器,但是192.168.206.101还可以作为192.168.206.102的主服务器。但这里只针对“1主2从”的配置模式说明,即:192.168.206.100作为主服务器(master),192.168.206.101、192.168.206.102都作为其的从属服务器(slave):
补充说明:自3.2版本之后,redis新增了保护模式(protected-mode),并且默认是开启的。在这种模式下要启用复制(replica)或者哨兵(sentinel)要么配置redis服务器密码:"requirepass pwd",要么绑定访问的ip:"bind ip1 ip2...",这里以配置密码的方式为例。

1.1 配置文件(redis.conf)配置

在101 / 102服务器的redis.conf文件中加上配置 "replicaof master_ip master_port"的配置项,如:
无论是主服务器还是从服务器,最好配置:“daemonize yes” ,即让redis服务以后台形式运行。

主服务器(master:192.168.206.100)的redis.conf

requirepass abc123  

具体配置如下:
从服务器(slave-101:192.168.206.101)的redis.conf

replicaof 192.168.206.100 6379 #格式:replicaof <masterip> <masterport>
masterauth abc123 # 告诉从服务器,主服务器的redis密码为:abc123
requirepass abc123 # 设置自己的密码为:abc123

从服务器(slave-102:192.1682061.102)的redis.conf
与以上相同即可

然后分别启动3台redis服务器,正常情况下不需要过多的配置,按照服务器默认路径即可正常启动,假设3台服务器安装路费都是 “/home/redis/”:

# 基本格式:/your_path/redis-server ./redis.conf --port port 
[root@r ~]# /home/redis/src/redis-server 
[root@r ~]# ps -ef | grep redis 

以102为例,以下说明redis服务已经正常启动了。
在这里插入图片描述
连接 master 客户端,设置一个key,再分别查看从服务器中是否有这个值:
在这里插入图片描述
以上说明主从配置成功!

1.2 命令行配置

这种方式就不需要重新启动redis服务了,比较灵活,在已经连接上redis客户端的情况下,如下:

# master
127.0.0.1:6379> config set requirepass abc123
OK
127.0.0.1:6379> config rewrite
OK
127.0.0.1:6379> info replication  // 查看主服务的复制详情
# Replication
role:master  // 角色:master
connected_slaves:2   // 有2个从服务连接
slave0:ip=192.168.206.101,port=6379,state=online,offset=377748,lag=0  // 从服务的详情
slave1:ip=192.168.206.102,port=6379,state=online,offset=377748,lag=0
master_replid:ec153d4e9a4dcebc9acad1c135864a608e7dbe2d
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:377748 
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:353552
repl_backlog_histlen:24197


# slave
127.0.0.1:6379> slaveof 192.168.206.100 6379
OK
127.0.0.1:6379> config set masterauth abc123
OK
127.0.0.1:6379> config rewrite
OK

在这里插入图片描述
至此,主从复制配置完成。

二、关于哨兵(sentinel)

在配置之前,先对哨兵的几个主要的概念做个简单的总结。

哨兵存在的意义: 由于redis主从复制如果出现问题,在没有使用哨兵机制的情况下,需要手动干预,在容灾处理方面不是很适合;哨兵的意义就是在主从复制出现问题的情况下,自动剔除问题服务器,并且进行投票选举出一个新的redis主服务器,保证线上的数据尽可能小的受到影响。

哨兵的任务: 哨兵(redis-sentinel)和redis的 redis-server、redis-cli都是单独并行存在的进程,哨兵主要用于管理多个Redis服务器,主要执行以下3个任务:
① 监控:哨兵会不断地监控每个redis服务器的运行情况,判断它们是否正常运行。
② 提醒:当被监控的某个Redis服务器出现问题时,哨兵可以通过api或者执行一个通知脚本给管理员或者其他应用发送通知。
③ 自动故障转移:当Master(主服务器)不能正常工作时,哨兵就会执行一次自动故障转移,它会将其中一个从服务器升级为新的主服务器,失效的主服务器改为新主服务器的从服务器。

主观下线: 即某个哨兵认为某台redis服务器失效,标记这台服务器的状态(subjective down,sdown)。

客观下线: 指多个哨兵对同一个服务器做出sdown的判断,并且通过命令 " sentinel is-master-down-by-addr" 交互交流之后得出的服务器下线判断,即流言协议(从其他哨兵那儿听说某个服务器下线了),即标记主服务器为客观下线(objecttive down,odown),只有主服务器存在“客观下线(odown)”的概念。

自动故障转移: 当某个哨兵发现了主服务器进入了客观下线的状态,那么这个哨兵就可能被选举出来,作为领头(leader)哨兵来执行服务器的自动故障转移,执行步骤如下:
◆ 选出一个从服务器,向被选中的从服务器发送 " slaveof no one "指令,将它升级为主服务器。
◆ 通过redis的发布与订阅功能,将更新后的配置广播给其他哨兵,其他哨兵收到配置则进行更新。
◆ 向已下线的旧主服务器(old master)发送 “slaveof <new_ip> <new_port>” 指令,让其复制新的主服务器。
◆ 当所有的从服务器开始复制新主服务器,领头(leader)哨兵终止本次自动故障转移。

必要的配置:
以 master:192.168.206.100 为例,/home/my_softs/redis/ 下新建一个sentinel-100.conf 的配置,并且加上如下的配置:

# 配置sentinel的监听端口
port 26379
# 后台进程模式开启
daemonize yes
# 配置日志文件位置
logfile "sentinel-log-100.log"
# 配置pig文件位置(shell脚本启动使用,看情况配置,也可以不配置)
pidfile "/var/run/redis-sentinel.pid"
# 配置监视的redis主服务器,格式: sentinel monitor <master-name> <master-ip> <master-port> <quonum>
# mymaster 是自定义的,给主服务器起个名字
# 2代表,当有2个sentinel认为一个master失效时,才会对这个master执行下线即故障转移操作
sentinel monitor mymaster 192.168.206.100 6379 2
# 配置master redis的服务器密码
sentinel auth-pass mymaster abc123

当配置完以上配置就可以了(其他配置就暂不介绍了,默认值就行了),然后启动 sentinel 之后,系统会主动更新你的配置文件,如下:
在这里插入图片描述
启动哨兵:/home/my_softs/redis/src/redis-sentinel ../sentinel-100.conf
剩下的2个从服务器,与之类似,只需要改下相应的配置文件名字或者路径就可以了,具体根据的安装路径而定。
当启动之后,可以发现,对应目录下的sentinel日志文件更新了,可查看配置的 sentinel 日志文件,以100为例:
在这里插入图片描述
然后把主服务器关掉:
在这里插入图片描述
当再次重启192.168.206.100之后发现,已经变成了101的从服务器了:
在这里插入图片描述

特别注意:
需要提醒的下的是,当你试图尝试在多个服务器之间配置哨兵、redis主从复制的话,需要保证一点:
(我之前因为疏忽,被坑了一上午o(╥﹏╥)o),就是各个每台服务器的 6379 、 26379(redis服务和哨兵服务的监听端口)都得从防火墙中开放出来:

[root@master run]# firewall-cmd --zone=public --list-port
20/tcp 21/tcp 22/tcp 80/tcp 8888/tcp 39000-40000/tcp 888/tcp 3306/tcp 9200/tcp 5601/tcp 9501/tcp 5200/tcp 6379/tcp 
[root@master run]# firewall-cmd --add-port=26379/tcp --permanent
success
[root@master run]# firewall-cmd --reload
success

最后,附上一个简单的启动与关闭 sentinel 服务shell 脚本。
如有错误,请不吝赐教,谢谢大家~:

#!/bin/bash
# sentinel 启动与关闭

REDIS_IP=localhost
REDIS_DIR=/home/my_softs/redis                      # redis-server启动脚本的所在目录,你如果忘了可以用find / -name xxx 或whereis xxx 找到
REDIS_SENTINEL_PATH=${REDIS_DIR}/src/redis-sentinel # 指定 sentinel 我执行文件位置
REDIS_SENTINEL_PORT=26379                           # redis的安装端口,6379是默认值,如果不是需要修改
REDIS_SENTINEL_CONF=${REDIS_DIR}/sentinel-100.conf  # 指定 sentinel 的配置文件地址
PID_FILE=/var/run/redis-sentinel.pid                # 指定pid的文件地址

# 启动方法  "/path-tp-sentinel/redis-sentinel /path-to/sentinel.conf/"
start(){
        if [ -f $PID_FILE ];then
                echo "$PID_FILE exists, redis-sentinel process is already running or crashed"
        else
                echo -n "Starting Redis_Sentinel_${REDIS_PORT}: "
                ${REDIS_SENTINEL_PATH} ${REDIS_SENTINEL_CONF}
        	if [ $? = 0 ];then
                	echo -e "[  \033[40;32mOK\033[0m  ]"
        	else
                	echo -e "[\033[40;31mFAILED\033[0m]"
        	fi
        fi
}

# 终止方法
stop(){
        if [ ! -f $PID_FILE ];then
                echo "$PID_FILE does not exist, process does not running"
        else
                PID=`ps -ef | grep "redis-sentinel" | grep -v grep | awk '{print $2}'` # 查找哨兵的pid
                echo "PID: ${PID}"
                echo -n "Stopping Redis_Sentinel_${REDIS_SENTINEL_PORT}: "

                kill -9 ${PID} &>/dev/null
                if [ -f $PID_FILE ];then
                    rm -rf ${PID_FILE}
                fi

		if [ $? = 0 ];then  # 判断上一条命令是否执行成功,成功则返回:0
                        echo -e "[  \033[40;32mOK\033[0m  ]"
                else
                        echo -e "[\033[40;31mFAILED\033[0m]"
                fi
        fi
}


case "$1" in
	start)
		start
		;;
	stop)
		stop
		;;
	restart)
		stop
		sleep 1
		start
		;;
	*)
        	echo "Usage $0 { start | stop | restart }"
		;;
esac



  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值