
在分布式系统中为了解决单点问题,通常会将同一份数据在多个Server上存储为多个副本。这样不仅可以提高系统的可用性,可以提高系统处理读请求的性能(将读请求负载均衡到不同的Server)。
Redis提供了复制功能,支持将同一份数据存储为多个副本,它是Redis集群高可用的基础。
建立复制
参与复制的Redis节点按照角色可以分为master和slave。每个slave只能有一个master,但一个master可以有多个slave。复制的数据流是单向的,只能由master复制到slave。
可以采用如下三种方式在两个Redis节点之间建立复制关系:
在配置文件中加入
slaveof {masterHost} {masterPort}在redis-server启动命令后增加参数
--slaveof {masterHost} {masterPort}Redis实例启动后,使用命令
slaveof {masterHost} {masterPort}
假设使用端口6379的Redis已经启动并作为master节点,下面我们启动一个使用端口6380的Redis实例,并使用命令让其成为6379的slave节点:

从上面的例子中可以看出,在6380成为6379的slave之后,6379会将自己的所有数据全都同步给6380。之后每当6379中有新的key加入时,6379会将新的key也同步到6380(如例子中的write_in_6379)。针对master 6379的任何修改都可以同步到slave 6380。
断开复制
slaveof命令不但可以在两个Redis节点间建立复制,还可以断开一个slave与master间的复制关系。
下面例子在6380节点上执行slaveof no one
命令来断开与6379之间的复制关系:

断开复制的主要流程包括:
断开master与slave之间的复制关系
将slave节点晋升为一个新的master节点
slave节点在断开与master节点之间的复制关系后并不会删除原有数据,只是无法再接受master节点的数据变化。
只读配置
由于复制只能从master到slave,如果直接修改slave节点上的数据会导致主从数据不一致。因此通常会将slave节点配置成只读模式,即slave只能接收来自master节点的数据变化,不能在slave节点上直接修改任何数据。
通过replica-read-only
参数可以配置slave是否启动只读模式,其默认参数是yes,即slave节点默认开启只读模式。

传输延迟
在生产环境中,master和slave一般会部署在不同的服务器上,同步数据的网络延迟就成为需要考虑的问题。
repl-disable-tcp-nodelay
参数用于控制是否关闭TCP_NODELAY,其默认值是no,即开启TCP_NODELAY。

TCP_NODELAY功能对传输数据的影响说明如下:
开启TCP_NODELAY时,master节点产生的数据无论多少都会及时发送给slave节点,这样master、slave之间的延迟就会变小,但会增加网络带宽资源的消耗。适用于主从之间的网络环境良好的场景,例如master、slave节点部署在同机架或同机房。
关闭TCP_NODELAY时,master节点上的数据发生变化并不会马上发送给slave节点,master节点会合并多个较小的TCP数据包后再一次性发送给slave节点。其默认的发送时间间隔取决于Linux内核,一般为40毫秒。这种配置适用于主从网络环境复杂或带宽资源紧张的场景,例如master、slave部署在不同的机房。
心跳
master、slave建立复制关系后,它们之间通过心跳维护着长连接。
master节点默认每隔10秒向slave节点发送ping命令,以此来判断slave节点的存活性和连接状态。
repl-ping-replica-period
参数可以控制master节点向slave节点发送ping命令的频率。

异步复制
当数据发生变化时,master将数据同步给slave的动作是异步发生的。
当master节点收到用户修改数据的请求时,在master本身处理完用户的写命令后就直接将处理结果返回给客户端,并不等待slave节点的复制完成。
由于主从复制过程是异步的,就会造成slave节点的数据相对于master节点存在延迟。延迟的数据量具体有多少,我们可以在master、slave两个节点上执行info replication
命令查看相关指标获得。
在6380节点上执行info replication
命令的结果如下图所示:

info replication
命令会显示很多信息,其中跟复制进度相关的是slave_repl_offset
和master_repl_offset
两个偏移量信息。前者表示slave节点的复制偏移量,后者表示master节点的复制偏移量,两者的差值就是slave节点当前复制的延迟量。
slave节点每秒会向master上报自己的复制偏移量,因此master节点上也会保存从节点的复制偏移量。在6379上执行info replication
命令如下所示:

通过判断master节点上这两个offset的值,也可以判断主从数据的复制进度。
Redis的复制速度取决于主从之间的网络环境、命令处理速度等。正常情况下,主从之间的数据延迟在1秒以内。
—————END—————




