1、准备好三台机器,使用diap用户完成搭建
2、安装Redis
-在资源库中下载redis-7.0.8.tar.gz,分别上传到三台服务器中软件安装的目录,我这里安装到/u01下
-安装依赖。yum -y install gcc-c++(root用户执行),三台服务器都要执行
3、修改Redis配置文件
mkdir /usr/local/redis
Mkdir /usr/local/redis/etc
cp /u01/redis-7.0.8/redis.conf /usr/local/redis/etc
vi /usr/local/redis/etc/redis.conf
daemonize yes #redis后台启动
requirepass !QAZ3edc #设置redis密码
bind 127.0.0.1 注释掉这行
pidfile /usr/local/redis/run/redis_6379.pid
logfile “/usr/local/redis/logs/redis.log”
dir /usr/local/redis/dbcache
masterauth !QAZ3edc #连接主机的密码
#以上内容三台机器都是一样配置,下面的内容在两台从节点上配置
slaveof 10.38.17.82 6379 #是10.38.17.82的从节点
mkdir /usr/local/redis/run
touch /usr/local/redis/run/redis_6379.pid
mkdir /usr/local/redis/logs
touch /usr/local/redis/logs/redis.log
mkdir /usr/local/redis/dbcache
4、启动Redis,看一主二从是否生效
进入/u01/redis-7.0.8/src,输入以下命令
./redis-server /usr/local/redis/etc/redis.conf #三台机器同时启动redis-server
./redis-cli -p 6379 #启动主节点的客户端redis-cli
127.0.0.1:6379>auth !QAZ3edc # 验证密码
OK
127.0.0.1:6379>info replication
role:master
connected_slaves:2
...
#说明一主二从模式搭建完毕
5、部署哨兵模式
将配置文件sentinel.conf复制到指定目录
cp sentinel.conf /usr/local/redis/etc
vi /usr/local/redis/etc/sentinel.conf
修改以下内容,三台机器都要
Daemonize yes
pidfile /usr/local/redis/run/redis-sentinel.pid
logfile "/usr/local/redis/logs/redis-sentinel.log"
dir /usr/local/redis/tmp
sentinel monitor mymaster 10.38.17.82 6379 2 #设置redis主机IP地址,端口,选举次数
sentinel auth-pass mymaster !QAZ3edc #设置redis主机访问密码
sentinel down-after-milliseconds mymaster 8000 #心跳检测8000毫秒,如果主机8秒内没有
创建配置中修改的pid、log、tmp文件(三台机器都要)
touch /usr/local/redis/run/redis-sentinel.pid
touch /usr/local/redis/logs/redis-sentinel.log
mkdir /usr/local/redis/tmp
6、启动哨兵模式
#进入/redis-7.0.8/src目录
./redis-sentinel /usr/local/redis/etc/sentinel.conf #三台机器都一样
#连接主节点的哨兵客户端
./redis-cli -p 26379
127.0.0.1:26379>ping
PONG
127.0.0.1:26379>info sentinel
#Sentinel
Sentinel_masters:1
...
master0:name=mymaster,status=ok,address=127.0.0.1:6379,slaves:2,sentinels=3
这样哨兵模式就搭建完毕。查询当前的主节点,在哨兵模式客户端输入命令SENTINEL get-master-addr-by-name mymaster mymaster
模拟主节点宕机:用kill命令将主节点的redis-server关闭,连接从节点redis-cli客户端,观察是否从slave变为master(总有一台从节点会自动变为主节点
哨兵是Redis的一种工作模式,以监控节点状态及执行故障转移 为主要工作,哨兵总是以固定的频率去发现节点、故障检测 ,然后在检测到主节点故障时以安全的方式执行故障转移,确保集群的高可用性。
这里的节点指的是其他哨兵节点和主从节点 。
1、自动发现数据节点(主从节点):
一般情况下,哨兵节点每隔10秒(故障转移时每隔1秒)向主从节点发送INFO命令,以此获取主从节点的信息。第一次执行时,哨兵仅知道我们给出的主节点信息,通过对主节点执行INFO命令,就可以获取其从节点列表,如此周期性执行,就可以不断发现新加入的节点
2、自动发现其他哨兵节点:
Redis提供了一种发布订阅的消息通信模式,即Pub/Sub,哨兵们就是通过一个约定好的通道(channel)发布/订阅hello信息进行通信。
每隔2秒,每个哨兵会通过它监控的主节点、从节点向通道发布一条hello信息
每个哨兵会通过它所监控的主节点、从节点订阅通道的信息,以此接收其他哨兵发布的信息
每个哨兵都会维护其监控的主节点信息,如果它接收到其他哨兵消息后,发现自己维护的信息已经过时,则立即执行更行过程。
如果哨兵接受到的信息没有在已有的监控列表中,就意味着发现了一个新的哨兵实例,此时会创建一个新的哨兵实例加入监控列表。在处理新增哨兵实例时,如果它与已存在的哨兵实例runId或者ip、port一致,将只保存最新的实例信息。
3、总结
节点发现的过程就是这样:对于数据节点采用INFO命令询问,从一个主节点得到从节点,再通过从节点检验主节点,实现数据节点发现;对于其他哨兵节点,借助正在被监控的数据节点以类似广播的方式,实现节点的发现。
1、故障检测
故障检测是哨兵执行故障转移的前提,在知晓需要监控的目标(主从节点)后,哨兵通过PING命令实现对主从节点的故障检测。
哨兵以集群方式工作,官方建议至少要有三个节点 (一主二从节点部署哨兵模式),每个节点都以相同的方式对主从节点进行监控与故障检测。由于网络抖动或者网络分区,单个哨兵对节点的故障检测可能无法代表其真实的状态,为了降低误判,哨兵之间还需要对节点的故障状态进行协商 。所以这里需要引入两个概念:
简单来说,SDOWN是哨兵自己认为节点宕机,而ODOWN是不但哨兵自己认为节点宕机,而且该哨兵与其他节点沟通后,达到一定数量的哨兵都认为节点宕机
这个一定数量可以配置:
sentinel monitor mymaster xx.xx.xx.xx 6379 2
这里的 2:代表只有两个或两个以上的哨兵认为主节点不可用的时候,才会把主节点设置为ODOWN状态,然后进行failovor操作
2、Redis如何实现SDOWN和ODOWN
Redis以类似心跳检测的PING命令对节点进行健康检查,然后根据节点的回复情况进行状态管理。
SDOWN状态是指在sentinel down-after-milliseconds 时间内未收到节点的PING命令回复,这个是在sentinel.conf中的sentinel down-after-milliseconds mymaster配置,如
sentinel down-after-milliseconds mymaster 8000 ##心跳检测8000毫秒,如果主机8秒内没有相应,就会将主节点设置为SDOWN
SDOWN无法触发故障转移 ,仅仅说明是一个哨兵认为节点发送故障(不可用)了,若要触发故障转移,必须达到ODOWN状态
当Sentinel将一个主节点判断为主观下线之后,为了确认这个主服务器是否真的下线 了,它会向同样监视这一主服务器的其他Sentinel进行询问,看它们是否也认为主服务器已经进入了下线状态。当Sentinel从其他Sentinel那里接收到足够数量的已下线判断之后,Sentinel就会将从服务器判定为客观下线,并对主服务器执行故障转移操作 。
ODOWN状态仅应用在主节点上 ,不对从节点及其他哨兵节点应用,但是SDOWN状态对他们都是有效的
1、进入故障转移过程有几个前提:
故障转移执行过程中的核心过程主要为Sentinel Leader选举,新主节点选举,配置其他从节点
2、Sentinel Leader选举
当一个主节点被判断为客观下线时,监控这个主节点的所有Sentinel会进行协商,选举一个Leader对下线的主节点执行故障转移操作 。故障检测是多个Sentinel同时执行 的,也就是说可能多个Sentinel在相近的时间内都判定主节点客观宕机了,因此Leader的选举过程在Sentinel集群内可能是同步进行的。所以,Sentinel需要在集群内进行“拉票”,“拉票”的依据就是配置纪元及“拉票”的时间。配置纪元越大,优先级越高;“拉票”请求越早,优先级越高 :
当Sentinel判断主节点客观下线后,会把自己的配置纪元加1,未检测到主节点ODOWN或检测慢的,自然落后于当前纪元
Sentinel会使用Sentinel is-master-down-by-addr命令向其他所有Sentinel发起投票请求,与故障检测过程中的“询问“不同,这里的runId将被设置为当前Sentinel的runId,epoch为最新的纪元。
其他Sentinel接收到“投票”请求后,执行以下过程:
Sentinel接收并处理Sentinel is-master-down-by-addr回复:把投票结果(runId)更新到该Sentinel的节点信息中。
投票结束,进行统计结果。该过程是在SENTINEL_FAILOVER_STATE_WAIT_START状态下执行的。Sentinel会遍历当前主节点下所有的Sentinel节点,把它们的投票信息进行统计;然后判断是否有Sentinel胜出。这里胜出的条件是:
3、新主节点选举
选举出Sentinel Leader后,Sentinel Leader会从该宕机的主节点的存活的从节点中选出一个新的主节点。首先,按照一下条件剔除从节点:
然后按照以下规则选择新的节点:
选出新的主节点之后,Sentinel Leader会向它发送slaveof NO ONE ,把这个从节点转为主节点(这是在从节点自身来看的角色转换)。
从节点接收slaveof NO ONE命令后,会重置其主节点信息,断开与其主节点、从节点的网络连接,重置其复制ID,并执行持久化重写操作。
4、配置其他从节点
新的主节点已经配置完成,接下来就是要让其他存活的从节点以该节点为主节点,然后向该节点发起主从复制,该过程原理比较简单:遍历原主节点的从节点,向这些从节点发送slaveof 命令
这样故障转移过程就完成。新的主节点也诞生。
5、注意:
Sentinel从不移除从节点,即使很长时间都不可用。这一点是非常有用的,因为当发生网络分区或者故障后,Sentinel需要正确的对恢复节点进行重新配置。经过故障转移,旧主节点将以从节点的角色加入集群 ,Sentinel会对他进行重新配置,让它从新的主节点执行主从复制。即使旧的主节点恢复,仍然是以从节点的身份加入集群,不再是主节点。
脑裂问题:redis的主从模式下脑裂是指因为网络问题,导致redis 主节点跟从节点和Sentinel集群处于不同的网络分区 ,此时因为Sentinel集群无法感知到 主节点的存在,就会将某一个从节点提升为主节点。此时就存在两个不同的主节点 ,就像一个大脑分裂成了两个。