Redis 分布式部署之哨兵

Redis的主从复制模式下,一旦主节点由于故障不能提供服务,需要人工将从节点晋升为主节点,同时还要通知应用方更新主节点地址,为此Redis从2.8开始正式提供了Redis Sentinel架构来解决此问题。

主从复制的问题

Redis的主从复制模式可以将主节点的数据改变同步给从节点,这样从节点就可以起到两个作用

  • 作为主节点的一个备份,一但主节点出了故障不可达的情况,从节点可以作为后备顶上来
  • 从节点可以扩展主节点的读能力,一旦主节点不能支撑住大并发量的读操作,从节点可以在一定的程度上帮忙主节点分担读压力

但主从复制也带来了以下问题

  • 一旦主节点出现故障,需要手动将一个从节点晋升为主节点,同时需要修改应用的主节点地址
  • 主节点的写能力受到单机的限制
  • 主节点的存储能力受到单机的限制

Redis Sentinel 的高可用性

当主从节点出现故障时,Redis Sentinel能自动的完成故障的发现和故障转移,并通知应用方,从而实现真正的高可用。

Redis Sentinel 是一个分布式架构,其中包含了若干 Sentinel 节点和 Redis 数据节点,每个 Sentinel 节点会对数据节点和其余 Sentinel 节点进行监控,当它发现节点不可达时,会对节点做下线标识。

如果被标识的是主节点,它还会和其它的 Sentinel 节点进行协商,当大多数 Sentinel 节点都认为主节点不可达时,它们会选举出一个 Sentinel 节点来完成自动的故障转移,同时会将这个变化实时通知给 Redis 应用方。

整个过程完全是自动的,不需要人工介入。

Redis Sentinel 的安装和部署

下面将以3个Sentinel节点、1个主节点、2个从节点组成一个Redis Sentinel进行说明,拓扑结构如下

Alt text

1. 部署 Redis 数据节点

创建数据节点相关目录,最后生成的文件树如下

mkdir -p /opt/redis-lab
cd /opt/redis-lab
[root@jiaozhulab redis-lab]# tree
.
├── data
│   ├── 6379.log
│   ├── 6380.log
│   ├── 6381.log
│   ├── dump-6379.rdb
│   ├── dump-6380.rdb
│   └── dump-6381.rdb
├── redis-master
│   ├── 6379.log
│   └── redis-6379.conf
├── redis-slave1
│   ├── 6380.log
│   └── redis-6380.conf
└── redis-slave2
    ├── 6381.log
    └── redis-6381.conf

主节点配置文件

[root@jiaozhulab redis-master]# cat redis-6379.conf
port 6379
daemonize yes
logfile "6379.log"
dbfilename "dump-6379.rdb"
dir "/opt/redis-lab/data"

从节点配置文件

cat redis-6380.conf
port 6380
daemonize yes
logfile "6380.log"
dbfilename "dump-6380.rdb"
dir "/opt/redis-lab/data"
slaveof 127.0.0.1 6379

[root@jiaozhulab redis-slave2]# cat redis-6381.conf
port 6381
daemonize yes
logfile "6381.log"
dbfilename "dump-6381.rdb"
dir "/opt/redis-lab/data"
slaveof 127.0.0.1 6379

验证

redis-cli -h 127.0.0.1 -p 6379 ping
redis-cli -h 127.0.0.1 -p 6380 ping
redis-cli -h 127.0.0.1 -p 6381 ping

确认主从关系

[root@jiaozhulab redis-slave2]# redis-cli  -h 127.0.0.1 -p 6379 info replication
# Replication
role:master
connected_slaves:2
slave0:ip=127.0.0.1,port=6380,state=online,offset=16408,lag=1
slave1:ip=127.0.0.1,port=6381,state=online,offset=16408,lag=1
master_replid:f9f22dca14563d62d020f71457e5ce4c25db166b
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:16408
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:1
repl_backlog_histlen:16408

2. 部署 Sentinel 节点

3个 Sentinel 节点的部署方法完全一致(端口不同),下面以sentinel-1节点的部署为例

配置 sentinel 节点

[root@jiaozhulab redis-sentinel-1]# cat redis-sentinel-26379.conf
port 26379
daemonize yes
logfile "26379.log"
dir "/opt/redis-lab/data"
sentinel myid 6e1e769a22a55731599cbd6686a710cf543cf97b
sentinel deny-scripts-reconfig yes
sentinel monitor mymaster 127.0.0.1 6379 2
sentinel config-epoch mymaster 0
# Generated by CONFIG REWRITE
sentinel leader-epoch mymaster 0
sentinel known-slave mymaster 127.0.0.1 6381
sentinel known-slave mymaster 127.0.0.1 6380
sentinel known-sentinel mymaster 127.0.0.1 26380 69f21283e0cd02f5b754a80d82bd022a9c380dc4
sentinel known-sentinel mymaster 127.0.0.1 26381 25760ad357f7f1556a736671568b4d0e799aeca2
sentinel current-epoch 0

启动sentinel节点

redis-sentinel redis-sentinel-26379.conf

验证

[root@jiaozhulab redis-sentinel-1]# redis-cli -h 127.0.0.1 -p 26379 info Sentinel
# Sentinel
sentinel_masters:1
sentinel_tilt:0
sentinel_running_scripts:0
sentinel_scripts_queue_length:0
sentinel_simulate_failure_flags:0
master0:name=mymaster,status=ok,address=127.0.0.1:6379,slaves=2,sentinels=3

3. 部署技巧

  1. Sentinel节点不应该部署在一台物理机器上
  2. 部署至少三个且奇数个的Sentinel节点