专栏首页微观技术Redis故障主从切换演示

Redis故障主从切换演示

Redis 2.4之后的版本开始集成了Sentinel,用于监控redis集群中 Master状态的工具,是Redis的高可用性解决方案。

sentinel 系统可以监视一个或者多个master节点,以及这些master节点的所有从节点;当某个master节点下线时,自动将该master下的某个从节点升级为master替代已下线的master节点继续处理请求。集群中的其他redis服务器自动指向新的master同步数据。

一般建议sentinel采取奇数台,防止某一台sentinel无法连接到master导致误切换。

Sentinel当前最新的稳定版本称为Sentinel 2,随着redis2.8的安装包一起发行。安装完Redis2.8后,可以在redis2.8/src/里找到Redis-sentinel的启动脚本

snetinel的状态会被持久化地写入sentinel的配置文件中。每次当收到一个新的配置时,或者新创建一个配置时,配置会被持久化到硬盘中,并带上配置的版本戳。这意味着,可以安全的停止和重启sentinel进程。

sentinel内部有3个定时任务:

1、每个sentinel每10秒会对master和slave发送info命令,两个目的:

a)发现slave节点

b)确认主从关系

2、每2秒每个sentinel通过master节点的channel交换信息(pub/sub)。master节点上有一个发布订阅的频道(__sentinel__:hello)。sentinel节点通过__sentinel__:hello频道进行信息交换(对节点的"看法"和自身的信息),达成共识。

3、每1秒每个sentinel对其他sentinel和redis节点执行ping操作(相互监控),这个其实是一个心跳检测,是失败判定的依据。

主观下线:

所谓主观下线(Subjectively Down, 简称 SDOWN)指的是单个Sentinel实例对服务器做出的下线判断,即单个sentinel认为某个服务下线(有可能是接收不到订阅,之间的网络不通等等原因)。

主观下线就是说如果服务器在down-after-milliseconds给定的毫秒数之内, 对 Sentinel 发送的 PING 命令没有回复, 或者返回一个错误, 那么 Sentinel 将这个服务器标记为主观下线。

客观下线:

客观下线(Objectively Down, 简称 ODOWN)指的是多个 Sentinel 实例在对同一个服务器做出 SDOWN 判断, 并且通过 SENTINEL is-master-down-by-addr 命令互相交流之后, 得出的服务器下线判断,然后开启failover。

客观下线条件只适用于主服务器: 对于任何其他类型的 Redis 实例, Sentinel 在将它们判断为下线前不需要进行协商, 所以从服务器或者其他 Sentinel 永远不会达到客观下线条件。只要一个 Sentinel 发现某个主服务器进入了客观下线状态, 这个 Sentinel 就可能会被其他 Sentinel 推选出, 并对失效的主服务器执行自动故障迁移操作。

单机启动三个实例,一主两从。创建三个目录,分别是6379、6380、6381,创建conf、log、db三个目录,并拷贝redis.conf到对应的conf目录下

  • (master)修改6379/conf 目录下的redis.conf 配置
daemonize yes                     <== daemon进程运行
pidfile /Users/onlyone/software/redis/6379/redis.pid   <== 进程id存放文件
port 6379                                    <== 端口
logfile /Users/onlyone/software/redis/6379/log/redis.log       <== 日志目录
dir /Users/onlyone/software/redis/6379/db/                     <== db目录
  • (slave) 修改6380/conf 目录下的redis.conf 配置
daemonize yes                     <== daemon进程运行
pidfile /Users/onlyone/software/redis/6380/redis.pid     <== 进程id存放文件
port 6380                                   <== 端口
logfile /Users/onlyone/software/redis/6380/log/redis.log       <== 日志目录
dir /Users/onlyone/software/redis/6380/db/                     <== db目录
slaveof 127.0.0.1 6379      <== master机器
  • (slave) 修改6381/conf 目录下的redis.conf 配置
daemonize yes                     <== daemon进程运行
pidfile /Users/onlyone/software/redis/6381/redis.pid   <== 进程id存放文件
port 6381                                   <== 端口
logfile /Users/onlyone/software/redis/6381/log/redis.log       <== 日志目录
dir /Users/onlyone/software/redis/6381/db/                     <== db目录
slaveof 127.0.0.1 6379      <== master机器

启动实例

./redis-server  /Users/onlyone/software/redis/6379/conf/redis.conf &
./redis-server  /Users/onlyone/software/redis/6380/conf/redis.conf &
./redis-server  /Users/onlyone/software/redis/6381/conf/redis.conf &

查看进程信息

ps -ef|grep redis

501 32933     1   0 10:24上午 ??         0:00.25 ./redis-server 127.0.0.1:6380
501 32986     1   0 10:27上午 ??         0:00.09 ./redis-server 127.0.0.1:6381
501 32880 12633   0 10:22上午 ttys000    0:00.43 ./redis-server *:6379

查看master节点信息

./redis-cli -p 6379 "info"


。。。省略。。。
\# Replication
role:master
connected_slaves:2
slave0:ip=127.0.0.1,port=6380,state=online,offset=518,lag=1
slave1:ip=127.0.0.1,port=6381,state=online,offset=518,lag=1
master_replid:38605ae9c8d326685b9d114b31efffc405b54129
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:518
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:1
repl_backlog_histlen:518
。。。省略。。。

查看slave(6380)节点信息

./redis-cli -p 6380 "info"


。。。省略。。。
\# Replication
role:slave
master_host:127.0.0.1
master_port:6379
master_link_status:up
master_last_io_seconds_ago:10
master_sync_in_progress:0
slave_repl_offset:658
slave_priority:100
slave_read_only:1
connected_slaves:0
master_replid:38605ae9c8d326685b9d114b31efffc405b54129
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:658
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:1
repl_backlog_histlen:658
。。。省略。。。

主库写数据

➜  src ./redis-cli -p 6379
127.0.0.1:6379> set name tom
OK
127.0.0.1:6379> get name
"tom"
127.0.0.1:6379>

查看从库同步数据

➜  src ./redis-cli -p 6380
127.0.0.1:6380> get name
"tom"
127.0.0.1:6380>

主从切换

修改 /Users/onlyone/software/redis/sentinel/sentinel.conf 配置:

// 指定sentinel去监视一个名为mymaster的Master,Master的IP地址为127.0.0.1,端口 6379,只要有一个sentinel监听到主观下线就发起切换
sentinel monitor mymaster 127.0.0.1 6379 1

// 指定Sentinel判定Master断线的时间。(单位为毫秒,判定为主观下线SDOWN)
sentinel down-after-milliseconds mymaster 6000

启动一个哨兵进程:

./redis-server  /Users/onlyone/software/redis/sentinel/sentinel.conf --sentinel &

查看进程:

➜  ~ ps -ef|grep redis
  501 40383     1   0  9:38下午 ??         0:02.92 ./redis-server 127.0.0.1:6380
  501 40392     1   0  9:38下午 ??         0:02.92 ./redis-server 127.0.0.1:6381
  501 41238     1   0 10:03下午 ??         0:00.82 ./redis-server 127.0.0.1:6379
  501 41486 40536   0 10:15下午 ttys000    0:00.18 ./redis-server *:26379 [sentinel]
  501 41010 40297   0  9:56下午 ttys003    0:00.01 ./redis-cli -p 6381
  501 40523 40441   0  9:40下午 ttys004    0:00.02 ./redis-cli -p 6380
  501 41502 40922   0 10:16下午 ttys005    0:00.01 ./redis-cli -p 6379

将6379端口的redis 进程(master)kill掉,Sentinel监控台的日志:

41486:X 21 Nov 22:17:25.082 # +sdown master mymaster 127.0.0.1 6379
41486:X 21 Nov 22:17:25.082 # +odown master mymaster 127.0.0.1 6379 #quorum 1/1
41486:X 21 Nov 22:17:25.082 # +new-epoch 1
41486:X 21 Nov 22:17:25.082 # +try-failover master mymaster 127.0.0.1 6379
41486:X 21 Nov 22:17:25.083 # +vote-for-leader 9dfae48ecf5b4cacda8053c138660b89eecf124e 1
41486:X 21 Nov 22:17:25.083 # +elected-leader master mymaster 127.0.0.1 6379
41486:X 21 Nov 22:17:25.083 # +failover-state-select-slave master mymaster 127.0.0.1 6379
41486:X 21 Nov 22:17:25.159 # +selected-slave slave 127.0.0.1:6381 127.0.0.1 6381 @ mymaster 127.0.0.1 6379
41486:X 21 Nov 22:17:25.159 * +failover-state-send-slaveof-noone slave 127.0.0.1:6381 127.0.0.1 6381 @ mymaster 127.0.0.1 6379
41486:X 21 Nov 22:17:25.229 * +failover-state-wait-promotion slave 127.0.0.1:6381 127.0.0.1 6381 @ mymaster 127.0.0.1 6379
41486:X 21 Nov 22:17:25.682 # +promoted-slave slave 127.0.0.1:6381 127.0.0.1 6381 @ mymaster 127.0.0.1 6379
41486:X 21 Nov 22:17:25.682 # +failover-state-reconf-slaves master mymaster 127.0.0.1 6379
41486:X 21 Nov 22:17:25.775 * +slave-reconf-sent slave 127.0.0.1:6380 127.0.0.1 6380 @ mymaster 127.0.0.1 6379
41486:X 21 Nov 22:17:26.697 * +slave-reconf-inprog slave 127.0.0.1:6380 127.0.0.1 6380 @ mymaster 127.0.0.1 6379
41486:X 21 Nov 22:17:26.697 * +slave-reconf-done slave 127.0.0.1:6380 127.0.0.1 6380 @ mymaster 127.0.0.1 6379
41486:X 21 Nov 22:17:26.780 # +failover-end master mymaster 127.0.0.1 6379
// 选举 6381 为新的master
41486:X 21 Nov 22:17:26.780 # +switch-master mymaster 127.0.0.1 6379 127.0.0.1 6381
// 6380作为slave,监听主节点master
41486:X 21 Nov 22:17:26.780 * +slave slave 127.0.0.1:6380 127.0.0.1 6380 @ mymaster 127.0.0.1 6381
// 6379作为slave,监听主节点master
41486:X 21 Nov 22:17:26.780 * +slave slave 127.0.0.1:6379 127.0.0.1 6379 @ mymaster 127.0.0.1 6381
// 6379 依然处于主观下线
41486:X 21 Nov 22:17:32.840 # +sdown slave 127.0.0.1:6379 127.0.0.1 6379 @ mymaster 127.0.0.1 6381

重新把6379 redis启动

41486:X 21 Nov 22:40:01.164 # -sdown slave 127.0.0.1:6379 127.0.0.1 6379 @ mymaster 127.0.0.1 6381
41486:X 21 Nov 22:40:11.153 * +convert-to-slave slave 127.0.0.1:6379 127.0.0.1 6379 @ mymaster 127.0.0.1 6381

本文分享自微信公众号 - 微观技术(weiguanjishu),作者:TomGE

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2019-11-22

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 一些Redis很实用的工作技巧

    常用技术框架、开源中间件,系统架构、数据库、大公司架构案例、常用三方类库、项目管理、线上问题排查、个人成长、思考等知识

    用户7676729
  • 聊聊领域驱动设计

    DDD全写 domain driver design ,也称为领域驱动设计。大型复杂业务系统架构一般都会用到,在提高系统扩展性有很大帮助。

    用户7676729
  • 如何通过Binlog来实现不同系统间数据同步

    互联网时代除了业务迭代速度快,还有就是数据增速也比较快。单应用、单实例、单数据库的时代早已不复返。现在,作为技术研发,如果参与的项目没有用到分库分表,都不好意说...

    用户7676729
  • 3.Redis常用命令:String

    字符串类型是Redis中最为基础的数据存储类型,它在Redis中是二进制安全的,这便意味着该类型可以接受任何格式的数据,如JPEG图像数据或Json对象描述信息...

    陈树义
  • redis介绍,redis安装,redis持久化,redis数据类型

    Redis是一个开源的使用ANSI C语言编写、支持网络、可基于内存亦可持久化的日志型、Key-Value数据库,并提供多种语言的API。从2010年3月15日...

    端碗吹水
  • Redis 从入门到起飞(上)

    1. Redis 介绍1.1 NoSQL 基本概念1.2 NoSQL 分类1.3 Redis 基本概念1.4 发展历史1.5 应用场景2. Redis 安装2....

    芋道源码
  • redis常用操作,redis操作键值,redis安全设置

    之前已经介绍过redis里各种数据类型的赋值操作,在这里则介绍一下各个数据类型的其他常用的操作。

    端碗吹水
  • Redis系列---操作命令及数据类型

    我们接下来操作的命令用的是Redis自带的客户端工具,在安装redis的目录下面有个redis-cli的,我们启动它即可,启动之前要先启动redis喔!

    Arebirth
  • 初识Redis

    老七Linux
  • Python全栈(六)项目前导之1.Redis介绍及数据类型介绍

    随着互联网+大数据时代的来临,传统的关系型数据库已经不能满足中大型网站日益增长的访问量和数据量。这个时候就需要一种能够快速存取数据的组件来缓解数据库服务的I/O...

    cutercorley

扫码关注云+社区

领取腾讯云代金券