引言

我们之前操作 Redis 都是单机版,但是实际应用中没人使用单机版,都是搭建集群的方式。这篇文章要介绍的主从复制,是指将一台 Redis 服务器的数据,复制到其他 Redis 服务器,我们将前者称为主节点 master,将后者称为从节点 slave(replica)。在这个过程中,数据的复制是单向的,即只能从主节点到从节点。并且从节点只能读数据,不能写数据,实现读写分离。

  • 一个主节点可以有多个从节点,一个从节点只能有一个主节点。所有的服务器默认都是主节点。
  • 从节点下面还可以有从节点,形成一个图的结构

主从复制的优点

  1. 数据冗余:主从复制实现了数据的热备份,是持久化之外的一种数据冗余方式。
  2. 故障恢复:当主节点出现问题时,可以由从节点提供服务,实现快速的故障恢复;实际上是一种服务的冗余。
  3. 负载均衡:在主从复制的基础上,配合读写分离,写数据时应用连接主节点,读数据时应用连接从节点,分担服务器负载;尤其是在写少读多的场景下,通过多个从节点分担读负载,可以大大提高 Redis 服务器的并发量。
  4. 高可用基础:主从复制是哨兵模式和集群能够实施的基础。

开启主从复制

主从复制的前提就是多个 Redis 服务器,因此要多个配置文件。

开启主从复制的方式有两种:

  • 配置配置文件

    从服务器配置master节点

    # 主节点ip port
    # replicaof <masterip> <masterport>
    # 主节点的认证密码(可选)
    # masterauth <master-password>
  • 显示命令开启

    客户端使用该命令slaveof [ip] [port]

    INFO REPLLICATION命令可查看节点信息

主从复制的具体实现

主从复制的实现可以分为三个阶段:建立连接、数据同步、命令传播

1. 建立连接

  • 发送 slaveof 异步命令

  • 建立 socket 连接

    连接成功后从节点会为该 socket 建立一个专门处理复制工作的文件事件处理器,负责后续的复制工作,如接收 RDB 文件、接收命令传播等;

  • 发送 ping 命令

    从节点成为主节点的客户端之后,发送 ping 命令进行首次请求,目的是检查 socket 连接是否可用,以及主节点当前是否能够处理请求

  • 身份验证

    取决于从节点是否设置 masterauth 选项,而这个又取决于主节点是否设置 requirepass

  • 发送从节点端口信息

2. 数据同步

连接建立完成后,要进行主从数据库的数据同步,这一步也可以看作从节点中数据的初始化。数据同步有旧版和新版两种。我们先来看看旧版 Redis 怎么实现数据同步的

旧版同步

旧版同步使用的命令是 sync,同步方式是全量复制。以下是sync命令的执行步骤:

  • 从服务器向主服务器发送 sync 命令
  • 主服务器收到后执行 BGSAVE 的rgb持久化命令,生成一个RDB文件。并用一个缓冲区记录生成rgb文件期间执行的所有写命令。
  • 主服务器将 rgb 文件发送给从服务器,从服务器载入整个 rgb 文件,同步数据库状态至执行 BGSAVE 时主服务的状态
  • 主服务器将记录在缓冲区的写命令发送给从服务器。至此从服务和主服务数据库状态达到一致。

旧版同步功能的缺陷:

  • 断线后重连需要再次发送 sync 同步命令,主服务再次生成 rgb 文件,从服务器载入恢复数据库状态。简单来说就是断线后又要全量复制,但其实没有必要,我们只需要同步断线后到重新连接期间主服务器变化的数据即可。

    并且,sync是一个非常耗费资源的操作,因此旧版同步是非常低效的。

新版同步

新版同步使用的命令是 psync ,同步方式是增量复制

psync 有完成重同步和部分重同步两种模式。完整重同步其实就是sync,主要用于处理初次服务的情况。部分重同步主要用于处理断线后重连的情况。部分重同步不需要重新生成、传送和载入整个rdb文件,只需要将从服务器缺少的写命令发送给从服务器执行即可。完美的解决了旧版同步效率低下的问题。

下面我们就来看看他是如何实现的?首先要了解几个概念

  • 主节点和从节点的复制偏移量

    主节点和从节点会各自维护一个复制偏移量 ( offset ),代表的是主节点向从节点传递的字节数。主节点每次向从节点传播 N 个字节数据时,主节点的 offset 增加 N;同理,当从节点每次收到主节点传来的 N 个字节数据时,从节点的 offset 增加 N。通过比较主节点和从节点的 offset 可以判断数据库状态是否一致,如果两者的 offset 相同,则一致,否则不一致;也可以根据两者的 offset 找出从节点缺少的数据。

  • 主节点的复制积压缓冲区

    主节点维护的一个固定长度的先进先出 ( FIFO) 队列,默认大小是 1MB。当主节点开始有从节点时,主节点创建复制积压缓冲区,其作用是备份主节点最近发送给从节点的数据。保存的数据有两方面:

    • 最近传播的写命令。为什么最近呢?因为队列长度固定,老的命令会被新的取代
    • 队列中每个字节对应的复制偏移量

    当从服务器重新连接上主机时,会通过 psync 命令把自己的offset发给主节点

    • 如果offset之后的数据全部在队列中,执行部分重同步(增量复制)
    • 如果offset之后的数据不全在队列中,执行完整重同步(全量复制)
  • 服务器的运行ID

    每个redis服务器都有自己的运行ID,在启动时自动生成,由40个随机的十六进制字符组成

    当从节点对主节点进行初次复制时,主节点会把自己的运行ID发给从节点,从节点保存并在断线重连上主节点时把次ID发送给主节点:

    • 如果此ID和主节点当前连接的ID一致,说明是同一个状态,可以进行增量复制
    • 如果不同,只能进行全量复制

总结:psync的执行流程:

命令传播

数据同步阶段完成后,主从节点进入命令传播阶段;在这个阶段主节点将自己执行的写命令发送给从节点,从节点接收命令并执行,从而保证主从节点数据的一致性。

这个阶段没啥可说的,就是把主节点执行的写命令发给从节点,让它们也执行一次,保证主从一致性

心跳检测

在命令传播阶段,从服务器默认会以每秒一次的频率向主服务器发送replconf ACK <replication_offset>,其中replication_offset是它当前的复制偏移量。心跳检测的目的有以下三个:

  • 检测主从服务器的网络连接状态

    如果主服务器超过一秒没有收到从服务的该命令,那么主服务器就知道主从连接出现问题了

  • 辅助实现min-slaves

    主服务我们可以配置以下两个参数来防止不安全写命令传播,如果从节点小于3或者lag大于10,主服务器都会拒绝执行写命令

    # 从节点的最小个数
    # min-replicas-to-write 3
    # 从节点lag的最大值
    # min-replicas-max-lag 10
  • 检测命令丢失

    上面说过心跳检测命令还发送了从节点自身保存的offset。主节点会与自己的 offset 进行对比,如果从节点数据缺失(如网络丢包),主节点会找到缺失的数据,并把这些数据重新推送给服务器(这里也会利用复制积压缓冲区)。

    参考

redis 主从复制详解的更多相关文章

  1. Redis主从复制详解

    1. 概述 主从复制:主节点负责写数据,从节点负责读数据,主节点定期把数据同步到从节点保证数据的一致性 2. 主从复制的相关操作 (1)配置文件:在从服务器的配置文件中加入 slaveof<ma ...

  2. redis配置详解

    ##redis配置详解 # Redis configuration file example. # # Note that in order to read the configuration fil ...

  3. Redis:默认配置文件redis.conf详解

    转: Redis:默认配置文件redis.conf详解 # Redis配置文件样例 # Note on units: when memory size is needed, it is possibl ...

  4. Redis配置文件redis.conf详解

    一.Redis配置文件redis.conf详解 # Note on units: when memory size is needed, it is possible to specifiy # it ...

  5. redis配置文件详解-3

    redis3.0以上配置文件 #################################INCLUDES ################################### include ...

  6. CentOS7/RHEL7安装Redis步骤详解

    CentOS7/RHEL7安装Redis步骤详解 CentOS7/RHEL7安装Redis还是头一次测试安装了,因为centos7升级之后与centos6有比较大的区别了,下面我们就一起来看看Cent ...

  7. Redis协议详解

    smark Beetle可靠.高性能的.Net Socket Tcp通讯组件 支持flash amf3,protobuf,Silverlight,windows phone Redis协议详解 由于前 ...

  8. Redis学习——详解Redis配置文件(三)

    一.Redis脚本简介 在我们介绍Redis的配置文件之前,我们先来说一下Redis安装完成后生成的几个可执行文件: redis-server .redis-cli .redis-benchmark ...

  9. Python操作redis学习系列之(集合)set,redis set详解 (六)

    # -*- coding: utf-8 -*- import redis r = redis.Redis(host=") 1. Sadd 命令将一个或多个成员元素加入到集合中,已经存在于集合 ...

随机推荐

  1. Java中Arrays数组的定义与使用

    初始化 Java中数组是固定长度,数组变量是个对象. NullPointerException 空指针异常. ArrayIndexOutOfBoundsException 索引值越界. 数组三种初始化 ...

  2. linux signal信号(SIGHUP、SIGINT、SIGQUIT、SIGILL、SIGTRAP、SIGABRT...........................)

    SIGHUP /* hangup */       ~~~~~~      SIGHUP,hong up ,挂断.本信号在用户终端连接(正常或非正常)结束时发出, 通常是在终端的控制进程结束时, 通知 ...

  3. 卷向字节码-Java异常到底是怎么被处理的?

    你好呀,我是why,你也可以叫我歪歪. 比如下面这位读者: 他是看了我<神了!异常信息突然就没了?>这篇文章后产生的疑问. 既然是看了我的文章带来的进一步思考,恰巧呢,我又刚好知道. 虽然 ...

  4. C++利用模板在Windows上快速调用DLL函数

    更新日志 --------- 2021/08/01 更新V2.2 增加 GetHmodule 函数 - 允许用户获取HMODULE以验证加载DLL是否成功. 2021/08/03 更新V2.3 增加 ...

  5. 可怕!字节跳动大牛爆出的“Android进阶指南”,强到无法形容,GitHub已标星“8.5k”!

    前言 从去年8月份开始,我开始重新找工作,在这期间刷了不少面试题和大牛博客,无意中薅到一份字节跳动大牛整理的一份"Android进阶指南",包含Android面试常见问题.主流技术 ...

  6. 微信小程序测试点

    一.测试范围 1.权限测试 需要检查以下几种情况下微信用户访问的权限 1)未授权微信登录小程序 未授权时,一般使用一些业务功能的时候,都会弹出提醒:先授权再操作对应功能.or在提交数据到后台的时候,会 ...

  7. xubuntu下制作自定义的ISO文件

    by han; 1.打开命令编辑器,建立文件 # sudo su # mkdir -p /opt/custom_conf/user_custom_conf/config 2.将自定义的设置复制保存到/ ...

  8. Use Emacs as Personal Knowledge Base

    http://stackoverflow.com/questions/2014636/how-to-maintain-an-emacs-based-knowledge-base

  9. 关于knn算法的总结思考

    更多的关于k近邻算法的思考 KNN(K- Nearest Neighbor)法即K最邻近法,数据挖掘分类技术中最简单的方法之一 对k近邻算法的总结: 优点部分 其可以解决分类问题,同时可以天然的解决多 ...

  10. 【工作篇】再次熟悉 SpringMVC 参数绑定

    前言 主要现在项目中使用的参数绑定五花八门的,搞得很头大,例如有些用字符串接收日期,用字符串接受数组等等,完全没有利用好 SpringMVC 的优势,这里自己也总结一下,免得到时又要百度谷歌查找. 以 ...