1.基本概念
-
高可用
- 数据少丢失,如果Redis发生宕机,可以通过AOF(记录操作)和RDB(内存快照)恢复数据,保证少丢失数据
- 服务少中断,通过增加冗余副本
-
Redis的主从库模式,数据副本一致,主从库间采用读写分离
- 主库:负责读操作和写操作,将写操作同步到从库上
- 从库:负责读操作
-
如果使用读写分离,即使每一个redis实例只开一个进程,但是多个实例的单进程相当于还是多进程,会引入新的并发安全问题(需要引入分布式锁,增加其他开销)
-
同步方式
- 一次性复制
- 分批同步
2.主从同步
2.1主从库间如何进行第一次同步?
-
replicaof(redis5.0以后)|slaveof(redis5.0之前)命令形成主库和从库关系,三个阶段完成数据第一次同步\
-
从库命令:replicaof 172.16.19.3 6379
-
同步三阶段
-
1.主从库间建立连接、协商同步过程,为全量复制做准备
-
作用:从库与主库建立连接后,告诉主库进行同步,主库确认回复后,主从库间就可以开始同步
-
具体过程
-
从库给主库发送 psync 命令,表示要进行数据同步,主库根据这个命令的参数来启动复制(主库的 runID,复制进度 offset)\
-
runID 每个 Redis 实例启动时都会自动生成的一个随机 ID,用来唯一标记这个实例(第一次设为?)\
-
offset 复制的偏移量 (第一次设为?)\
-
-
主库执行FULLRESYNC 响应命令带上两个参数:主库 runID 和主库目前的复制进度 offset
- FULLRESYNC 响应表示第一次复制采用的全量复制,也就是说,主库会把当前所有的数据都复制给从库
-
-
-
2.主库将所有数据同步到从库(RDB)
-
主库将所有数据同步给从库。从库收到数据后,在本地完成数据加载。这个过程依赖于内存快照生成的 RDB 文件
-
主库执行 bgsave 命令,生成 RDB 文件,将文件发给从库\
-
从库接收到 RDB 文件后,会先清空当前数据库,然后加载 RDB 文件\
- 避免数据不一致
-
注意:主库不会被阻塞,仍然可以正常接收请求
-
为了保证主从库的数据一致性,主库会在内存中用专门的 replication buffer,记录 RDB 文件生成后收到的所有写操作\
-
-
3.同步最新的操作到从库
- 把此时 replication buffer 中的修改操作发给从库,从库再重新执行这些操作
- 此时从库和主库就保持一致了
-
2.2主从级联模式分担全量复制时的主库压力
-
全量复制中的耗时操作
-
生成RDB文件(通过cow将内存数据写入磁盘)
- 主库忙于 fork 子进程生成 RDB 文件,fork 这个操作会阻塞主线程处理正常请求,从而导致主库响应应用程序的请求速度变慢\
-
传输RDB文件
- 传输 RDB 文件也会占用主库的网络带宽,同样会给主库的资源使用带来压力(是g级别的文件)\
-
-
使用主 - 从 - 从解决上述问题
- 将主库的压力分散到从库上
-
可以手动选择一个从库(比如选择内存资源配置较高的从库),用于级联其他的从库\
-
**第一次全量复制后,基于长连接的命令传播,可以避免频繁建立连接的开销
**
**
**
2.3主从库间网络断了
-
2.8之前,网络断开后进行一次全量复制,开销非常大
-
2.8以后,网络断了之后,主从库会采用增量复制的方式继续同步(断开网络期间的操作复制一份)
-
保持增量数据的关键 repl_backlog_buffer
-
当主从库断连后,主库会把断连期间收到的写操作命令
- 写入 replication buffer
- 把这些操作命令也写入 repl_backlog_buffer 这个缓冲区
-
repl_backlog_buffer是一个环形缓冲区,主库会记录自己写到的位置,从库则会记录自己已经读到的位置(自己记录消费位置)(kafak是broker记录消费者消费的位置)\
-
master_repl_offset 主库偏移量
-
slave_repl_offset从库偏移量\
-
恢复过程
-
从库首先会给主库发送 psync 命令,并把自己当前的 slave_repl_offset 发给主库
-
主库会判断自己的 master_repl_offset 和 slave_repl_offset 之间的差距\
-
主库只用把 master_repl_offset 和 slave_repl_offset 之间的命令操作同步给从库就行\
-
-
注意:因为 repl_backlog_buffer 是一个环形缓冲区,所以在缓冲区写满后,主库会继续写入,此时,就会覆盖掉之前写入的操作
-
解决办法
-
调整 repl_backlog_size 这个参数\
-
缓冲空间的计算公式是:缓冲空间大小 (数据不一致的情况)= 主库写入命令速度 * 操作大小 - 主从库间网络传输命令速度 * 操作大小\
-
实际情况可多扩充几倍
-
\
3.总结
-
网络带宽也是计算机的一种资源
-
长链接复制操作指令
-
主从同步基本原理
-
全量复制
- 第一次不可避免
- 使用主 - 从 - 从模式,来缓解主库的压力
-
基于长链接的命令传播\
- 常规同步阶段
-
增量复制
- 网络断连后使用
- repl_backlog_size设置较大,否则会导致数据被覆盖\
-
-
两个buffer(缓冲区)
-
repl_backlog_buffer(记录所有操作缓冲区)\
-
**replication buffer(记录需要发给从库|客户端的缓冲区)
**
-
-
两个offset
-
master_repl_offset\
-
**slave_repl_offset
**
-
\