本文参考 嗨客网 Redis面试题
Redis Sentinel 是一个分布式系统, 你可以在一个架构中运行多个 Sentinel 进程(progress), 这些进程使用流言协议(gossip protocols)来接收关于主服务器是否下线的信息,并使用投票协议(agreement protocols)来决定是否执行自动故障迁移,以及选择哪个从服务器作为新的主服务器。
虽然 Redis Sentinel 释出为一个单独的可执行文件 redis-sentinel , 但实际上它只是一个运行在特殊模式下的 Redis 服务器,你可以在启动一个普通 Redis 服务器时通过给定 --sentinel
选项来启动 Redis Sentinel 。
Sentinel(哨兵)是用于监控 redis 集群中 Master 状态的工具,是 Redis 的高可用性解决方案,sentinel 哨兵模式已经被集成在 redis2.4 之后的版本中。sentinel 是 redis 高可用的解决方案,sentinel 系统可以监视一个或者多个 redis master 服务,以及这些 master 服务的所有从服务;当某个 master 服务下线时,自动将该 master 下的某个从服务升级为 master 服务替代已下线的 master 服务继续处理请求。
sentinel 可以让 redis 实现主从复制,当一个集群中的 master 失效之后,sentinel 可以选举出一个新的 master 用于自动接替 master 的工作,集群中的其他 redis 服务器自动指向新的 master 同步数据。一般建议 sentinel 采取奇数台,防止某一台 sentinel 无法连接到 master 导致误切换。
Sentinel 系统用于管理多个 Redis 服务器(instance), 该系统执行以下三个任务:
首先, 哨兵模式是一种特殊的模式,它是 Redis 高可用的一种实现方案。首先哨兵是一个独立的进程, 可以实现对 Redis 实例的监控、通知、自动故障转移。
实际上,每个哨兵节点每秒通过 ping 去进行心跳监测(包括所有 redis 实例和 sentinel 同伴),并根据回复判断节点是否在线。
如果某个 sentinel 线程发现主库没有在给定时间( down-after-milliseconds)内响应这个 PING,则这个 sentinel 线程认为主库是不可用的,这种情况叫 “主观失效”(即SDOWN);这种情况一般不会引起马上的故障自动转移,但是当多个 sentinel 线程确实发现主库是不可用并超过 sentinel.conf 里面的配置项 sentinel monitor mymaster {#ip} {#port} {#number} 中的 #number 时候(这里实际上采用了流言协议),一般其余 sentinel 线程会通过 RAFT 算法推举领导的 sentinel 线程负责主库的客观下线并同时负责故障自动转移,这种情况叫 “客观失效”(即 ODOWN)。
具体流程如下图所示:
配置项 | 参数类型 | 作用 |
---|---|---|
port | 整数 | 启动哨兵进程端口 |
dir | 文件夹目录 | 哨兵进程服务临时文件夹,默认为/tmp,要保证有可写入的权限 |
sentinel down-after-milliseconds | <服务名称><毫秒数(整数)> | 指定哨兵在监控Redis服务时,当Redis服务在一个默认毫秒数内都无法回答时,单个哨兵认为的主观下线时间,默认为30000(30秒) |
sentinel parallel-syncs | <服务名称><服务器数(整数)> | 指定可以有多少个Redis服务同步新的主机,一般而言,这个数字越小同步时间越长,而越大,则对网络资源要求越高 |
sentinel failover-timeout | <服务名称><毫秒数(整数)> | 指定故障切换允许的毫秒数,超过这个时间,就认为故障切换失败,默认为3分钟 |
sentinel notification-script | <服务名称><脚本路径> | 指定sentinel检测到该监控的redis实例指向的实例异常时,调用的报警脚本。该配置项可选,比较常用 |
Redis 三主三从可以最完整的保证数据的完整性,但是所需要的服务器资源也是最多的。在一般情况,统筹兼顾数据完整性和方案经济性,一般最优解是采用一主两从三哨兵的模式,我们使用的配置如下所示:
实例 | IP | 端口 | 备注 |
---|---|---|---|
Redis(主) | 192.168.33.135 | 9500 | |
Redis(从) | 192.168.33.136 | 9501 | |
Redis(从) | 192.168.33.133 | 9502 | |
Sentinel(1) | 192.168.33.135 | 26379 | 默认端口 |
Sentinel(2) | 192.168.33.136 | 26379 | 默认端口 |
Sentinel(3) | 192.168.33.133 | 26379 | 默认端口 |
首先,我们在 135 机器上,创建配置存放的目录,命令如下:
mkdir -p /usr/local/redis/master
mkdir -p /usr/local/redis/sentinel
创建完毕,如下图所示:
接着,我们在 136 机器上,创建类似的目录,命令如下:
mkdir -p /usr/local/redis/slave
mkdir -p /usr/local/redis/sentinel
创建完毕,如下图所示:
最后,我们在 133 机器上,创建目录,命令如下:
mkdir -p /usr/local/redis/slave
mkdir -p /usr/local/redis/sentinel
创建完毕,如下图所示:
至此,所有的目录都创建完毕。
我们首先,在 135 机器上,创建 master 的配置,使用 vim 创建对应的配置文件,具体命令如下:
vim /usr/local/redis/master/redis-master.conf
接着,我们写入如下配置内容:
bind 0.0.0.0
port 9500
logfile "9500.log"
dbfilename "dump-9500.rdb"
daemonize yes
rdbcompression yes
接着,我们在 136 机器上,配置从的配置,使用 vim 创建对应的配置文件,具体命令如下:
vim /usr/local/redis/slave/redis-slave.conf
接着,我们写入如下配置内容:
bind 0.0.0.0
port 9501
logfile "9501.log"
dbfilename "dump-9501.rdb"
daemonize yes
rdbcompression yes
slaveof 192.168.33.135 9500
我们再次配置 133 机器上的从配置,使用 vim 创建对应的配置文件,具体命令如下:
vim /usr/local/redis/slave/redis-slave.conf
接着,我们写入如下配置内容:
bind 0.0.0.0
port 9502
logfile "9502.log"
dbfilename "dump-9502.rdb"
daemonize yes
rdbcompression yes
slaveof 192.168.33.135 9502
至此,我们的主从配置已经配置完毕了。
我们首先,在 135 机器上,创建 sentinel 的配置,使用 vim 创建对应的配置文件,具体命令如下:
vim /usr/local/redis/sentinel/sentinel.conf
接着,我们写入如下配置内容:
port 26379
logfile "26379.log"
daemonize yes
# 这里定义主库的IP和端口,还有最后的2表示要达到2台sentinel认同才认为主库已经挂掉
sentinel monitor mymaster 192.168.33.135 9500 2
# 主库在30000毫秒(即30秒)内没有反应就认为主库挂掉(即主观失效)
sentinel down-after-milliseconds mymaster 30000
# 若新主库当选后,允许最大可以同时从新主库同步数据的从库数
sentinel parallel-syncs mymaster 1
# 若在指定时间(即180000毫秒,即180秒)内没有实现故障转移,则会自动再发起一次
sentinel failover-timeout mymaster 180000
接着,在 136 和 133 机器创建同样的配置文件,写入一模一样的配置内容。
我们首先,在 135 机器启动 Redis 主,具体命令如下:
redis-server /usr/local/redis/master/redis-master.conf
接着,我们在 136 机器启动 Redis 从,具体命令如下:
redis-server /usr/local/redis/slave/redis-slave.conf
同样,我们在 133 机器启动 Redis 从,具体命令如下:
redis-server /usr/local/redis/slave/redis-slave.conf
至此,我们的主从已经启动完毕,现在,我们启动哨兵,首先在 135 机器启动,具体命令如下:
redis-server /usr/local/redis/sentinel/sentinel.conf --sentinel
接着,在 133 和 136 输入相同的命令启动即可。注意,这里我们直接使用了 redis-server 命令启动了 sentinel,也可以直接使用 redis 提供的 redis-sentinel 工具直接启动。全部启动完毕之后,我们可以使用 ps 命令,查看,具体命令如下:
ps -ef | grep redis-server
全部启动成功,则输出如下:
我们首先,使用 redis-cli 登录 redis master,即 135 机器的 9500 端口,具体命令如下:
redis-cli -p 9500
接着,我们使用 GET 命令,查看键 URL 的内容,具体命令如下:
GET URL
执行完毕后,如下图所示:
同时,我们在 136 机器的 slave 上即 9501 端口,同样查看 URL 的值,执行完毕后,如下图所示:
最后,我们同样在 133 的 slave 上即 9502 端口查看 URL 的值,执行完毕后,如下图所示:
我们看到,此时三个机器上的 URL 都为空,现在,我们在 135 机器的 9500 端口也就是 redis master 上设置 URL 的值,具体命令如下:
SET URL www.haicoder.net
执行完毕后,如下图所示:
现在,我们可以在两台 slave 上,再次查看 URL 的值,我们发现,这两台 slave 都有对应的值了,如下图所示:
即,我们的主从配置完毕了。
现在,我们验证高可用,也就是能够实现自动的主动切换,我们首先停掉 master,也就是 135 机器的 9500 端口,我们执行如下命令即可:
shutdown
执行完毕后,如下图所示:
此时,我们模拟了主节点宕机了,现在,我们分别查看两个 slave 节点的配置,我们分别登录 133 和 136 机器的 slave,执行如下命令:
INFO Replication
在 9501 端口执行后,输出如下:
我们看到,此时原来是 slave 的已经自动切换为了 master,这就是哨兵在起作用,实现了故障后的主备切换,如果这时候我们在新的 9501 的 master 上设置数据,并在 9502 端口查看数据,此时也是可以同步数据的。
原文链接:链接
其他:目录
更多文章,可以关注下方公众号: