为了解决单点问题,保证数据的安全性,Redis 提供了复制机制,用于知足故障恢复和负载均衡等需求。经过复制机制,Redis 能够经过多个副本保证数据的安全性,从而提供高可用的基础,Redis 的哨兵和集群模式都是在复制基础上实现高可用的。git
想要对两个 Redis 节点创建主从复制关系,能够经过如下三种方式来实现:github
slaveof {masterHost} {masterPort}
选项;--slaveof {masterHost} {masterPort}
参数;slaveof {masterHost} {masterPort}
命令。主从节点复制关系创建后,可使用 info replication
命令查看相关的复制状态。须要注意的是每一个从节点只能有一个主节点,但主节点能够同时拥有多个从节点,复制行为是单向的,只能由主节点复制到从节点,所以从节点默认都是只读模式,即 slave-read-only
的值默认为 yes
。redis
在启动后,若是想要断开复制关系,能够经过在从节点上执行 slaveof no one
命令,此时从节点会断开与主节点的复制关系,但并不会删除原有的复制成功的数据,只是没法再获取主节点上的数据。算法
经过 slaveof 命令还能够实现切换主节点的操做,命令以下:shell
slaveof {newMasterIp} {newMasterPort}
复制代码
须要注意的是,当你从一个主节点切换到另一个主节点时,该从节点上的原有的数据会被彻底清除,而后再执行复制操做,从而保证该从节点上的数据和新主节点上的数据相同。安全
复制机制最主要的缺陷在于,一旦主节点出现故障,从节点没法自动晋升为主节点,须要经过手动切换来实现,这样没法达到故障的快速转移,所以也不能实现高可用。基于这个缘由,就产生了哨兵模式。bash
哨兵模式的主要做用在于它可以自动完成故障发现和故障转移,并通知客户端,从而实现高可用。哨兵模式一般由一组 Sentinel 节点和一组(或多组)主从复制节点组成,架构以下:架构
Redis Sentinel 是一个特殊的 Redis 节点。在哨兵模式建立时,须要经过配置指定 Sentinel 与 Redis Master Node 之间的关系,而后 Sentinel 会从主节点上获取全部从节点的信息,以后 Sentinel 会定时向主节点和从节点发送 info
命令获取其拓扑结构和状态信息。负载均衡
基于 Redis 的发布订阅功能, 每一个 Sentinel 节点会向主节点的 __sentinel__:hello
频道上发送该 Sentinel 节点对于主节点的判断以及当前 Sentinel 节点的信息 ,同时每一个 Sentinel 节点也会订阅该频道, 来获取其余 Sentinel 节点的信息以及它们对主节点的判断。运维
经过以上两步全部的 Sentinel 节点以及它们与全部的 Redis 节点之间都已经彼此感知到,以后每一个 Sentinel 节点会向主节点、从节点、以及其他 Sentinel 节点定时发送 ping 命令做为心跳检测, 来确认这些节点是否可达。
每一个 Sentinel 都会定时进行心跳检查,当发现主节点出现心跳检测超时的状况时,此时认为该主节点已经不可用,这种断定称为主观下线。以后该 Sentinel 节点会经过 sentinel ismaster-down-by-addr
命令向其余 Sentinel 节点询问对主节点的判断, 当 quorum 个 Sentinel 节点都认为该节点故障时,则执行客观下线,即认为该节点已经不可用。这也同时解释了为何必须须要一组 Sentinel 节点,由于单个 Sentinel 节点很容易对故障状态作出误判。
这里 quorum 的值是咱们在哨兵模式搭建时指定的,后文会有说明,一般为
Sentinel节点总数/2+1
,即半数以上节点作出主观下线判断就能够执行客观下线。
由于故障转移的工做只须要一个 Sentinel 节点来完成,因此 Sentinel 节点之间会再作一次选举工做, 基于 Raft 算法选出一个 Sentinel 领导者来进行故障转移的工做。 被选举出的 Sentinel 领导者进行故障转移的具体步骤以下:
slaveof no one
命令让其成为主节点。下面演示在单机上搭建哨兵模式,多机搭建步骤亦同。须要注意的是在实际生产环境中,为了保证高可用,Sentinel 节点须要尽可能部署在不一样主机上,同时为了保证正常选举,至少须要 3个 Sentinel 节点。
拷贝三份 redis.conf
,分别命名为 redis-6379.conf ,redis-6380.conf ,redis-6381.conf ,须要修改的配置项以下:
# redis-6379.conf
port 6379
daemonize yes #以守护进程的方式启动
pidfile /var/run/redis_6379.pid #当Redis以守护进程方式运行时,Redis会把pid写入该文件
logfile 6379.log
dbfilename dump-6379.rdb
dir /home/redis/data/
# redis-6380.conf
port 6380
daemonize yes
pidfile /var/run/redis_6380.pid
logfile 6380.log
dbfilename dump-6380.rdb
dir /home/redis/data/
slaveof 127.0.0.1 6379
# redis-6381.conf
port 6381
daemonize yes
pidfile /var/run/redis_6381.pid
logfile 6381.log
dbfilename dump-6381.rdb
dir /home/redis/data/
slaveof 127.0.0.1 6379
复制代码
拷贝三份 sentinel.conf
,分别命名为 sentinel-26379.conf ,sentinel-26380.conf ,sentinel-26381.conf ,配置以下:
# sentinel-26379.conf
port 26379
daemonize yes
logfile 26379.log
dir /home/redis/data/
sentinel monitor mymaster 127.0.0.1 6379 2
sentinel down-after-milliseconds mymaster 30000
sentinel parallel-syncs mymaster 1
sentinel failover-timeout mymaster 180000
# sentinel-26380.conf
port 26380
daemonize yes
logfile 26380.log
dir /home/redis/data/
sentinel monitor mymaster 127.0.0.1 6379 2
sentinel down-after-milliseconds mymaster 30000
sentinel parallel-syncs mymaster 1
sentinel failover-timeout mymaster 180000
# sentinel-26381.conf
port 26381
daemonize yes
logfile 26381.log
dir /home/redis/data/
sentinel monitor mymaster 127.0.0.1 6379 2
sentinel down-after-milliseconds mymaster 30000
sentinel parallel-syncs mymaster 1
sentinel failover-timeout mymaster 180000
复制代码
分别启动三个 Redis 节点,命令以下:
redis-server redis-6379.conf
redis-server redis-6380.conf
redis-server redis-6381.conf
复制代码
分别启动三个Sentinel节点,命令以下:
redis-sentinel sentinel-26379.conf
redis-sentinel sentinel-26380.conf
redis-sentinel sentinel-26381.conf
复制代码
使用 ps -ef | grep redis
命令查看进程,此时输出应该以下:
可使用 info replication
命令查看 Redis 复制集的状态,此时输出以下。能够看到 6379 节点为 master 节点,而且有两个从节点,分别为 slave0 和 slave1,对应的端口为 6380 和 6381:
可使用 info Sentinel
命令查看任意 Sentinel 节点的状态,从最后一句输出能够看到 Sentinel 节点已经感知到 6379 的 master 节点,而且也知道它有两个 slaves 节点;同时 Sentinel 节点彼此之间也感知到,共有 3 个 Sentinel 节点:
更多文章,欢迎访问 [全栈工程师手册] ,GitHub 地址:github.com/heibaiying/…