Redis的主从复制是如何作的?复制过程当中也会产生各类问题

在Redis客户端经过info replication能够查看与复制相关的状态,对于了解主从节点的当前状态,以及解决出现的问题都会有帮助。node

主从复制,是指将一台Redis服务器的数据,复制到其余的Redis服务器。前者称为主节点(master/leader),后者称为从节点(slave/follower);数据的复制是单向的,只能由主节点到从节点。redis

默认状况下,每台Redis服务器都是主节点;且一个主节点能够有多个从节点(或没有从节点),但一个从节点只能有一个主节点。数据库

主从复制的做用主要包括:安全

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

如何使用主从复制

开启主从复制

主从复制的开启,彻底是在从节点发起的;不须要咱们在主节点作任何事情。服务器

从节点开启主从复制,有3种方式:网络

  • 配置文件:在从服务器的配置文件中加入:slaveof
  • 启动命令:redis-server启动命令后加入 --slaveof
  • 客户端命令:Redis服务器启动后,直接经过客户端执行命令:slaveof,则该Redis实例成为从节点。

断开主从复制

经过slaveof命令创建主从复制关系之后,能够经过slaveof no one断开。并发

从节点断开复制后,不会删除已有的数据,只是再也不接受主节点新的数据变化。负载均衡

主从复制的实现原理

主从复制过程大致能够分为3个阶段:链接创建阶段(即准备阶段)数据同步阶段命令传播阶段less

链接创建阶段

step1:保存主节点信息

从节点服务器内部维护了两个字段,即masterhost和masterport字段,用于存储主节点的ip和port信息。异步

slaveof是异步命令,从节点完成主节点ip和port的保存后,向发送slaveof命令的客户端直接返回OK**,实际的复制操做在这以后才开始进行。**

step2:创建socket链接

从节点每秒1次调用复制定时函数replicationCron(),若是发现了有主节点能够链接,便会根据主节点的ip和port,建立socket链接。

若是链接成功:

从节点:为该socket创建一个专门处理复制工做的文件事件处理器,负责后续的复制工做,如接收RDB文件、接收命令传播等。

主节点:接收到从节点的socket链接后(即accept以后),为该socket建立相应的客户端状态,并将从节点看作是链接到主节点的一个客户端,后面的步骤会以从节点向主节点发送命令请求的形式来进行。

step3:发送ping命令

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

从节点发送ping命令后,可能出现3种状况:

(1)返回pong:说明socket链接正常,且主节点当前能够处理请求,复制过程继续。

(2)超时:必定时间后从节点仍未收到主节点的回复,说明socket链接不可用,则从节点断开socket链接,并重连。

(3)返回pong之外的结果:若是主节点返回其余结果,如正在处理超时运行的脚本,说明主节点当前没法处理命令,则从节点断开socket链接,并重连。

step4:身份验证

若是从节点中设置了masterauth选项,则从节点须要向主节点进行身份验证;没有设置该选项,则不须要验证。

从节点进行身份验证是经过向主节点发送auth命令进行的,auth命令的参数即为配置文件中的masterauth的值。

若是主节点设置密码的状态,与从节点masterauth的状态一致(一致是指都存在,且密码相同,或者都不存在),则身份验证经过,复制过程继续;若是不一致,则从节点断开socket链接,并重连。

step5:发送从节点端口信息

身份验证以后,从节点会向主节点发送其监听的端口号,主节点将该信息保存到该从节点对应的客户端的slave_listening_port字段中;该端口信息除了在主节点中执行info Replication时显示之外,没有其余做用。

数据同步阶段

主从节点之间的链接创建之后,即可以开始进行数据同步,该阶段能够理解为从节点数据的初始化。

具体执行的方式是:从节点向主节点发送psync命令,开始同步。

数据同步阶段是主从复制最核心的阶段,根据主从节点当前状态的不一样,能够分为全量复制和部分复制

在数据同步阶段以前,从节点是主节点的客户端,主节点不是从节点的客户端;而到了这一阶段及之后,主从节点互为客户端。缘由在于:在此以前,主节点只须要响应从节点的请求便可,不须要主动发请求,而在数据同步阶段和后面的命令传播阶段,主节点须要主动向从节点发送请求(如推送缓冲区中的写命令),才能完成复制。

命令传播阶段

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

在命令传播阶段,除了发送写命令,主从节点还维持着心跳机制:PING和REPLCONF ACK。

PS:

延迟与不一致: 命令传播是异步的过程,即主节点发送写命令后并不会等待从节点的回复;所以实际上主从节点之间很难保持实时的一致性,延迟在所不免。数据不一致的程度,与主从节点之间的网络情况、主节点写命令的执行频率、以及主节点中的repl-disable-tcp-nodelay配置等有关。

repl-disable-tcp-nodelay no:该配置做用于命令传播阶段,控制主节点是否禁止与从节点的TCP_NODELAY;默认no,即不由止TCP_NODELAY。当设置为yes时,TCP会对包进行合并从而减小带宽,可是发送的频率会下降,从节点数据延迟增长,一致性变差;具体发送频率与Linux内核的配置有关,默认配置为40ms。当设置为no时,TCP会立马将主节点的数据发送给从节点,带宽增长但延迟变小。通常来讲,只有当应用对Redis数据不一致的容忍度较高,且主从节点之间网络情况很差时,才会设置为yes;多数状况使用默认值no。

【数据同步阶段】全量复制和部分复制

在Redis2.8之前,从节点向主节点发送sync命令请求同步数据,此时的同步方式是全量复制;

在Redis2.8之后,从节点能够发送psync命令请求同步数据,此时根据主从节点当前状态的不一样,同步方式多是全量复制或部分复制。

  1. 全量复制:用于初次复制或其余没法进行部分复制的状况,将主节点中的全部数据都发送给从节点,是一个很是重要的操做。
  2. 部分复制:用于网络中断等状况后的复制,只将中断期间主节点执行的写命令发送给从节点,与全量复制相比更加高效。须要注意的是,若是网络中断时间过长,致使主节点没有可以完整地保存中断期间执行的写命令,则没法进行部分复制,仍使用全量复制。

全量复制

Redis经过psync命令进行全量复制的过程以下:

(1)从节点判断没法进行部分复制,向主节点发送全量复制的请求;或从节点发送部分复制的请求,但主节点判断没法进行全量复制;

(2)主节点收到全量复制的命令后,执行bgsave,在后台生成RDB文件,并使用一个缓冲区(称为复制缓冲区)记录从如今开始执行的全部写命令

(3)主节点的bgsave执行完成后,将RDB文件发送给从节点;从节点首先清除本身的旧数据,而后载入接收的RDB文件,将数据库状态更新至主节点执行bgsave时的数据库状态

(4)主节点将前述复制缓冲区中的全部写命令发送给从节点,从节点执行这些写命令,将数据库状态更新至主节点的最新状态

(5)若是从节点开启了AOF,则会触发bgrewriteaof的执行,从而保证AOF文件更新至主节点的最新状态

经过全量复制的过程能够看出,全量复制是很是重要的操做:

(1)主节点经过bgsave命令fork的进程进行RDB持久化,该过程是很是消耗CPU、内存(页表复制)、硬盘IO的;

(2)主节点经过网络将RDB文件发送给从节点,对主从节点的带宽都会带来很大的消耗

(3)从节点清空老数据、载入新RDB文件的过程是阻塞的,没法响应客户端的命令;若是从节点执行bgrewriteaof,也会带来额外的消耗

部分复制

因为全量复制在主节点数据量较大时效率过低,所以Redis2.8开始提供部分复制,用于处理网络中断时的数据同步。

部分复制的实现,依赖于三个重要的概念:复制偏移量,复制积压缓冲区,服务器运行ID

复制偏移量

主节点和从节点分别维护一个复制偏移量(offset),表明的是主节点向从节点传递的字节数;主节点每次向从节点传播N个字节数据时,主节点的offset增长N;从节点每次收到主节点传来的N个字节数据时,从节点的offset增长N。

offset用于判断主从节点的数据库状态是否一致:若是两者offset相同,则一致;若是offset不一样,则不一致,此时能够根据两个offset找出从节点缺乏的那部分数据。例如,若是主节点的offset是1000,而从节点的offset是500,那么部分复制就须要将offset为501-1000的数据传递给从节点。而offset为501-1000的数据存储的位置,就是下面要介绍的复制积压缓冲区。

复制积压缓冲区

复制积压缓冲区是由主节点维护的、固定长度的、先进先出(FIFO)队列,默认大小1MB;当主节点开始有从节点时建立,其做用是备份主节点最近发送给从节点的数据。注意,不管主节点有一个仍是多个从节点,都只须要一个复制积压缓冲区。

在命令传播阶段,主节点除了将写命令发送给从节点,还会发送一份给复制积压缓冲区,做为写命令的备份;除了存储写命令,复制积压缓冲区中还存储了其中的每一个字节对应的复制偏移量(offset)。因为复制积压缓冲区定长且是先进先出,因此它保存的是主节点最近执行的写命令;时间较早的写命令会被挤出缓冲区。

因为该缓冲区长度固定且有限,所以能够备份的写命令也有限,当主从节点offset的差距过大超过缓冲区长度时,将没法执行部分复制,只能执行全量复制。反过来讲,为了提升网络中断时部分复制执行的几率,能够根据须要增大复制积压缓冲区的大小(经过配置repl-backlog-size);例如若是网络中断的平均时间是60s,而主节点平均每秒产生的写命令(特定协议格式)所占的字节数为100KB,则复制积压缓冲区的平均需求为6MB,保险起见,能够设置为12MB,来保证绝大多数断线状况均可以使用部分复制。

从节点将offset发送给主节点后,主节点根据offset和缓冲区大小决定可否执行部分复制:

  • 若是offset偏移量以后的数据,仍然都在复制积压缓冲区里,则执行部分复制;
  • 若是offset偏移量以后的数据已不在复制积压缓冲区中(数据已被挤出),则执行全量复制。

服务器运行ID(runid)

每一个Redis节点(不管主从),在启动时都会自动生成一个随机ID(每次启动都不同),由40个随机的十六进制字符组成;

runid用来惟一识别一个Redis节点。经过info Server命令,能够查看节点的runid。

主从节点初次复制时,主节点将本身的runid发送给从节点,从节点将这个runid保存起来;当断线重连时,从节点会将这个runid发送给主节点;主节点根据runid判断可否进行部分复制:

  • 若是从节点保存的runid与主节点如今的runid相同,说明主从节点以前同步过,主节点会继续尝试使用部分复制(到底能不能部分复制还要看offset和复制积压缓冲区的状况);
  • 若是从节点保存的runid与主节点如今的runid不一样,说明从节点在断线前同步的Redis节点并非当前的主节点,只能进行全量复制。

psync命令的执行

image

(1)首先从节点根据当前状态,决定如何调用psync命令:

  • 若是从节点以前未执行过slaveof或最近执行了slaveof no one,则从节点发送命令为psync ? -1,向主节点请求全量复制;
  • 若是从节点以前执行了slaveof,则发送命令为psync,其中runid为上次复制的主节点的runid,offset为上次复制截止时从节点保存的复制偏移量。

(2)主节点根据收到的psync命令,及当前服务器状态,决定执行全量复制仍是部分复制:

  • 若是主节点版本低于Redis2.8,则返回-ERR回复,此时从节点从新发送sync命令执行全量复制;
  • 若是主节点版本够新,且runid与从节点发送的runid相同,且从节点发送的offset以后的数据在复制积压缓冲区中都存在,则回复+CONTINUE,表示将进行部分复制,从节点等待主节点发送其缺乏的数据便可;
  • 若是主节点版本够新,可是runid与从节点发送的runid不一样,或从节点发送的offset以后的数据已不在复制积压缓冲区中(在队列中被挤出了),则回复+FULLRESYNC,表示要进行全量复制,其中runid表示主节点当前的runid,offset表示主节点当前的offset,从节点保存这两个值,以备使用。

【命令传播阶段】心跳机制

在命令传播阶段,除了发送写命令,主从节点还维持着心跳机制:PING和REPLCONF ACK。心跳机制对于主从复制的超时判断、数据安全等有做用。

主->从:PING

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

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

从->主: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的读负载均衡:由主节点提供写服务,由一个或多个从节点提供读服务(多个从节点既能够提升数据冗余程度,也能够最大化读负载能力);

在使用Redis读写分离时须要注意的问题。

延迟与不一致问题

因为主从复制的命令传播是异步的,延迟与数据的不一致不可避免。若是应用对数据不一致的接受程度程度较低,可能的优化措施包括:

优化主从节点之间的网络环境(如在同机房部署);

监控主从节点延迟(经过offset)判断,若是从节点延迟过大,通知应用再也不经过该从节点读取数据;

使用集群同时扩展写负载和读负载等。

在命令传播阶段之外的其余状况下,从节点的数据不一致可能更加严重,例如链接在数据同步阶段,或从节点失去与主节点的链接时等。从节点的slave-serve-stale-data参数便与此有关:它控制这种状况下从节点的表现;若是为yes(默认值),则从节点仍可以响应客户端的命令,若是为no,则从节点只能响应info、slaveof等少数命令。该参数的设置与应用对数据一致性的要求有关;若是对数据一致性要求很高,则应设置为no。

数据过时问题

在单机版Redis中,存在两种删除策略:

  • 惰性删除:服务器不会主动删除数据,只有当客户端查询某个数据时,服务器判断该数据是否过时,若是过时则删除。
  • 按期删除:服务器执行定时任务删除过时数据,可是考虑到内存和CPU的折中(删除会释放内存,可是频繁的删除操做对CPU不友好),该删除的频率和执行时间都受到了限制。

在主从复制场景下,为了主从节点的数据一致性,从节点不会主动删除数据,而是由主节点控制从节点中过时数据的删除。因为主节点的惰性删除和按期删除策略,都不能保证主节点及时对过时数据执行删除操做,所以,当客户端经过Redis从节点读取数据时,很容易读取到已通过期的数据。Redis 3.2中,从节点在读取数据时,增长了对数据是否过时的判断:若是该数据已过时,则不返回给客户端;将Redis升级到3.2能够解决数据过时问题。

故障切换问题

在没有使用哨兵的读写分离场景下,应用针对读和写分别链接不一样的Redis节点;当主节点或从节点出现问题而发生更改时,须要及时修改应用程序读写Redis数据的链接;链接的切换能够手动进行,或者本身写监控程序进行切换,但前者响应慢、容易出错,后者实现复杂,成本都不算低。

复制超时问题

主从节点复制超时是致使复制中断的最重要的缘由之一。

超时判断意义: 在复制链接创建过程当中及以后,主从节点都有机制判断链接是否超时,其意义在于:

(1)若是主节点判断链接超时,其会释放相应从节点的链接,从而释放各类资源,不然无效的从节点仍会占用主节点的各类资源(输出缓冲区、带宽、链接等);此外链接超时的判断可让主节点更准确的知道当前有效从节点的个数,有助于保证数据安全(配合前面讲到的min-slaves-to-write等参数)。

(2)若是从节点判断链接超时,则能够及时从新创建链接,避免与主节点数据长期的不一致。

判断机制

主从复制超时判断的核心,在于repl-timeout参数,该参数规定了超时时间的阈值(默认60s),对于主节点和从节点同时有效;主从节点触发超时的条件分别以下:

(1)主节点:每秒1次调用复制定时函数replicationCron(),在其中判断当前时间距离上次收到各个从节点REPLCONF ACK的时间,是否超过了repl-timeout值,若是超过了则释放相应从节点的链接。

(2)从节点:从节点对超时的判断一样是在复制定时函数中判断,基本逻辑是:

  • 若是当前处于链接创建阶段,且距离上次收到主节点的信息的时间已超过repl-timeout,则释放与主节点的链接;
  • 若是当前处于数据同步阶段,且收到主节点的RDB文件的时间超时,则中止数据同步,释放链接;
  • 若是当前处于命令传播阶段,且距离上次收到主节点的PING命令或数据的时间已超过repl-timeout值,则释放与主节点的链接。

复制阶段链接超时有关的一些实际问题:

(1)数据同步阶段:在主从节点进行全量复制bgsave时,主节点须要首先fork子进程将当前数据保存到RDB文件中,而后再将RDB文件经过网络传输到从节点。若是RDB文件过大,主节点在fork的进程+保存RDB文件时耗时过多,可能会致使从节点长时间收不到数据而触发超时;此时从节点会重连主节点,而后再次全量复制,再次超时,再次重连……这是个悲伤的循环。为了不这种状况的发生,除了注意Redis单机数据量不要过大,另外一方面就是适当增大repl-timeout值,具体的大小能够根据bgsave耗时来调整。

(2)命令传播阶段:在该阶段主节点会向从节点发送PING命令,频率由repl-ping-slave-period控制;该参数应明显小于repl-timeout值(后者至少是前者的几倍)。不然,若是两个参数相等或接近,网络抖动致使个别PING命令丢失,此时恰巧主节点也没有向从节点发送数据,则从节点很容易判断超时。

(3)慢查询致使的阻塞:若是主节点或从节点执行了一些慢查询(如keys *或者对大数据的hgetall等),致使服务器阻塞;阻塞期间没法响应复制链接中对方节点的请求,可能致使复制超时。

复制缓冲区溢出

在全量复制阶段,主节点会将执行的写命令放到复制缓冲区中,该缓冲区存放的数据包括了如下几个时间段内主节点执行的写命令:bgsave生成RDB文件、RDB文件由主节点发往从节点、从节点清空老数据并载入RDB文件中的数据。

当主节点数据量较大,或者主从节点之间网络延迟较大时,可能致使该缓冲区的大小超过了限制,此时主节点会断开与从节点之间的链接;这种状况可能引发全量复制->复制缓冲区溢出致使链接中断->重连->全量复制->复制缓冲区溢出致使链接中断……的循环。

复制缓冲区的大小由client-output-buffer-limit slave {hard limit} {soft limit} {soft seconds}配置,默认值为client-output-buffer-limit slave 256MB 64MB 60,其含义是:若是buffer大于256MB,或者连续60s大于64MB,则主节点会断开与该从节点的链接。该参数是能够经过config set命令动态配置的(即不重启Redis也能够生效)。

须要注意的是,复制缓冲区是客户端输出缓冲区的一种,主节点会为每个从节点分别分配复制缓冲区;而复制积压缓冲区则是一个主节点只有一个,不管它有多少个从节点。

各场景下复制的选择及优化技巧

第一次创建复制

此时全量复制不可避免,但仍有几点须要注意:

若是主节点的数据量较大,应该尽可能避开流量的高峰期,避免形成阻塞;

若是有多个从节点须要创建对主节点的复制,能够考虑将几个从节点错开,避免主节点带宽占用过大。

若是从节点过多,也能够调整主从复制的拓扑结构,由一主多从结构变为树状结构(中间的节点既是其主节点的从节点,也是其从节点的主节点);

但使用树状结构应该谨慎:虽然主节点的直接从节点减小,下降了主节点的负担,可是多层从节点的延迟增大,数据一致性变差;且结构复杂,维护至关困难。

主节点重启

主节点重启能够分为两种状况来讨论,一种是故障致使宕机,另外一种则是有计划的重启。

主节点宕机

主节点宕机重启后,runid会发生变化,所以不能进行部分复制,只能全量复制。

实际上在主节点宕机的状况下,应进行故障转移处理,将其中的一个从节点升级为主节点,其余从节点重新的主节点进行复制;且故障转移应尽可能的自动化。

安全重启:debug reload

在一些场景下,可能但愿对主节点进行重启,例如主节点内存碎片率太高,或者但愿调整一些只能在启动时调整的参数。若是使用普通的手段重启主节点,会使得runid发生变化,可能致使没必要要的全量复制。

为了解决这个问题,Redis提供了debug reload的重启方式:**重启后,主节点的runid和offset****都不受影响,**避免了全量复制。

但debug reload是一柄双刃剑:它会清空当前内存中的数据,从新从RDB文件中加载,这个过程会致使主节点的阻塞,所以也须要谨慎。

从节点重启

从节点宕机重启后,其保存的主节点的runid会丢失,所以即便再次执行slaveof,也没法进行部分复制。

网络中断

若是主从节点之间出现网络问题,形成短期内网络中断,能够分为多种状况讨论。

第一种状况:网络问题时间极为短暂,只形成了短暂的丢包,主从节点都没有断定超时(未触发repl-timeout);此时只须要经过REPLCONF ACK来补充丢失的数据便可。

第二种状况:网络问题时间很长,主从节点判断超时(触发了repl-timeout),且丢失的数据过多,超过了复制积压缓冲区所能存储的范围;此时主从节点没法进行部分复制,只能进行全量复制。为了尽量避免这种状况的发生,应该根据实际状况适当调整复制积压缓冲区的大小;此外及时发现并修复网络中断,也能够减小全量复制。

第三种状况:介于前述两种状况之间,主从节点判断超时,且丢失的数据仍然都在复制积压缓冲区中;此时主从节点能够进行部分复制。

复制相关的配置

slaveof:Redis启动时起做用;做用是创建复制关系,开启了该配置的Redis服务器在启动后成为从节点。该注释默认注释掉,即Redis服务器默认都是主节点。

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

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)多个从节点有较大的几率在短期内创建主从复制。

client-output-buffer-limit slave 256MB 64MB 60:与全量复制阶段主节点的缓冲区大小有关,见前面的介绍。

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

masterauth:与链接创建阶段的身份验证有关。

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

repl-backlog-size 1mb:复制积压缓冲区的大小。

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

min-slaves-to-write 3与min-slaves-max-lag 10:规定了主节点的最小从节点数目,及对应的最大延迟,见前面的介绍。

slave-serve-stale-data yes:与从节点数据陈旧时是否响应客户端命令有关,见前面的介绍。

slave-read-only yes:从节点是否只读;默认是只读的。因为从节点开启写操做容易致使主从节点的数据不一致,所以该配置尽可能不要修改。

单机内存大小限制

fork操做对Redis单机内存大小的限制。实际上在Redis的使用中,限制单机内存大小的因素很是之多,单机内存过大可能形成的影响:

(1)切主:当主节点宕机时,一种常见的容灾策略是将其中一个从节点提高为主节点,并将其余从节点挂载到新的主节点上,此时这些从节点只能进行全量复制;若是Redis单机内存达到10GB,一个从节点的同步时间在几分钟的级别;若是从节点较多,恢复的速度会更慢。若是系统的读负载很高,而这段时间从节点没法提供服务,会对系统形成很大的压力。

(2)从库扩容:若是访问量忽然增大,此时但愿增长从节点分担读负载,若是数据量过大,从节点同步太慢,难以及时应对访问量的暴增。

(3)缓冲区溢出:(1)和(2)都是从节点能够正常同步的情形(虽然慢),可是若是数据量过大,致使全量复制阶段主节点的复制缓冲区溢出,从而致使复制中断,则主从节点的数据同步会全量复制->复制缓冲区溢出致使复制中断->重连->全量复制->复制缓冲区溢出致使复制中断……的循环。

(4)超时:若是数据量过大,全量复制阶段主节点fork+保存RDB文件耗时过大,从节点长时间接收不到数据触发超时,主从节点的数据同步一样可能陷入全量复制->超时致使复制中断->重连->全量复制->超时致使复制中断……的循环。

此外,主节点单机内存除了绝对量不能太大,其占用主机内存的比例也不该过大:最好只使用50%-65%的内存,留下30%-45%的内存用于执行bgsave命令和建立复制缓冲区等。

相关文章
相关标签/搜索