持久化是复制的基础。复制技术使得读写操作分散到独立的服务器上。类似于读写锁。
复制方式
两种复制方式:一种是主(master)-从(slave)模式(星型拓扑),一种是从(slave)-从(slave)模式(有向无环):
通过配置多个Redis实例独立运行、定向复制,形成Redis集群。master负责写、slave负责读。
复制的优点
1、高可用。
2、高性能。在Redis集群中,master负责写,slave负责读。
3、水平扩展性。通过增加slave机器可以横向(水平)扩展Redis的查询服务能力。
复制的缺点
- 数据一致性问题。如何保证master服务器写入的数据能够及时同步到slave机器上。
- 编程复杂。如何在客户端实现读写分离。
复制的实时性和数据一致性矛盾。更好的一致性方案通常会损失性能,降低吞吐量和服务能力。
从2.6版本开始,支持对slave的只读模式的配置,默认对slave的配置也是只读。
主从复制(全量复制)
通过主从复制,多个slave拥有和master相同的数据库副本。
主从复制的特点:
1 master可以有多个slave。
2 slave可以连接其他slave,形成图状结构。
3 Redis使用异步复制。从2.8开始,slave每秒发起一个Ack来确认复制流的处理进度。
4 主从复制不会阻塞master。slave在执行首次同步的时候可以使用旧数据集提供查询;也可以配置为当Master与slave失去联系时,让Slave返回客户端错误提示。
5 当slave要删掉旧的数据集,并重新加载新版数据时,slave会阻塞连接请求(一般发生在与Master断开重连后的恢复阶段)
6 主从复制可以提高系统的可伸缩性,用slave专门处理client的读请求,比如sort操作可以使用slave来处理。也可以做简单的数据冗余。
7 master禁用数据持久化,只在slave上开启数据持久化。
主从复制的过程:
1 如果设置了slave,无论是第一次连接还是重连到Master,slave建立和master的连接后,它都会发出SYNC命令;
2 当Master收到SYNC命令之后,会做两件事:
a) Master执行BGSAVE,即在后台保存数据到磁盘(rdb快照文件)。
b) Master同时将新收到的写入和修改数据集的命令存入缓冲区(非查询类)。
3 当Master在后台把数据保存到快照文件完成之后,Master会把这个快照文件传送给slave,而slave把内存清空后,加载该文件到内存中。
4 Master也会把这期间收集到缓冲区中的命令,通过Reids命令协议形式转发给slave,slave执行这些命令,实现和Master的同步。从master到slave的同步数据的命令和从client发送的命令使用相同的协议格式。
5 Master/slave此后会不断通过异步方式进行命令的同步,达到最终数据的一致。
6 需要注意的是Master和slave之间一旦发生重连都会引发全量同步操作。但在2.8之后版本,也可能是部分同步操作。
7 如果master同时收到多个slave发来的同步连接命令,只会启动一个进程来写rdb快照文件,然后发送给所有slave。
配置slave服务器:
slaveof 192.168.100.2 6379 #指定master的ip和端口
增量复制
全量复制过程中,slave和master断开后、slave和master重新连接上,需要全量复制,这个策略是不友好的,从2.8开始,Redis提供了增量复制的机制:
master除了备份RDB文件之外,还会维护一个环形队列,以及环形队列的写索引和slave同步的全局offset,环形队列存储最新的操作数据,当slave和maste断开重连之后,会把slave维护的offset,也就是上次同步到哪里的这个值告诉master,同时会告诉master上次和当前slave连接的master的runid,满足下面两个条件,Redis不会全量复制:
- slave传递的run id和master的run id一致。
- master在环形队列上可以找到offset的值。
满足上面两个条件,Redis就不会全量复制。
增量复制是由psync命令实现的,slave通过psync命令让Redis进行增量复制,当然最终是否能够增量复制取决于环形队列的大小和slave的断线时长以及重连的master是否是之前的master。
Redis同时也提供了当没有slave需要同步的时候,多久可以释放环形队列。repl-backlog-ttl 3600。
增量复制混合复制
Redis4.0支持rdb和aof混合的复制方式。
免持久化复制(实验功能)
免持久化机制叫做Diskless Replication,前面基于RDB快照文件写磁盘的方式可以看出,Redis必须先把RDB文件写入磁盘,再进行网络传输。免持久化复制是通过网络直接把RDB文件传送给slave。在Redis2.8.18版本开始支持。
repo-diskless-sync no
为了让后续的slave能够尽量赶上本次复制,参数repl-diskless-sync-delay指定复制开始的时间延迟。
半同步复制
和MySQL复制策略类似,Redis复制是异步的,但也提供了半同步的复制策略,半同步复制策略的语义是:在maste接受写操作的时候,只有当一定时间间隔内,至少有N台slave在线,否则写入无效。
上面功能的实现基于Redis下面特性:
- slaves每秒钟会ping一次master,告诉master当前slave复制到哪里了。
- master会记住每个slave复制到哪里了。
通过下面配置来指定时间间隔和N这个值:
min-slaves-to-write
min-slaves-max-lag
当配置了上面两个参数之后,如果写操作没有满足上面的两个条件,那么master会报错,并且将本次写操作视为无效。这有点像CAP理论中的“C”,即一致性实现,虽然半同步策略不能完全保证master和slave的数据一致性,但是相对减少了不一致性的窗口期。
网友评论