一、主从复制了解

定义:主从复制是指将一个redis服务器(又叫主节点master)的数据复制到其他的redis服务器(又叫从节点slave)上。其主要是为了解决数据的多机备份(数据副本)以及性能的扩展(扩展读性能),为高可用、负债均衡等做基础。想想如果是单机应用,当服务器宕机则无法提供服务,且一台机器容量十分有限。有了主从复制则当一个节点损坏(指不可恢复的硬件损坏)时,数据因为有备份,可以方便恢复。

主从复制过程中有如下规则:

  1. 一个master节点可有多个slave节点;
  2. 一个slave 只能有一个master;
  3. 数据流只能单向的从msater复制到slave。
  4. 一般情况下master节点可以进行读和写,slave节点只能进行读操作,写操作被禁止
  5. slave节点挂了不影响其他slave节点的读和master节点的读和写,重新启动后会将数据从master节点同步过来
  6. master节点宕机,不影响slave节点的读,且不会从slave节点重新选一个master,即redis将不再提供写服务。
  7. 让slave节点支持写操作没有意义,因为写入的数据不会被同步到其他节点;且当master节点修改同一条数据后,slave节点的数据会被覆盖掉。

作用:数据冗余备份、故障恢复(主节点故障可由从节点提供服务)、负债均衡(配合读写分离,主节点写从节点读,分担服务器负载来提高并发处理量)、实现高可用及集群的基础。

二、实现主从复制的方式

开启主从复制完全由从节点发起,主节点不做任何操作,有两种方式:slaveof 命令、配置

  1. slaveof 命令:客户端执行  slaveof ip port (ip、port为master节点对应的ip和redis服务端口)。
  2. 配置:在 redis.conf 配置文件添加  slaveof ip port (ip、port同上),另外为实现slave的只读,多加 slave-read-only yes 配置。

另外,当从节点不想做从节点,即要与主节点脱离关系,可以执行命令 slaveof no one 。此时从节点将断开复制,但是已存在的数据不会删除,只是不会再根据以前的主节点修改数据。当redis成为从节点时,会自动把其原来的数据清空。

三、主从信息查看

我们可以在节点执行 info replication 命令来查看节点的主从信息。

  1. 主节点执行:可看到节点角色(master)、偏移量、从节点连接个数、从节点的ip和端口 等信息
  2. 从节点执行:可看到节点角色(slave)、偏移量、连接的主节点ip及端口 等信息

可以在节点执行 info server 命令来查看节点的启动信息。

  1. 主从节点执行:可看到节点启动时使用的配置文件路径、redis版本号、进程id、run_id 等信息

上面查看到的信息中,run_id以及偏移量是两个比较重要的概念,其对下面全量复制和部分复制等有重要作用。

  1. run_id:每个redis服务启动都会生成的一个唯一标识,重启后该id会发生变化。从节点根据该id查找主节点,同时根据主节点该id是否发生变化来判断主节点是否改变以及重启,从而触发全量或部分复制。
  2. 偏移量:主节点在每次执行写操作都会修改该偏移量进行增加,从节点通过自己的偏移量与主节点偏移量的差距来判断自己还有多少信息没有同步,根据两个偏移量差距判断是使用全量复制还是部分复制。

四、全量复制与部分复制

全量复制流程:

  1. 从节点在开始连接主节点时,并不知道主节点偏移量以及runid,所以从节点发 psync ? -1 命令给主节点表示其第一次连接。
  2. 主节点收到信息后知道从节点需要全量复制,于是给从节点发此时主节点的偏移量以及runid
  3. 从节点将主节点的这两个信息进行保存
  4. 主节点发送完信息后会执行bgsave命令进行rdb持久化(上节讲到的一个触发情景),生成对应的rdb文件(可能会因为耗时太长,从节点收不到数据而超时导致复制失败,可增加repl-timeout值处理)。
  5. 在主节点进行持久化时,不避免会有新命令执行,如果不作处理从节点执行完rdb文件后也无法与主节点数据一致。于是主节点会将bgsave之后的操作记录在一个buffer(复制缓冲区)。
  6. 当bgsave完成后主节点会将rdb文件发送给从节点,接着将复制缓冲区中的写命令也发给从节点
  7. 从节点先将旧数据清空,然后执行rdb文件以及buffer发送的数据,从而实现主从数据一致,同时从节点也记录了主节点此刻偏移量等信息。

全量复制需要耗费的时间:

  1. 主节点执行bgsave耗费的时间
  2. 主节点将rdb文件通过网络传输给从节点的时间
  3. 从节点清空遗留数据耗费的时间
  4. 从节点加载rdb文件花费的时间

全量复制发生场景及避免(因为全量复制耗费时长和资源):

  1. 主从第一次建立连接一定会进行全量复制(不可避免)。优化:可以在夜间数据库操作较少时进行
  2. 主节点runid发生变化,如重启主节点。优化:可通过哨兵和集群进行故障转移
  3. 在进行部分复制然而发现复制积压缓冲区(repl_back_buffer)不足,如网络断开时间较长,从节点的偏移量不在复制积压缓冲区内,无法使用部分复制。优化:增大复制积压缓冲区的大小(rel_backlog_size),默认为1M。

部分复制流程:

场景:在redis主从结构中,主从一般部署在不同的机器,即主从之间必须通过网络进行数据传输。当网络异常时,master节点将有部分数据没有同步到slave,一段时间后从节点重新连上主节点,这是就会出现不少数据未同步。当数据量差距不是特别大时,将进行部分复制来减少消耗。流程如下:

  1. 主节点在执行写命令的同时会把命令发送给复制积压缓冲区(repl_back_buffer),复制积压缓冲区将保存写命令及对应的偏移量。注意该缓冲区有大小,当写入的数量超过则会删除最先写进的命令。
  2. 从节点因为网络原因断开一段时间后重新连上主节点并发送 pysnc {offset} {runId} 命令给主节点,其中offset为从节点断开连接前的偏移量,runid为主节点runid。
  3. 主节点判断从节点的偏移量之后的操作还在复制积压缓冲区内,会将缓冲区中的写命令发送给从节点,从节点记录到数据库,此过程为部分复制。
  4. 当从节点的偏移量之后的部分数据不在复制积压缓冲区内(数据被挤出删除),则会在从节点进行全量复制。

五、复制缓冲区与复制积压缓冲区

(1)复制缓冲区

全量复制时使用到的一个缓冲区,每个从节点都会有一个该缓冲区,其主要存放全量复制过程中主节点开始执行bgsave到从节点载入rdb文件这个时间段中主节点的写命令。但是当主节点数据量太大或者网络延迟太大导致上面的时间段太长,即要写入的数据超过缓冲区的大小,导致主节点断开与从节点的连接。可能还会引起全量复制->复制缓冲区溢出导致连接中断->重连->全量复制->复制缓冲区溢出导致连接中断的循环。

复制缓冲区的大小由client-output-buffer-limit slave {hard limit} {soft limit} {soft seconds}配置,默认值为client-output-buffer-limit slave 256MB 64MB 60,其含义是:如果buffer大于256MB,或者连续60s大于64MB,则主节点会断开与该从节点的连接。

(2)复制积压缓冲区

主节点维护的一个缓冲区,在主节点开始有从节点时创建(不管几个从节点都只有一个),其是长度固定且为先进先出的队列,默认大小为1MB。主要用来备份主节点最近发送给从节点的写命令,同时还会存储该写命令对应的偏移量(offset),当主从节点offset的差距过大超过缓冲区长度时,将无法执行部分复制,只能执行全量复制。由于该缓冲区长度有限,因此备份的命令也有限,又因为其为先进先出的队列,所以先进入缓冲区的命令会随着命令的增加被挤出缓冲区。因为部分复制效率高,所以为了能够提高部分复制的几率,可以适当增加积压缓冲区的大小,即设置配置 repl-backlog-size 的大小。

(3)总结

  1. 复制缓冲区是客户端输出缓冲区的一种,主节点会为每一个从节点都创建一个复制缓冲区,主要用于全量复制使用。
  2. 复制积压缓冲区则是一个主节点只有一个,与从节点数量无关。

六、其他

(1)主从redis故障影响:

  1. slave宕机:失去一个读节点,增加读操作压力到别的机器,影响不大
  2. master宕机:失去写操作能力,影响很大,生产环境一般不允许,所以如果没有实现Sentinel,则需要手动将其中一个slave节点设置为主节点,然后让其他节点修改主节点。但是这种手动操作不友好,也会导致服务一段时间的瘫痪,一般还是通过Sentinel处理该问题。

(2)读写分离作用

主从中的读写分离是为了将读操作分摊到多个服务,减轻master的压力,但是读写分离有可能有导致复制数据延迟、读到过期数据

(3)复制风暴

当只有一个主节点且主节点重启,则runid会发生变化,如果有很多个从节点,则会一起对主节点发起全量复制,这将对主节点的性能有一个很大的损耗。所以做主从时要合理规划网络结构。

(4)master宕机导致redis无法提供写服务问题可通过sentinel进行处理

主从模式中,master节点挂了以后,redis就不能对外提供写服务了,其他slave不能自动升级为master,所以一般主从模式还会添加sentinel。当sentinel发现master节点挂了以后,sentinel就会从slave中重新选举一个master。sentinel会在slave中选择一个做为master,并修改它们的配置文件,其他slave的配置文件也会被修改,比如slaveof属性会指向新的master。当旧的master节点重启后将不再是master,而是做为slave接收新的master节点的同步数据。当使用sentinel模式时,客户端连接的是sentinel的ip和端口,由sentinel来提供具体的功能实现,这样当master节点挂掉以后,sentinel就会感知并将新的master节点提供给使用者。

(5)主从模式中会读取到过期数据的原因

因为redis有两种删除策略:

  • 惰性删除:服务器不会主动删除某个过期数据,当客户端查询该数据时服务器才判断该数据是否过期并进行删除。
  • 定期删除:服务器执行定时任务删除过期数据,考虑服务器性能,所以删除的频率和执行时间都有限制。

结合上面两种删除策略,因为从节点不会主动对数据进行修改删除操作(由主节点控制),而主节点又没有及时将过期数据删除,所以客户端很容易就获取到从节点中过期的数据。好在redis3.2处理了这个问题,在从节点读数据时会判断是否过期,过期将不返回。

(6)主从数据不一致

主节点在给从节点发送写命令时是异步的,即不会等待从节点的回复,所以由于网络、性能、命令执行频率等原因导致主从节点很难保持实时的一致性,延迟在所难免。这里我们讲讲主节点中repl-disable-tcp-nodelay配置对延迟的影响。

repl-disable-tcp-nodelay no:该配置默认为no,主要用来控制主节点是否禁止与从节点的TCP_NODELAY。设置为no则不禁止TCP_NODELAY,此时TCP会立马将主节点的数据发送给从节点,带宽增加但延迟变小。设置为yes时,TCP会对包进行合并从而减少带宽,但是发送的频率会降低导致从节点数据延迟增加,一致性变差;具体发送频率与操作系统有关,默认配置为40ms。所以一般还是使用默认的no。

七、主从复制涉及的配置

slaveof <masterip> <masterport>:在从节点设置,设置其连接的主节点的ip和端口,无配置则为主节点。

repl-disable-tcp-nodelay no:同命令传播阶段的延迟有关

masterauth <master-password>:在从节点连接主节点时身份验证

slave-read-only yes:从节点设置为只读;默认为yes。

repl-backlog-size 1mb:复制积压缓冲区的大小设置,默认1MB

client-output-buffer-limit slave 256MB 64MB 60:全量复制过程中主节点复制缓冲区大小设置

repl-timeout 60:与各个阶段主从节点连接超时判断有关

repl-ping-slave-period 10:与命令传播阶段主从节点的超时判断有关

repl-backlog-ttl 3600:当主节点没有从节点时,复制积压缓冲区保留的时间,这样当断开的从节点重新连进来时,可以进行全量复制;默认3600s。如果设置为0,则永远不会释放复制积压缓冲区。

repl-diskless-sync no:作用于全量复制阶段,控制主节点是否使用diskless复制(无盘复制)。所谓diskless复制,是指在全量复制时,主节点不再先把数据写入RDB文件,而是直接写入slave的socket中,整个过程中不涉及硬盘;diskless复制在磁盘IO很慢而网速很快时更有优势。需要注意的是,截至Redis3.0,diskless复制处于实验阶段,默认是关闭的。

repl-diskless-sync-delay 5:该配置作用于全量复制阶段,当主节点使用diskless复制时,该配置决定主节点向从节点发送之前停顿的时间,单位是秒;只有当diskless复制打开时有效,默认5s。之所以设置停顿时间,是基于以下两个考虑:(1)向slave的socket的传输一旦开始,新连接的slave只能等待当前数据传输结束,才能开始新的数据传输 (2)多个从节点有较大的概率在短时间内建立主从

八、命令传播阶段的心跳机制(参考 https://www.cnblogs.com/kismetv/p/9236731.html)

主从节点在命令传播时维持着心跳机制:PING和REPLCONF ACK。心跳机制对于主从复制的超时判断、数据安全等有作用。

1.主->从:PING

每隔指定的时间,主节点会向从节点发送PING命令,这个PING命令的作用,主要是为了让从节点进行超时判断。

PING发送的频率由repl-ping-slave-period参数控制,单位是秒,默认值是10s。

关于该PING命令究竟是由主节点发给从节点,还是相反,有一些争议;因为在Redis的官方文档中,对该参数的注释中说明是从节点向主节点发送PING命令,如下图所示:

但是根据该参数的名称(含有ping-slave),以及代码实现,我认为该PING命令是主节点发给从节点的。相关代码如下:

2. 从->主:REPLCONF ACK

在命令传播阶段,从节点会向主节点发送REPLCONF ACK命令频率是每秒1次;命令格式为:REPLCONF ACK {offset},其中offset指从节点保存的复制偏移量。REPLCONF ACK命令的作用包括:

(1)实时监测主从节点网络状态:该命令会被主节点用于复制超时的判断。此外,在主节点中使用info Replication,可以看到其从节点的状态中的lag值,代表的是主节点上次收到该REPLCONF ACK命令的时间间隔,在正常情况下,该值应该是0或1,如下图所示:

(2)检测命令丢失:从节点发送了自身的offset,主节点会与自己的offset对比,如果从节点数据缺失(如网络丢包),主节点会推送缺失的数据(这里也会利用复制积压缓冲区)。注意,offset和复制积压缓冲区,不仅可以用于部分复制,也可以用于处理命令丢失等情形;区别在于前者是在断线重连后进行的,而后者是在主从节点没有断线的情况下进行的。

(3)辅助保证从节点的数量和延迟:Redis主节点中使用min-slaves-to-write和min-slaves-max-lag参数,来保证主节点在不安全的情况下不会执行写命令;所谓不安全,是指从节点数量太少,或延迟过高。例如min-slaves-to-write和min-slaves-max-lag分别是3和10,含义是如果从节点数量小于3个,或所有从节点的延迟值都大于10s,则主节点拒绝执行写命令。而这里从节点延迟值的获取,就是通过主节点接收到REPLCONF ACK命令的时间来判断的,即前面所说的info Replication中的lag值。

redis学习(叁) -- 主从复制相关推荐

  1. 转-Redis学习手册(目录)

    为什么自己当初要选择Redis作为数据存储解决方案中的一员呢?现在能想到的原因主要有三.其一,Redis不仅性能高效,而且完全免费.其二,是基于C/C++开发的服务器,这里应该有一定的感情因素吧.最后 ...

  2. Redis学习总结(数据类型、持久化、事务、数据删除策略、主从复制、哨兵、缓存雪崩等)

    Redis学习总结 1.Redis是什么 1.概念 2.特点 3.应用场景 2.Linux环境安装redis 3.Redis的数据存储格式 1.String类型 1.String类型的常用操作 2.S ...

  3. Redis学习笔记---Redis的主从复制

    Redis学习笔记-Redis的主从复制 1.Redis的高可用性 高可用性(High Availability)通常来描述一个系统经过专门的设计,从而减少停工时间,而保持其服务的高度可用性. Rei ...

  4. Redis学习笔记之Redis单机,伪集群,Sentinel主从复制的安装和配置

    0x00 Redis简介 Redis是一款开源的.高性能的键-值存储(key-value store).它常被称作是一款数据结构服务器(data structure server). Redis的键值 ...

  5. Redis进阶之主从复制

    转载自  Redis进阶之主从复制 一.主从复制概述 主从复制,是指将一台Redis服务器的数据,复制到其他的Redis服务器.前者称为主节点(master),后者称为从节点(slave):数据的复制 ...

  6. redis学习与入门~~~

    redis学习与入门~~~ 一. Redis 简介: 通常而言目前的数据库分类有几种,包括 SQL/NSQL,,关系数据库,键值数据库等等,分类的标准也不1,Redis本质上也是一种键值数据库的,但它 ...

  7. mysql redis教程_MySQL redis学习与应用

    诸如mysql等关系型数据库,在数据存储在高并发情况下读写性能有所限制,Nosql(非关系型数据库)便应运而生,弥补了关系型数据库的不足. [简介] redis是作为一种key-value存储形式的N ...

  8. Redis学习笔记(五)——持久化及redis.conf配置文件叙述

    对于日常使用来说,学习完SpringBoot集成Redis就够我们工作中使用了,但是既然学习了,我们就学习一些Redis的配置及概念,使我们可以更深层次的理解Redis,以及增强我们的面试成功概率,接 ...

  9. Redis学习笔记(2)

    9.主从复制 9.1搭建集群原因 9.1.1 性能 Redis 本身的 QPS 已经很高了,但是如果在一些并发量非常高的情况下,性能还是会受到影响.这个时候我们希望有更多的 Redis 服务来完成工作 ...

最新文章

  1. python医学科研中能做什么-一个博士生接受怎样的训练是完整、全面的科研训练?...
  2. Android利用广播实现ViewPager中item之间的数据通信
  3. 电子信息科学与技术计算机科学与技术会计学,我是本三学生 学的电子信息科学与技术专业 今年大三 从没接触过会计 想考注册会计师 可以么 ?...
  4. Java基础:HashMap的用法
  5. 面试官:Thread.sleep(0) 有什么用?
  6. boost::asio
  7. 谁说我们没有美国富---中国公款消费一年X掉9个航母战斗群
  8. python批量复制文件夹下所有文件_python定时复制远程文件夹中所有文件
  9. 实验一 SNMP网络管理架构的验证
  10. 开户银行的现代化支付行号CNAPS查询
  11. 鱼塘钓鱼题解(堆解决)
  12. Android调用系统设置界面
  13. linux 进程的vss rss uss,内存VSS,RSS,PSS,USS解读
  14. shell脚本之AWK-AWK的变量和AWK运算符
  15. PC端使用百度地图查询经纬度
  16. polished css,CSS in JS
  17. 大数据岗位薪资了解一下~
  18. 关于STM32H745xI双核芯片的SMPS和LDO配置,导致芯片无法复位,无法下载程序
  19. Rails的静态资源管理(三)—— 开发环境的Asset Pipelin
  20. 服务器共享文件夹限制容量,.如何限制共享文件夹大小.doc

热门文章

  1. qemu trace 使用
  2. 读书笔记-最全的 Swift 4 新特性解析
  3. EtherCAT I/O 马达控制机器人从站控制器设计
  4. 90% 的 CDP 成了摆设?3 家零售企业说可以这么玩
  5. 小米android工程师工资待遇,【小米工资】android系统工程师待遇-看准网
  6. 石器时代单机版 – 80后的初恋网游
  7. windows 10“查看设备和打印机“中,存在大量”多媒体设备”
  8. Antlr4之简单的sql查询解析demo
  9. H3CSE路由-路由引入
  10. 用于广告机,闸机设备,自助售货机,工控主机等的rk3288开发板