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)
全量复制的过程
- master接受到全量复制的请求,启动bgsave进程生成rdb file;同时,会开启一个buffer缓存所有新的写命令
关于buffer的配置:
client-output-buffer-limit replica 256MB 64MB 60
如果在复制期间,内存缓冲区超过60秒一直消耗超过 64MB,或者一次性超过 256MB,那么停止复制,复制失败。后两个参数是配合使用的,假如:消耗超过64MB 一直持续了59秒,但是60秒的时候不超过64MB了,那么就保持连接继续复制。
bgsave完成后,master会将rdb file 给slave;slave会将其存到磁盘并加载到内存
master 发送缓存的命令给slave
下面为master的日志记录,同步的过程
1 | 3829:M 10 Oct 2019 14:47:08.193 * Replica 10.226.50.31:6379 asks for synchronization |
无盘化复制
正常情况下,全量复制需要在磁盘上创建rdb文件,并从磁盘上读取该文件发送给slave
磁盘效率低下,会严重影响master的效率,可配置不经过磁盘,直接发送
1 | repl-diskless-sync yes |
注意:
- 不建议使用slave作为master的热备,关掉master的持久化;master宕机后会立马同步到slave导致数据丢失
- 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 | replicaof 10.226.50.31 6381 |
replicaof [ip] [port]
在5.0.4之前使用的时slaveof;
修改配置的bind/port/logfile/dbfilename/dir等配置参数,启动redis
1 | redis-server /etc/redis-6379.conf |
启动后查看redis的replication 6379, 角色为slave;写入数据报错
1 | [root@localhost ~]# redis-cli |
master的角色为master,存在master replid,slave 同步的位置offset;写入数据成功,查看slave,数据已经同步
1 | [root@localhost ~]# redis-cli -p 6381 |
redis sentinel
Sentinel(哨兵)是用于监控redis集群中Master状态的工具,sentinel哨兵模式已经被集成在redis2.4之后的版本中。
sentinel进程可以监视一个或者多个redis master/slave服务;当某个master服务下线时,自动将该master下的某个从服务升级为master服务替代已下线的master服务继续处理请求。
写博客太需要时间,未完,待续。。。