主从复制
1、什么是Redis主从复制?
- 主从复制,是指将一台Redis服务器的数据,复制到其他的Redis服务器。前者称为主节点(master),后者称为从节点(slave);数据的复制是单向的,只能由主节点到从节点。
- 默认情况下,每台Redis服务器都是主节点;且一个主节点可以有多个从节点(或没有从节点),但一个从节点只能有一个主节点。
2、主从复制有哪些好处?
- 读写分离:master 写、slave 读,提高服务器的读写负载能力;
- 负载均衡:基于主从结构,配合读写分离,由 slave 分担 master 负载,并根据需求的变化,改变 slave 的数量,通过多个从节点分担数据读取负载,大大提高 Redis 服务器并发量与数据吞吐量;
- 故障恢复:当 master 出现问题时,由 slave 提供服务,实现快速的故障恢复;
- 数据冗余:实现数据热备份,是持久化之外的一种数据冗余方式;
- 高可用基石:基于主从复制,构建哨兵模式与集群,实现 Redis 的高可用方案。
3、讲一讲读写分离?
Redis提供了主从库模式,以保证数据副本的一致,主从库之间采用的是读写分离的方式。
- 读操作:主库、从库都可以接收;
- 写操作:首先到主库执行,然后,主库将写操作同步给从库。
4、为什么要采用读写分离的方式呢?
- 容易造成数据不一致:假设主从库都可以接收客户端的写操作,当客户端对同一个数据前后修改了多次,每一次的修改请求都发送到不同的实例上,会造成这个数据在多个实例上的副本不一致问题,在读取这个数据的时候,就可能读取到旧的值。如果要保持数据在多个实例的一致性,就要涉及到加锁、实例间协商是否完成修改等一系列操作,但这会带来巨额的开销。
- 保证数据的一致性:主从库模式一旦采用了读写分离,所有数据的修改只会在主库上进行,主库有了最新的数据后,会同步给从库,这样,主从库的数据就是一致的。
5、主从库间如何进行第一次同步?
主从库第一次同步分为三个阶段:
- 第一阶段:建立连接,协商同步;
- 第二阶段:主库同步数据给从库;
- 第三阶段:主库发送新命令给从库;
第一阶段: 主从库间建立连接,从库给主库发送psync命令,表示要进行数据同步,psync命令包含了主库的runID和复制进度offset两个参数。
- runID,是每个Redis实例启动时都会自动生成的一个随机ID,用来唯一标记这个实例。当从库和主库第一次复制时,因为不知道主库的runID,所以将runID设为“?”。
- offset,此时设为-1,表示第一次复制。
第二阶段: 主库收到psync命令后,会用FULLRESYNC响应命令带上两个参数:主库runID和主库目前的复制进度offset,返回给从库。从库收到响应后,会记录下这两个参数。
- FULLRESYNC响应表示第一次复制采用的全量复制,也就是说,主库会把当前所有的数据都复制给从库。
- 主库执行bgsave命令,生成RDB文件,发给从库,从库接收RDB文件,先清空当前数据库,然后加载RDB文件。
第三阶段:由于发送RDB过程期间会产生新数据,因此主库会把第二阶段执行过程中新收到的写命令,再发送给从库。
6、讲一讲主从级联模式分担全量复制时的主库压力?
一次全量复制中,对于主库来说,需要完成两个耗时的操作:生成RDB文件和传输RDB文件。如果从库数量很多,主库进行全量复制,会导致主库忙于fork子进程生成RDB文件,而fork这个操作会阻塞主线程处理正常请求,从而导致主库响应应用程序的请求速度变慢。
通过“主-从-从”模式将主库生成RDB和传输RDB的压力,以级联的方式分散到从库上。
具体如下:
- 1、手动选择一个从库(比如选择内存资源配置较高的从库),用于级联其他的从库。
- 2、再选择一些从库,让和刚才所选的从库,建立起主从关系。
基于长连接的命令传播: 主从完成全量复制后会继续维持一个网络连接,主库会通过这个连接将后续陆续收到的命令操作再同步给从库,这个过程可以避免频繁建立连接的开销。
7、增量复制?
假设主从网络断了之后,主从库会采用增量复制的方式继续同步。
- 全量复制是同步所有数据;
- 增量复制只会把主从库网络断连期间主库收到的命令,同步给从库。
当主从库断连后,主库会把断连期间收到的写操作命令写入repl_backlog_buffer环形缓冲区,主库会记录自己写到的位置,从库则会记录自己已经读到的位置。
8、为什么主从库间的复制不使用AOF呢?
- 虽然AOF记录的操作命令更全,相比于RDB丢失的数据更少,但AOF文件比RDB文件大,网络传输比较耗时。
- 从库在初始化数据时,RDB文件比AOF文件执行更快 。