Redis具备高可靠性,体如今两方面:数据库
今天咱们学习的就是经过主从复制实现副本冗余,从而实现Redis的高可靠性。网络
Redis提供主从库模式,保证数据副本的一致,主从库之间采用的是读写分离的方式。socket
若是容许全部节点可以处理读写请求,就须要解决加锁、实例间协商、数据同步等操做,会带来巨额的开销。性能
所以采用主从库模式时,要配置主库只写,从库只读。学习
当设置了主从库模式,此时从库是空的,如何进行主从库的第一次同步呢?3d
Redis采用全量复制来进行第一次同步,具体有三个步骤,以下图所示:日志
第一步,主从库创建链接,协商同步。code
第二步:主库同步数据给从库。blog
从库收到数据后,在本地完成数据加载。这过程依赖于RDB快照。get
第三步,主库发送新写命令给从库
主库在数据同步过程当中,会记录全部写操做,避免丢失同步过程接收的新的写命令。
关于replication buffer的更多内容,下面再介绍。
若是有多个从库,每一个从库都要跟主库进行全量同步,这样主库的压力会很大。
Redis提供“主-从-从”模式将主库生成RDB和传输RDB的压力,以级联的方式分散到从库上。
简单来讲,构建父子从库结构,子从库的数据同步从父从库获取。以下图所示:
在从库上执行命令:replicaof 所选从库的IP 6379
,就能够设置从库的父从库了。
至此,主从库完成了第一次同步,那后续如何保持同步呢?
当主从库完成同步后,会维护一个网络链接,主库会经过这个链接将后续的命令同步给从库。
可是这里有潜在的风险点:若是网络断连或者出现阻塞了,那怎么办呢?
在Redis 2.8以前,网络断了后要从新进行全量复制。但在Redis 2.8以后,Redis提供了增量复制的方式。
当创建了主从结构后,主库会把写命令写入repl_backlog_buffer缓冲区里,当网络断开并从新链接后,从库会发送同步命令,而后主库再把未同步的命令发送给从库,从库执行这些命令就恢复数据一致了。具体流程以下图所示:
repl_backlog_buffer是一个环形缓冲区,以下图所示:
因为其环形结构,当由于网络问题影响从库读取命令的速度,会出现写满后继续写入命令时,会覆盖掉从库还没读的内容,从而形成数据不一致,须要从新全量复制。
所以要根据状况来设置repl_backlog_buffer的大小,经过配置repl_backlog_size来调整缓冲区大小。配置公式为:缓冲空间大小 = 主库写入命令速度 * 操做大小 - 主从库间网络传输命令速度 * 操做大小。而repl_backlog_size= 缓冲空间 * 2。
例如主库写操做2000/秒,每一个操做大小2KB,网络传输1000个操做/秒,那缓冲空间大小=2000*2 - 1000*2=2MB,那repl_backlog_size就设置为4MB。
为何主库间的数据复制同步不使用AOF?
有三方面缘由:
关于replication buffer
每一个与Redis通讯的客户端(从库也算client),都会分配一个buffer,全部数据交互都是经过这个buffer进行的。
Redis先把数据写到这个buffer中,而后再把buffer中的数据发到client的socket中,经过网络发送出去,完成数据交互。
而主从同步的这个buffer,是用于保证主从数据一致的,因此才叫它replication buffer。
能够经过配置项client-output-buffer-limit
来配置这个buffer的大小。当保存到buffer里的内容超过限制,主库会强制断开这个client的链接。这样会有潜在风险。
若是从库处理主库传输的命令很是慢,就会把这个buffer撑满,而后主库会断开链接。中断后,从库再次发起复制请求,可能会致使恶性循环,引起复制风暴。