Redis的高可用方案有三种:

  • master/slave主从方案

主节点提供读写操作,从节点提供读操作;

主节点故障,需要手动主备切换;

读写主还是从,由客户端控制;

  • 哨兵(sentinel)模式来进行主从替换以及故障恢复

在主从模式的基础上增加sentinel监听,主节点不可用,自动将slave提升为master;

客户端通过sentinel获取主/从节点;

  • redis cluster集群方案

去中心化,平等结构,数据槽;

这里主要介绍下,简单的主从模式与sentinel结构;

redis master/slave (replication)

master/slave 是为了解决点单故障而出现的,slave是对master的镜像;

主要工作机制

  • master-slave使用异步方式复制数据,同样使用异步的确认slave-to-master
  • 一个master可以拥有多个slave
  • slave也可以连接slave (4.0以后,所有的sub-slaves从maser接受复制数据)
  • master在做复制操作的时候,不会block master的读写操作
  • slave在复制操作过程中,根据配置使用旧的数据提供服务或者返回错误(配置replica-serve-stale-data);完成复制后,旧的数据会被删除,新的会被加载,期间会拒绝连接( block incoming connections)
  • slave可做横向扩容或者数据的安全性与高可用
  • master可关闭持久化,直接内存读写,slave开启持久化,保存数据;注意master重启,slave也会同步空的数据

redis replication 工作原理

  • 两个参数确定了同步的信息

replication ID: 伪随机数,与当前数据集生成,每个master具有

offset:master/slave 之间同步的位置记录

当slave连接到master后,使用PSYNC命令发送当前master 的replication ID与offset

  • 正常情况,master发送增量数据给slave,offset开始
  • slave发送无效的replication ID/master没有足够的backlog,会开始全量复制(full resynchronization)
全量复制的过程
  1. master接受到全量复制的请求,启动bgsave进程生成rdb file;同时,会开启一个buffer缓存所有新的写命令

关于buffer的配置:

client-output-buffer-limit replica 256MB 64MB 60

如果在复制期间,内存缓冲区超过60秒一直消耗超过 64MB,或者一次性超过 256MB,那么停止复制,复制失败。后两个参数是配合使用的,假如:消耗超过64MB 一直持续了59秒,但是60秒的时候不超过64MB了,那么就保持连接继续复制。

  1. bgsave完成后,master会将rdb file 给slave;slave会将其存到磁盘并加载到内存

  2. master 发送缓存的命令给slave

下面为master的日志记录,同步的过程

1
2
3
4
5
6
7
8
3829:M 10 Oct 2019 14:47:08.193 * Replica 10.226.50.31:6379 asks for synchronization
3829:M 10 Oct 2019 14:47:08.193 * Full resync requested by replica 10.226.50.31:6379
3829:M 10 Oct 2019 14:47:08.193 * Starting BGSAVE for SYNC with target: disk
3829:M 10 Oct 2019 14:47:08.194 * Background saving started by pid 4102
4102:C 10 Oct 2019 14:47:09.637 * DB saved on disk
4102:C 10 Oct 2019 14:47:09.637 * RDB: 6 MB of memory used by copy-on-write
3829:M 10 Oct 2019 14:47:09.685 * Background saving terminated with success
3829:M 10 Oct 2019 14:47:09.731 * Synchronization with replica 10.226.50.31:6379 succeeded
无盘化复制

正常情况下,全量复制需要在磁盘上创建rdb文件,并从磁盘上读取该文件发送给slave

磁盘效率低下,会严重影响master的效率,可配置不经过磁盘,直接发送

1
2
3
4
repl-diskless-sync yes

# 等待 5s 后再开始复制,因为要等更多 replica 重新连接过来
repl-diskless-sync-delay 5

注意:

  1. 不建议使用slave作为master的热备,关掉master的持久化;master宕机后会立马同步到slave导致数据丢失
  2. master的备份方案需要做,防止本地文件丢失;sentinel可以监控并切换,但有可能master failure还未检测到就已经重启,也会导致情况1
至少N个slave才能写成功

Redis 2.8开始,可以配置至少有N个slave连接的情况下,master才能接受写请求

由于redis使用异步复制,不能保证slave真正接受到了某个写请求,于是有可能有一个丢失窗口

工作特点:

  • slave每秒钟ping master,确认复制的数据的数量
  • master记录每个slave最后一次ping的时间
  • 用户可配置不大于最大秒数的延迟的最小的slave数量

如果有N个slave,延迟小于M秒,则写入成功;否则返回错误,写入失败

redis配置参数:

  • min-slaves-to-write <number of slaves>
  • min-slaves-max-lag <number of seconds>
过期key处理
  • replica不会过期key,只会等待master过期key。如果master过期了一个key,或者通过LRU淘汰了一个key,那么会模拟一条del命令发送给replica
  • master过期数据,因此在slave内存中可能存在逻辑上已经过期的数据还未及时被删除,slave中使用(its logical clock)only for read operations确定key不存在,不违反一致性
  • Lua脚本执行期间不会执行过期策略;发送同样的Lua脚本到slave保证一致性
heartbeat

主从节点互相都会发送 heartbeat 信息。

master 默认每隔 10秒 发送一次 heartbeat,replica node 每隔 1秒 发送一个 heartbeat。

redis replication 配置

配置是比较简单的,了解基本原理主要是为了在出现问题时,能够快速定位问题

1
2
3
4
5
6
7
replicaof 10.226.50.31 6381


# master 配置认证密码
# requirepass foobared
# slave 认证
# masterauth foobared

replicaof [ip] [port]

在5.0.4之前使用的时slaveof;

修改配置的bind/port/logfile/dbfilename/dir等配置参数,启动redis

1
2
redis-server /etc/redis-6379.conf
redis-server /etc/redis-6381.conf

启动后查看redis的replication 6379, 角色为slave;写入数据报错

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
[root@localhost ~]# redis-cli 
127.0.0.1:6379> info replication
# Replication
role:slave
master_host:10.226.50.31
master_port:6381
master_link_status:up
master_last_io_seconds_ago:10
master_sync_in_progress:0
slave_repl_offset:128880
slave_priority:100
slave_read_only:1
connected_slaves:0
master_replid:a868c97d4f90ce5e77d6d6bd1787e8f61df35eff
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:128880
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:1
repl_backlog_histlen:128880
127.0.0.1:6379> set a b
(error) READONLY You can't write against a read only replica.

master的角色为master,存在master replid,slave 同步的位置offset;写入数据成功,查看slave,数据已经同步

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
[root@localhost ~]# redis-cli -p 6381
127.0.0.1:6381> info replication
# Replication
role:master
connected_slaves:1
slave0:ip=10.226.50.31,port=6379,state=online,offset=128978,lag=0
master_replid:a868c97d4f90ce5e77d6d6bd1787e8f61df35eff
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:128978
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:1
repl_backlog_histlen:128978
127.0.0.1:6381> set a b
OK

redis sentinel

Sentinel(哨兵)是用于监控redis集群中Master状态的工具,sentinel哨兵模式已经被集成在redis2.4之后的版本中。

sentinel进程可以监视一个或者多个redis master/slave服务;当某个master服务下线时,自动将该master下的某个从服务升级为master服务替代已下线的master服务继续处理请求。

写博客太需要时间,未完,待续。。。