相信不少小伙伴都已经配置过主从复制,可是对于redis主从复制的工做流程和常见问题不少都没有深刻的了解。咔咔此次用时俩天时间给你们整理一份redis主从复制的所有知识点。redis
本文实现所需环境 centos7.0 redis4.0数据库
@TOCcentos
主从复制就是如今有俩台redis服务器,把一台redis的数据同步到另外一台redis数据库上。前者称之为主节点(master),后者为从节点(slave)。数据是只能master往slave同步单向。服务器
可是在实际过程当中是不可能只有俩台redis服务器来作主从复制的,这也就意味这每台redis服务器都有可能会称为主节点(master)网络
下图案例中,咱们的slave3既是master的从节点,也是slave的主节点。并发
先知道这么个概念,更多详解继续查看下文。 负载均衡
假设咱们如今就一台redis服务器,也就是单机状态。socket
在这种状况下会出现的第一个问题就是服务器宕机,直接致使数据丢失。若是项目是跟¥占关系的,那形成的后果就可想而知。函数
第二个状况就是内存问题了,当只有一台服务器时内存确定会到达峰值的,不可能对一台服务器进行无限升级的。 学习
这会应该会有不少疑问,master跟slave怎么链接呢? 如何同步数据呢? 假如master服务器宕机了呢?别着急,一点一点解决你的问题。
在上边咱们说了为何使用redis的主从复制,那么主从复制的做用就是针对为何使用它来说了。
说了这么多,咱们先简单的配置一个主从复制案例,而后在谈实现的原理。
redis存储路径为:usr/local/redis
日志跟配置文件存储在:usr/local/redis/data
首先咱们先配置俩个配置文件,分别为redis6379.conf 和 redis6380.conf
redis-server redis6380.conf
,而后使用
redis-cli -p 6380
链接,由于redis的默认端口就是6379因此咱们启动另一台redis服务器直接使用
redis-server redis6379.conf
而后直接使用
redis-cli
直接链接就能够。
咱们先得有一个概念,就是在配置主从复制时,全部的操做都是在从节点来操做,也就是slave。
那么咱们在从节点执行一个命令为 slaveof 127.0.0.1 6379
,执行完就表明咱们链接上了。
set kaka 123 和 set master 127.0.0.1
,而后在slave6380端口是能够成功获取到的,也就说明咱们的主从复制就已经配置完成了。可是在实现生产环境可不是就这样完事了,后边会在进一步对主从复制进行优化,直到实现高可用。
在使用配置文件启动主从复制以前呢!先须要把以前使用客户端命令行链接的断开,在从主机执行slaveof no one
便可断开主从复制。
info
查看
这张图是使用从节点使用客户端命令行链接主节点后,在主节点的客户端输入info
打印的信息,能够看到有一个slave0的一个信息。
slaveof no one
后,在主节点打印的
info
,说明从节点已经跟主节点断开链接了。
redis-server redis6380.conf
当在从节点从新启动后就能够在主节点直接查看到从节点的链接信息。
这种方式配置也是很简单,在启动redis服务器时直接就启动主从复制,执行命令:redis-server --slaveof host port
便可。
这个是主节点的日志信息
主从复制完整的工做流程分为如下三个阶段。每一段都有本身的内部工做流程,那么咱们会对这三个过程进行谈论。
在创建链接的过程当中,从节点会保存master的地址和端口、主节点master保存从节点slave的端口。
当从节点第一次链接主节点时,先会执行一次全量复制此次的全量复制是没法避免的。
全量复制执行完成后,主节点就会发送复制积压缓冲区的数据,而后从节点就会执行bgrewriteaof恢复数据,这也就是部分复制。
在这个阶段提到了三个新点,全量复制、部分复制、复制缓冲积压区。会在下文的常见问题里详细说明这几个点。
当master数据库被修改后,主从服务器的数据不一致后,此时就会让主从数据同步到一致,这个过程称之为命令传播。
master会将接收到的数据变动命令发送给slave,slave接收命令后执行命令,让主从数据达到一致。
命令传播阶段的部分复制
在命令传播阶段出现断网的状况,或者网络抖动时会致使链接断开(connection lost)
这个时候主节点master仍是会继续往replbackbuffer(复制缓冲积压区)写数据
从节点会继续尝试链接主机(connect to master)
当从节点把本身的runid和复制偏移量发送给主节点,而且执行pysnc命令同步
若是master判断偏移量是在复制缓冲区范围内,就会返回continue命令。而且发送复制缓冲区的数据给从节点。
从节点接收数据执行bgrewriteaof,恢复数据
psync ? 1 psync runid offset
找对应的runid
索取数据。可是这里能够考虑一下,当从节点第一次链接的时候根本就不知道主节点的runid 和 offset
。因此第一次发送的指令是psync ? 1
意思就是主节点的数据我全要。psync runid offset
2
继续执行全量复制。这里的runid不匹配只有的多是从节点重启了这个问题后边会解决,offset(偏移量)不匹配就是复制积压缓冲区溢出了。 若是runid或offset校验经过,从节点的offset和主节点的offset相同时则忽略。 若是runid或offset检验经过,从节点的offset与offset不相同,则会发送 +CONTINUE offset(这个offset为主节点的),经过socket发送复制缓冲区中从节点offset到主节点offset的数据。1-4是全量复制 5-8是部分复制
在主节点的第3步下面 主节点在主从复制的期间是一直在接收客户端的数据,主节点的offset是一直变化的。只有有变化就会给每一个slave进行发送,这个发送的过程称之为心跳机制
在命令传播阶段是,主节点与从节点之间一直都须要进行信息互换,使用心跳机制进行维护,实现主节点和从节点链接保持在线。
master心跳
slave心跳任务
心跳阶段的注意事项 主节点为保障数据稳定性,当从节点挂掉的数量或者延迟太高时。将会拒绝全部信息同步。
这里有俩个参数能够进行配置调整:
min-slaves-to-write 2
min-slaves-max-lag 8
这俩个参数表示从节点的数量就剩余2个,或者从节点的延迟大于8秒时,主节点就会强制关闭maste功能,中止数据同步。
那么主节点是如何知道从节点挂掉的数量和延迟时间呢! 在心跳机制里边slave 会每隔一秒发送perlconf ack 这个指令,这个指令可携带偏移量,也能够携带从节点的延迟时间和从节点的数量。
咱们先看一下这个run id是什么,执行info命令便可看到。在上文中咱们查看启动日志信息也能够看到。
在主从复制初次启动时,master会把本身的runid发送给slave,slave会保存master的这个id,咱们可使用info命令查看
当断线重连时,slave把这个id发送给master,若是slave保存的runid与master如今的runid相同,master会尝试使用部分复制(这块可否复制成功还有一个因素就是偏移量)。若是slave保存的runid与master如今的runid不一样,则会直接进行全量复制。
复制缓冲积压区是一个先进先出的队列,用户存储master收集数据的命令记录。复制缓冲区的默认存储空间是1M。
能够在配置文件修改repl-backlog-size 1mb
来控制缓冲区大小,这个比例能够根据本身的服务器内存来修改,咔咔这边是预留出了30%左右。
复制缓冲区到底存储的是什么?
当执行一个命令为set name kaka
时,咱们能够查看持久化文件查看
在命令传播阶段,主节点会把收集的数据存储到复制缓冲区中,而后在发送给从节点。就是这里出现了问题,当主节点数据量在一瞬间特别大的时候,超出了复制缓冲区的内存,就会有一部分数据会被挤出去,从而致使主节点和从节点的数据不一致。从而进行全量复制。若是这个缓冲区大小设置不合理那么很大可能会形成死循环,从节点就会一直全量复制,清空数据,全量复制。
用于同步信息,对比主节点和从节点的差别,当slave断联时恢复数据使用。
这个值也就是来本身于复制缓冲积压区里边的那个偏移量。
当主节点重启后,runid的值将发生变化,会致使全部的从节点进行全量复制。
这个问题咱们无需考虑,知道系统是怎么优化的便可。
在创建完主从复制后主节点会建立master-replid变量,这个生成的策略跟runid同样,长度是41位,runid长度是40位,而后发送给从节点。
在主节点执行shutdown save命令时,进行了一次RDB持久化会把runid 和 offset保存到RDB文件中。可使用命令redis-check-rdb查看该信息。
因为网络环境不佳,从节点网络中断。复制积压缓冲区内存太小致使数据溢出,伴随着从节点偏移量越界,致使全量复制。有可能会致使反复的全量复制。
解决方案:修改复制积压缓冲区的大小:repl-backlog-size
设置建议:测试主节点链接从节点的时间,获取主节点每秒平均产生的命令总量write_size_per_second
复制缓冲区空间设置 = 2 * 主从链接时间 * 主节点每秒产生的数据总量
因为主节点的cpu占用太高,或者从节点频繁链接。出现这种状况形成的结果就是主节点各类资源被严重占用,其中包括但不限于缓冲区,宽带,链接等。
为何会出现主节点资源被严重占用?
在心跳机制中,从节点每秒会发送一个指令replconf ack指令到主节点。 从节点执行了慢查询,占用大量的cpu 主节点每秒调用复制定时函数replicationCron,而后从节点长时间没有相应。
解决方案:
设置从节点超时释放
设置参数:repl-timeout
这个参数默认为60秒。超过60秒,释放slave。
因为网络因素,多个从节点的数据会不一致。这个因素是没有办法避免的。
关于这个问题给出俩个解决方案:
第一个数据须要高度一致配置一台redis服务器,读写都用一台服务器,这种方式仅限于少许数据,而且数据需高度一直。
第二个监控主从节点的偏移量,若是从节点的延迟过大,暂时屏蔽客户端对该从节点的访问。设置参数为slave-serve-stale-data yes|no。 这个参数一但设置就只能响应info slaveof等少数命令。
这个问题直接在客户端维护一个可用节点列表,当从节点故障时,切换到其余节点进行工做,这个问题在后边集群会说到。
本文主要讲解了什么是主从复制、主从复制工做的三大阶段以及工做流程、部分复制的三大核心。命令传播阶段的心跳机制。最后说明了主从复制常见问题。
耗时俩天写的文章,这也是咔咔最近耗时最长的一篇文章,之后咔咔发的文章估计都是这样的,不会在把一问题单独出多篇文章来说解,会一篇文章所有说完。不完善知识点或者错误知识点,随着咔咔的知识点增多在回来改善。文章主要是为了咔咔回顾方便。有什么问题评论区见。
咔咔但愿是你们共同交流学习,不对的能够指出来,不喜勿喷。