redis - 主从复制

Posted yangjunh

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了redis - 主从复制相关的知识,希望对你有一定的参考价值。

主从复制

基本介绍

主从复制(master-slave replication), 可以让从服务器(slave server)成为主服务器(master server)的精确复制品。

特点

  • 异步复制
    • 不会阻塞主服务器,初次复制,主服务器也可以处理请求
    • 不会一直阻塞从服务器,复制新版时用旧版处理请求,删除旧版载入新版时会阻塞
  • 从服务器会以1次/second的频率向主服务器报告复制流处理进度。(Redis 2.8以后)
  • 一个主有多个从,从也可以有自己的从

用途

  • 数据备份
  • 进行数据持久化
  • 读写分离负载
    • 只读服务器(2.6后默认模式)
      • 用配置文件的 slave-read-only 选项控制
      • 用命令行的 [CONFIG SET] 命令控制
      • DEBUGCONFIG 等管理式命令仍可以使用, 所以我们还是不应该将服务器暴露给互联网或者任何不可信网络。 不过, 使用 redis.conf 中的命令改名选项, 我们可以通过禁止执行某些命令来提升只读从服务器的安全性。

复制功能的运作原理

  • 建立从时,从向主发送一个 [SYNC] 命令
  • 主接到 [SYNC] ,开始执行 [BGSAVE]
  • 主保存操作执行期间, 将新执行的写入命令保存到缓冲区
  • [BGSAVE] 执行完毕后, 主将得到的.rdb 文件发送给从
  • 从接收 .rdb 文件并载入到内存中。
  • 之后主服务器会以 Redis 命令协议的格式, 将写命令缓冲区中积累的所有内容都发送给从服务器
  • 多个从同时向主发送 [SYNC] ,主也只需执行一次 [BGSAVE] 命令

复制时主从连接断开

  • 从自动重连
  • 从根据主的情况选择执行完整重同步/部分重同步
    • 尝试继续执行原有的复制进程
    • 主为被发送的复制流创建一个内存缓冲区
    • 主从都记录一个复制偏移量和一个主 ID
    • 断开重连后从向主请求继续执行原来的复制进程
      • 如果从记录的主 ID 和当前要连接的主 ID 相同,并且从记录的偏移量所指定的数据仍然保存在主的复制流缓冲区里面,则用 [PSYNC] 继续执行原有复制过程
      • 否则执行完整重同步

配置

  • 方法一:配置文件

    # 从的配置文件
    slaveof master_IP master_PORT
    
  • 方法二:redis命令

    # 从的客户端
    127.0.0.1:6379> SLAVEOF master_IP master_PORT
    

只读从服务器

从 Redis 2.6 开始, 从服务器支持只读模式, 并且该模式为从服务器的默认模式。

只读模式由 redis.conf 文件中的 slave-read-only 选项控制, 也可以通过 CONFIG SET 命令来开启或关闭这个模式。

只读从服务器会拒绝执行任何写命令, 所以不会出现因为操作失误而将数据不小心写入到了从服务器的情况。

即使从服务器是只读的, DEBUGCONFIG 等管理式命令仍然是可以使用的, 所以我们还是不应该将服务器暴露给互联网或者任何不可信网络。 不过, 使用 redis.conf 中的命令改名选项, 我们可以通过禁止执行某些命令来提升只读从服务器的安全性。

你可能会感到好奇, 既然从服务器上的写数据会被重同步数据覆盖, 也可能在从服务器重启时丢失, 那么为什么要让一个从服务器变得可写呢?

原因是, 一些不重要的临时数据, 仍然是可以保存在从服务器上面的。 比如说, 客户端可以在从服务器上保存主服务器的可达性(reachability)信息, 从而实现故障转移(failover)策略。

从服务器相关配置

如果主服务器通过 requirepass 选项设置了密码, 那么为了让从服务器的同步操作可以顺利进行, 我们也必须为从服务器进行相应的身份验证设置。

对于一个正在运行的服务器, 可以使用客户端输入以下命令:

config set masterauth <password>

要永久地设置这个密码, 那么可以将它加入到配置文件中:

masterauth <password>

另外还有几个选项, 它们和主服务器执行部分重同步时所使用的复制流缓冲区有关, 详细的信息可以参考 Redis 源码中附带的 redis.conf 示例文件。

主服务器只在有至少 N 个从服务器的情况下,才执行写操作

从 Redis 2.8 开始, 为了保证数据的安全性, 可以通过配置, 让主服务器只在有至少 N 个当前已连接从服务器的情况下, 才执行写命令。

不过, 因为 Redis 使用异步复制, 所以主服务器发送的写数据并不一定会被从服务器接收到, 因此, 数据丢失的可能性仍然是存在的。

以下是这个特性的运作原理:

  • 从服务器以每秒一次的频率 PING 主服务器一次, 并报告复制流的处理情况。
  • 主服务器会记录各个从服务器最后一次向它发送 PING 的时间。
  • 用户可以通过配置, 指定网络延迟的最大值 min-slaves-max-lag , 以及执行写操作所需的至少从服务器数量 min-slaves-to-write

如果至少有 min-slaves-to-write 个从服务器, 并且这些服务器的延迟值都少于 min-slaves-max-lag 秒, 那么主服务器就会执行客户端请求的写操作。

你可以将这个特性看作 CAP 理论中的 C 的条件放宽版本: 尽管不能保证写操作的持久性, 但起码丢失数据的窗口会被严格限制在指定的秒数中。

另一方面, 如果条件达不到 min-slaves-to-writemin-slaves-max-lag 所指定的条件, 那么写操作就不会被执行, 主服务器会向请求执行写操作的客户端返回一个错误。

以下是这个特性的两个选项和它们所需的参数:

  • min-slaves-to-write
  • min-slaves-max-lag

详细的信息可以参考 Redis 源码中附带的 redis.conf 示例文件。

以上是关于redis - 主从复制的主要内容,如果未能解决你的问题,请参考以下文章

Spring之redis主从复制(非哨兵模式)

redis实战_04_yucong_主从复制

详解Redis 主从复制及主从复制原理

redis主从复制最好采用哪种结构

redis高可用之主从复制,哨兵,集群

Redis(主从复制哨兵模式集群)概述及部署