redis第六讲

主从库:将一份数据同时保存在多个实例上。即使有一个实例出现了故 障,需要过一段时间才能恢复,其他实例也可以对外提供服务。

读写分离:

读操作:主库、从库都可以接收;

写操作:首先到主库执行,然后,主库将写操作同步给从库

y?

redis vip漂移 redis runid_redis

如上图上面那个,会让数据在三个实例上的副本不一致。如果我们非要保持这个数据在三个实例上一致,就要涉及到加锁、实例间协商是否完成修改等一系列操作,但这会带来巨额的开销。
replicaof 172.16.19.3 6379 变成172.16.19.3的从库。
第一次同步:

redis vip漂移 redis runid_redis_02

  • 从库给主库发送 psync 命令,表示要进行数据同步,主库根据这个命令的参数 来启动复制。psync 命令包含了主库的 runID 和复制进度 offset 两个参数。runID,是每个 Redis 实例启动时都会自动生成的一个随机 ID,用来唯一标记这个实 例。当从库和主库第一次复制时,因为不知道主库的 runID,所以将 runID 设 为“?”。offset,此时设为 -1,表示第一次复制。
  • 主库收到 psync 命令后,会用 FULLRESYNC 响应命令带上两个参数:主库 runID 和主库 目前的复制进度 offset,返回给从库。从库收到响应后,会记录下这两个参数。
  • 在第二阶段,主库将所有数据同步给从库。从库收到数据后,在本地完成数据加载。这个 过程依赖于内存快照生成的 RDB 文件。从库接收到 RDB 文件后,会先清空当前数据库,然后加载 RDB 文件。为了保证主从库的数据一致性,主库会在内存中用专门的 replication buffer,记录 RDB 文件生成后收到的所有写操作。
  • 第三个阶段,主库会把第二阶段执行过程中新收到的写命令,再发送给从 库。

主从级联模式分担全量复制时的主库压力

如果从库数量很多,就会导致主库忙于 fork 子进程生 成 RDB 文件,进行数据全量同步。fork 这个操作会阻塞主线程处理正常请求。传输 RDB 文件也会占用主库的网络带宽,同样 会给主库的资源使用带来压力。

通过“主 - 从 - 从”模式将主库生成 RDB 和传输 RDB 的压力, 以级联的方式分散到从库上。们可以再选择一些从库(例如三分之一的从库),在这些从库上执行如下命令,让它们和刚才所选的从库,建立起主从关系。

redis vip漂移 redis runid_nosql_03

但是网络断了怎么办?
Redis 2.8 之前,如果主从库在命令传播时出现了网络闪断,那么,从库就会和主库重 新进行一次全量复制。2.8之后,增量复制。
主库会把断连期间收到的写操作命令,写入 replication buffer,同时也 会把这些操作命令也写入 repl_backlog_buffer 这个缓冲区。
repl_backlog_buffer 是一个环形缓冲区,主库会记录自己写到的位置,从库则会记录自己 已经读到的位置。
随着主库不断接 收新的写操作,它在缓冲区中的写位置会逐步偏离起始位置,我们通常用偏移量来衡量这 个偏移距离的大小,对主库来说,对应的偏移量就是 master_repl_offset。
主从库的连接恢复之后,从库首先会给主库发送 psync 命令,并把自己当前的 slave_repl_offset 发给主库,主库会判断自己的 master_repl_offset 和 slave_repl_offset 之间的差距。
此时,主库只用把 master_repl_offset 和 slave_repl_offset 之间的命令操作同步给从库就行。
环形缓冲空间小了怎么办?
可以调整 repl_backlog_size 这个参 数。这个参数和所需的缓冲空间大小有关。缓冲空间的计算公式是:缓冲空间大小 = 主库 写入命令速度 * 操作大小 - 主从库间网络传输命令速度 * 操作大小。在实际应用中,考虑 到可能存在一些突发的请求压力,我们通常需要把这个缓冲空间扩大一倍,即 repl_backlog_size = 缓冲空间大小 * 2。