一、什么是主从同步?

主从同步,就是将数据冗余备份,主库(Master)将自己库中的数据,同步给从库(Slave)。

从库可以一个,也可以多个,如图所示:

二、为什么需要主从同步?

Redis 虽然有 RDB 和 AOF 持久化技术,可以在服务器重启的情况下保证内存中的数据不会丢失(但不意味着数据不丢,重启的时候还是会有不可用的情况)。

但是如果服务器关闭后,再也起不来了(比如硬件故障),那意味着数据是完全丢失的!会对业务产生重大影响。

所以,主从同步的必要性,在于数据的高可用。它可以保证机器故障时,还有其他的服务器可以进行故障转移。

问题来了,多台服务器冗余同一份数据,Redis 是如何保证数据的一致性的?

三、Redis 是如何做到主从同步的?

简单概括,有两点:

  1. 一切修改只在主库进行:即主库可读可写,从库只读不可写;
  2. 写操作从主库同步到从库:全量同步、增量同步。

(一)全量同步

1. 建立连接 协商同步

1.1 使用客户端 redis-cli 连接从库,执行 replicaof 命令,指定主库 IP 和端口;

1.2 从库响应后,执行 psync 命令,它包含 主库 runid复制偏移量 offset 两个参数:

  • runid:启动时自动生成随机唯一 ID。首次同步时,主库 runid 未知,所以为 ?
  • offset:表示复制的进度,第一次同步时,其值为 -1

1.3 主库收到 psync 命令后,使用 FULLRESYNC 命令响应从库,同时也包含 主库 runid复制偏移量 offset 两个参数,从库会记录这两个参数。

注:replicaof 命令等同于 slaveof 命令,Redis 5.0 之前使用 slaveof 命令。

2. RDB 同步

2.1 主库执行 bgsave 命令,此时将 fork 出子进程生成 RDB 文件,新命令会写入到缓冲区;

2.2 发送 RDB 文件到从库;

2.3 从库清空数据后,载入 RDB 文件。

注一:为保证数据一致性,bgsave 执行后,主库会持续写入新命令到缓冲区,直到从库加载 RDB 完成;

注二:bgsave 创建了子进程,子进程独立负责 RDB 生成的工作,生成 RDB 的过程中,不会阻塞 Redis 主库,主库依然可以正常处理命令。

3. 命令同步

3.1 完成 RDB 载入后,从库会回复确认消息给主库,主库会将缓冲区的写命令发送给从库;

3.2 从库接收主库的写命令并执行,使得主从数据一致。

注:命令执行后,长连接会一直保持,写操作命令也会一直同步,保证主从数据的一致性;

这个过程也称为「基于长连接的命令传播」。

(二)增量同步

命令传播的过程中,如果出现 网络故障 导致连接断开,此时新的写命令将无法同步到从库。

即便是抖动后断开又恢复网络连接,但此时 TCP 连接已经断开,数据肯定是需要重新同步了。

  • 在 Redis 2.8 之前,从库只能和主库重新发起全量同步,对于较大的 RDB 文件,网络恢复时间较长;
  • 从 Redis 2.8 开始,从库已支持增量同步,只会把断开的时候没有发生的写命令,同步给从库。

详细过程如下:

  1. 网络恢复后,从库发生 psync 命令给主库,并携带之前主库返回的 runid,还有复制的偏移量 offset;
  2. 主库收到命令后,核查 runid 和 offset,确认没问题将响应 CONTINUE 命令;
  3. 主库发送网络断开期间的写命令,从库接收命令并执行。

实际上,主库在进行命令传播的过程中,做了两个事情:

  1. 发送写命令给从库;
  2. 写命令写入 repl_backlog_buffer 复制积压缓冲区,保存最近传播的写命令。

复制积压缓冲区,是一个环形缓冲区。主库除了拥有 repl_backlog_buffer,还存在复制点位 master_repl_offset;

同理,从库,也有复制点位 slave_repl_offset;

如果从库的 psync 命令指定的 offset,数据还存在 repl_backlog_buffer 缓冲区里,也就是:

master_repl_offset - size < slave_repl_offset,即主库最小的偏移量,小于从库的偏移量,说明数据还在环形缓冲区里。

所以,只要主库的缓冲区足够大,足以容纳最近的写命令(Redis 协议),就可以在网络中断后使用增量同步了。

默认 repl_backlog_buffer = 1M,如果写入数据量较大,比如 1M/s,显然,网络故障 1秒后,复制积压缓冲区数据无效,所以应该增大它的值。

具体大小,需要根据实际情况确定。建议设置 10M 以上,大概就是 10s 以内的中断,因为 Redis 服务器启动也需要一定时间。


文章来源于本人博客,发布于 2022-05-28,原文链接:https://imlht.com/archives/259/

Redis 主从同步原理的更多相关文章

  1. Redis主从同步原理-SYNC【转】

    和MySQL主从复制的原因一样,Redis虽然读取写入的速度都特别快,但是也会产生读压力特别大的情况.为了分担读压力,Redis支持主从复制,Redis的主从结构可以采用一主多从或者级联结构,下图为级 ...

  2. Redis——主从同步原理

    刚接触到Redis,首先对Redis有一个初步的了解. 开源,免费,遵守BSD协议,key-value数据库. 可以将内存中的数据保存在磁盘中,重启的时候可以再次加载使用. 多种key-value类型 ...

  3. Redis主从同步原理-PSYNC【转】

    Reids复制数据主要有2种场景: 1. 从服务器从来第一次和当前主服务器连接,即初次复制 2. 从服务器断线后重新和之前连接的主服务器恢复连接,即断线后重复制   对于初次复制来说使用SYNC命令进 ...

  4. Redis主从同步分析(转)

    一.Redis主从同步原理 1.1 Redis主从同步的过程 配置好slave服务器连接的master后,slave会建立和master的连接,然后发送sync命令.无论是第一次同步建立的连接还是连接 ...

  5. 15.6,redis主从同步

    redis主从同步 原理:1. 从服务器向主服务器发送 SYNC 命令.2. 接到 SYNC 命令的主服务器会调用BGSAVE 命令,创建一个 RDB 文件,并使用缓冲区记录接下来执行的所有写命令.3 ...

  6. Redis主从同步分析

    一.Redis主从同步原理1.1 Redis主从同步的过程配置好slave服务器连接的master后,slave会建立和master的连接,然后发送sync命令.无论是第一次同步建立的连接还是连接断开 ...

  7. Linux - redis主从同步

    目录 Linux - redis主从同步 环境准备 配置主从同步 测试写入数据,主库写入数据,检查从库数据 手动进行主从复制故障切换 Linux - redis主从同步 原理: 从服务器向主服务器发送 ...

  8. 04 Redis主从同步

    redis主从同步 原理:1. 从服务器向主服务器发送 SYNC 命令.2. 接到 SYNC 命令的主服务器会调用BGSAVE 命令,创建一个 RDB 文件,并使用缓冲区记录接下来执行的所有写命令.3 ...

  9. redis 主从同步

    修改redis.conf配置文件 vi redis.conf 在编辑模式下 输入  /slaveof 来搜索 将slaveof启用 即 将#删除 依次配置所有 slave 并将进程 kill 掉 重启 ...

  10. redis主从同步故障切换及集群配置

    一.redis是一中高性能的缓存数据库, 原理:1. 从服务器向主服务器发送 SYNC 命令.2. 接到 SYNC 命令的主服务器会调用BGSAVE 命令,创建一个 RDB 文件,并使用缓冲区记录接下 ...

随机推荐

  1. 武装你的WEBAPI-OData Versioning

    本文属于OData系列 目录 武装你的WEBAPI-OData入门 武装你的WEBAPI-OData便捷查询 武装你的WEBAPI-OData分页查询 武装你的WEBAPI-OData资源更新Delt ...

  2. 利用css var函数让你的组件样式输出规范样式API,可定制性更高;

    我们平时在使用Elementui Antdesing这些UI库时,难免会碰到使用deep强行侵入式去修改组件内部样式的情况:   比如下列代码,我们需要把ant的分页样式进行高度自定义,就得使用dee ...

  3. 2023-05-09:石子游戏中,爱丽丝和鲍勃轮流进行自己的回合,爱丽丝先开始 。 有 n 块石子排成一排。 每个玩家的回合中,可以从行中 移除 最左边的石头或最右边的石头, 并获得与该行中剩余石头值

    2023-05-09:石子游戏中,爱丽丝和鲍勃轮流进行自己的回合,爱丽丝先开始 . 有 n 块石子排成一排. 每个玩家的回合中,可以从行中 移除 最左边的石头或最右边的石头, 并获得与该行中剩余石头值 ...

  4. 2021-04-07:给定一个非负数组arr,长度为N,那么有N-1种方案可以把arr切成左右两部分,每一种方案都有,min{左部分累加和,右部分累加和},求这么多方案中,min{左部分累加和,右部分累加和}的最大值是多少? 整个过程要求时间复杂度O(N)。

    2021-04-07:给定一个非负数组arr,长度为N,那么有N-1种方案可以把arr切成左右两部分,每一种方案都有,min{左部分累加和,右部分累加和},求这么多方案中,min{左部分累加和,右部分 ...

  5. 2021-05-17:数组中所有数都异或起来的结果,叫做异或和。给定一个数组arr,可以任意切分成若干个不相交的子数组。其中一定存在一种最优方案,使得切出异或和为0的子数组最多。返回这个最多数量。

    2021-05-17:数组中所有数都异或起来的结果,叫做异或和.给定一个数组arr,可以任意切分成若干个不相交的子数组.其中一定存在一种最优方案,使得切出异或和为0的子数组最多.返回这个最多数量. 福 ...

  6. 2021-08-03:完美洗牌问题。给定一个长度为偶数的数组arr,假设长度为N*2,左部分:arr[L1……Ln],右部分: arr[R1……Rn],请把arr调整成arr[L1,R1,L2,R2,

    2021-08-03:完美洗牌问题.给定一个长度为偶数的数组arr,假设长度为N*2,左部分:arr[L1--Ln],右部分: arr[R1--Rn],请把arr调整成arr[L1,R1,L2,R2, ...

  7. Django自定义storage上传文件到Minio

    首先新建一个MyStorage.py,自定义Storage类 from io import BytesIO from django.core.files.storage import Storage ...

  8. Typo in static class property declarationeslint

    eslint 检测提示 Typo in static class property declarationeslint 找了半天原来是propTypes 写成了PropTypes (就是一个首字母大写 ...

  9. docker 部署 springboot项目和直接运行 jar 文件详细步骤

    目前docker发布springboot有两种方式,一种是制作镜像,另一种是直接运行jar 文件 第一种使用镜像来部署 一.创建项目目录 [root@dex ~]# mkdir /opt/backst ...

  10. 代码随想录算法训练营Day28 回溯算法 | 491.递增子序列 46.全排列 47.全排列 II

    代码随想录算法训练营 491.递增子序列 题目链接:491.递增子序列 给定一个整型数组, 你的任务是找到所有该数组的递增子序列,递增子序列的长度至少是2. 示例: 输入: [4, 6, 7, 7] ...