和MySQL主从复制的缘由同样,Redis虽然读取写入的速度都特别快,可是也会产生读压力特别大的状况。为了分担读压力,Redis支持主从复制,Redis的主从结构能够采用一主多从或者级联结构,Redis主从复制能够根据是不是全量分为全量同步和增量同步。node
1、概念redis
主从复制,是指将一台Redis服务器的数据,复制到其余的Redis服务器。前者称为主节点(master),后者称为从节点(slave);数据的复制是单向的,只能由主节点到从节点。默认状况下,每台Redis服务器都是主节点;且一个主节点能够有多个从节点(或没有从节点),但一个从节点只能有一个主节点。服务器
2、做用网络
1.主从复制实现了数据的热备份,是持久化以外的一种数据冗余方式。并发
2.当主节点出现问题时,能够由从节点提供服务,实现快速的故障恢复;其实是一种服务的冗余。负载均衡
3.在主从复制的基础上,配合读写分离,能够由主节点提供写服务,由从节点提供读服务(即写Redis数据时应用链接主节点,读Redis数据时应用链接从节点),分担服务器负载;尤为是在写少读多的场景下,经过多个从节点分担读负载,能够大大提升Redis服务器的并发量。异步
4.高可用基石:除了上述做用之外,主从复制仍是哨兵和集群可以实施的基础,所以说主从复制是Redis高可用的基础。socket
3、创建复制tcp
须要注意,主从复制的开启,彻底是在从节点发起的;不须要咱们在主节点作任何事情。函数
从节点开启主从复制,有3种方式:
(1)配置文件
在从服务器的配置文件中加入:slaveof masterip masterport
(2)启动命令
redis-server启动命令后加入 --slaveof masterip masterport
(3)客户端命令
Redis服务器启动后,直接经过客户端执行命令:slaveof masterip masterport,则该Redis实例成为从节点。
上述3种方式是等效的,下面以客户端命令的方式为例,看一下当执行了slaveof后,Redis主节点和从节点的变化。
经过slaveof masterip masterport命令创建主从复制关系之后,能够经过slaveof no one断开。须要注意的是,从节点断开复制后,不会删除已有的数据,只是再也不接受主节点新的数据变化。
4、实现步骤
创建链接
1、保存主节点信息
从节点服务器内部维护了两个字段,即masterhost和masterport字段,用于存储主节点的ip和port信息。
须要注意的是,slaveof是异步命令,从节点完成主节点ip和port的保存后,向发送slaveof命令的客户端直接返回OK,实际的复制操做在这以后才开始进行。
2、创建socket链接
从节点每秒1次调用复制定时函数replicationCron(),若是发现了有主节点能够链接,便会根据主节点的ip和port,建立socket链接。若是链接成功,则:
从节点:为该socket创建一个专门处理复制工做的文件事件处理器,负责后续的复制工做,如接收RDB文件、接收命令传播等。
主节点:接收到从节点的socket链接后(即accept以后),为该socket建立相应的客户端状态,并将从节点看作是链接到主节点的一个客户端,后面的步骤会以从节点向主节点发送命令请求的形式来进行。
3、发送ping命令
从节点成为主节点的客户端以后,发送ping命令进行首次请求,目的是:检查socket链接是否可用,以及主节点当前是否可以处理请求。
从节点发送ping命令后,可能出现3种状况:
(1)返回pong:说明socket链接正常,且主节点当前能够处理请求,复制过程继续。
(2)超时:必定时间后从节点仍未收到主节点的回复,说明socket链接不可用,则从节点断开socket链接,并重连。
(3)返回pong之外的结果:若是主节点返回其余结果,如正在处理超时运行的脚本,说明主节点当前没法处理命令,则从节点断开socket链接,并重连。
4、身份验证
若是从节点中设置了masterauth选项,则从节点须要向主节点进行身份验证;没有设置该选项,则不须要验证。从节点进行身份验证是经过向主节点发送auth命令进行的,auth命令的参数即为配置文件中的masterauth的值。
若是主节点设置密码的状态,与从节点masterauth的状态一致(一致是指都存在,且密码相同,或者都不存在),则身份验证经过,复制过程继续;若是不一致,则从节点断开socket链接,并重连。
5、发送从节点端口信息
身份验证以后,从节点会向主节点发送其监听的端口号(前述例子中为6380),主节点将该信息保存到该从节点对应的客户端的slave_listening_port字段中;该端口信息除了在主节点中执行info Replication时显示之外,没有其余做用。
数据同步
主从节点之间的链接创建之后,即可以开始进行数据同步,该阶段能够理解为从节点数据的初始化。具体执行的方式是:从节点向主节点发送psync命令(Redis2.8之前是sync命令),开始同步。
数据同步阶段是主从复制最核心的阶段,根据主从节点当前状态的不一样,能够分为全量复制和部分复制,下面会有一章专门讲解这两种复制方式以及psync命令的执行过程,这里再也不详述。
须要注意的是,在数据同步阶段以前,从节点是主节点的客户端,主节点不是从节点的客户端;而到了这一阶段及之后,主从节点互为客户端。缘由在于:在此以前,主节点只须要响应从节点的请求便可,不须要主动发请求,而在数据同步阶段和后面的命令传播阶段,主节点须要主动向从节点发送请求(如推送缓冲区中的写命令),才能完成复制。
命令传播
数据同步阶段完成后,主从节点进入命令传播阶段;在这个阶段主节点将本身执行的写命令发送给从节点,从节点接收命令并执行,从而保证主从节点数据的一致性。
在命令传播阶段,除了发送写命令,主从节点还维持着心跳机制:PING和REPLCONF ACK。因为心跳机制的原理涉及部分复制,所以将在介绍了部分复制的相关内容后单独介绍该心跳机制。
延迟与不一致
须要注意的是,命令传播是异步的过程,即主节点发送写命令后并不会等待从节点的回复;所以实际上主从节点之间很难保持实时的一致性,延迟在所不免。数据不一致的程度,与主从节点之间的网络情况、主节点写命令的执行频率、以及主节点中的repl-disable-tcp-nodelay配置等有关。
repl-disable-tcp-nodelay no:该配置做用于命令传播阶段,控制主节点是否禁止与从节点的TCP_NODELAY;默认no,即不由止TCP_NODELAY。当设置为yes时,TCP会对包进行合并从而减小带宽,可是发送的频率会下降,从节点数据延迟增长,一致性变差;具体发送频率与Linux内核的配置有关,默认配置为40ms。当设置为no时,TCP会立马将主节点的数据发送给从节点,带宽增长但延迟变小。
通常来讲,只有当应用对Redis数据不一致的容忍度较高,且主从节点之间网络情况很差时,才会设置为yes;多数状况使用默认值no。
5、缺陷
主从复制虽然解决或缓解了数据冗余、故障恢复、读负载均衡等问题,但其缺陷仍很明显,如故障恢复没法自动化;写操做没法负载均衡;存储能力受到单机的限制。每次slaveof断开后,(不管是主动断开,仍是网络故障),再链接master;都要master所有dump出来rdb,再aof,即同步的过程都要从新执行1遍。因此不要多台slaveof同时启动,不然master可能IO剧增。