Redis学习 主从复制(master-replica)架构介绍及实现

如下笔记以及实验皆出自于 中华石杉大佬的视频教学,我跟着作了实验,而且把课上的笔记整理了一下。html

redis的主从架构

在一个项目中使用redis必然是由于咱们想要作成高并发,redis是整个大型的缓存架构中,支撑高并发的很是重要的一个环节, 可是光redis是不够的。java

redis不能支撑高并发的瓶颈就是 单机 单机的redis不可能说QPS超过10万+,除非你的机器性能特别好,维护作的好, 并且你的总体的操做不能太复杂。node

因此读写分离通常来讲是用来支撑高并发,写的请求比较少,大量的请求都是读,那么redis的主从架构就是比较好的选择, 主从架构 -> 读写分离 -> 水平扩容支撑读高并发,主节点用来写,从节点用来读。git

PS:在我使用的5.0.4版本中slave这个术语已经被replica代替了,嗯~ 这个单词的意思确实有点很差听哈。反正官方已经改掉了,我也就全换掉了。github

master-replica

redis replication(主从复制)的核心机制

  • redis采用异步方式复制master节点数据到replica节点,不过redis 2.8开始,replica node会周期性地确认本身每次复制的数据量
  • 一个master node是能够配置多个replica node的
  • replica node也能够链接其余的replica node
  • replica node作复制的时候,是不会block master node的正常工做的
  • replica node在作复制的时候,也不会block对本身的查询操做,它会用旧的数据集来提供服务; 可是复制完成的时候,须要删除旧数据集,加载新数据集,这个时候就会暂停对外服务了
  • replica node主要用来进行横向扩容,作读写分离,扩容的replica node能够提升读的吞吐量

redis 主从复制的核心原理

当启动一个 replica node 的时候,它会发送一个 PSYNC 命令给 master node。redis

若是 replica node 使用 PSYNC 初次链接到 master node,那么会触发一次 full resynchronization 全量复制。此时 master 会启动一个后台线程, 开始生成一份 RDB 快照文件,同时还会将从客户端 client 新收到的全部写命令缓存在内存中。RDB 文件生成完毕后, master 会将这个 RDB 发送给 replica, replica 会先写入本地磁盘,而后再从本地磁盘加载到内存中,接着 master 会将内存中缓存的写命令发送到 replica,replica 也会同步这些数据。replica node 若是跟 master node 有网络故障,断开了链接,会自动重连,链接以后 master node 仅会复制给 replica 部分缺乏的数据。spring

流程图

什么是PSYNC命令呢

简单来讲PSYNC完成的使命就是判断从服务器是否须要全量复制仍是增量复制,毕竟每次由于一点点网路波动从新链接主节点,都要全量复制,很是的低效缓存

PSYNC格式:安全

PSYNC runid offsetbash

runid

每一个Redis服务器都会有一个代表本身身份的ID。在PSYNC中发送的这个ID是指以前链接的Master的ID,若是没保存这个ID, PSYNC的命令会使用”PSYNC ? -1” 这种形式发送给Master,表示须要全量复制。

offset(复制偏移量)

在主从复制的Master和replica双方都会各自维持一个offset。Master成功发送N个字节的命令后会将Master的offset加上N, replica在接收到N个字节命令后一样会将replica的offset增长N。Master和replica若是状态是一致的那么它的的offset也应该是一致的。

全量复制流程

  • 主节点master收到全量复制的命令后 执行 bgsave ,在本地生成一份 rdb 快照文件;并使用一个缓冲区(称为复制缓冲区)记录从如今开始执行的全部写命令 redis配置文件中有个参数:client-output-buffer-limit replica 256MB 64MB 60

若是在复制期间,内存缓冲区超过60秒一直消耗超过 64MB,或者一次性超过 256MB,那么中止复制,复制失败。后两个参数是配合使用的,假如:消耗超过64MB 一直持续了59秒,可是60秒的时候不超过64MB了,那么就保持链接继续复制。

  • master node 将 rdb 快照文件发送给 replica node,若是 rdb 复制时间超过 60秒(redis配置文件参数:repl-timeout),那么 replica node 就会认为复制失败, 能够适当调大这个参数(对于千兆网卡的机器,通常每秒传输 100MB,6G 文件,极可能超过 60s)

  • master node 在生成 rdb 时,会将全部新的写命令缓存在内存中,在 replica node 保存了 rdb 以后,再将新的写命令复制给 replica node; 从节点首先清除本身的旧数据,而后载入接收的RDB文件

  • 主节点将前述复制缓冲区中的全部写命令发送给从节点,从节点执行这些写命令,若是从节点开启了AOF,则会触发bgrewriteaof的执行,从而保证AOF文件更新至主节点的最新状态

部分复制流程(增量复制)

  • 若是全量复制过程当中,master-replica 网络链接断掉,那么 replica 从新链接 master 时,会触发增量复制。

  • master 直接从本身的 backlog 中获取部分丢失的数据,发送给 replica node,默认 backlog 就是 1MB。

  • master 就是根据 replica 发送的 psync 中的 offset 来从 backlog 中获取数据的。

例如,若是主节点的offset是1000,而从节点的offset是500,那么部分复制就须要将offset为501-1000的数据传递给从节点

完整的复制流程

replica node 启动时,会在本身本地保存 master node 的信息,包括 master node 的host和ip,可是复制流程没开始。

replica node 内部有个定时任务,每秒检查是否有新的 master node 要链接和复制,若是发现,就跟 master node 创建 socket 网络链接; 而后 replica node 发送 ping 命令给 master node。若是 master 设置了 requirepass(就是redis的登陆密码), 那么 replica node 必须发送 masterauth 的口令过去进行认证;master node 第一次执行全量复制,将全部数据发给 replica node; 而在后续,master node 持续将写命令,异步复制给 replica node。

redis-master-slave-replication-detail

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

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

  • 第三步:身份验证,若是从节点中设置了masterauth选项,则从节点须要向主节点进行身份验证;没有设置该选项,则不须要验证; 从节点进行身份验证是经过向主节点发送auth命令进行的,auth命令的参数即为配置文件中的masterauth的值;若是主节点设置密码的状态, 与从节点masterauth的状态一致(一致是指都存在,且密码相同,或者都不存在),则身份验证经过,复制过程继续;若是不一致,则从节点断开socket链接,并重连。

  • 第四步:数据同步,就是全量复制或者增量复制,并且在复制阶段继续有写命令会存在主节点内存中,后续会异步发送给replica node

replica node若是跟master node有网络故障,断开了链接,会自动重连。master若是发现有多个replica node都来从新链接, 仅仅会启动一个rdb save操做,用一份数据服务全部replica node。

主从复制的断点续传

从redis 2.8开始,就支持主从复制的断点续传,若是主从复制过程当中,网络链接断掉了,那么能够接着上次复制的地方,继续复制下去,而不是从头开始复制一份

master node会在内存中常见一个backlog,master和replica都会保存一个replica offset还有一个master id,offset就是保存在backlog中的。 若是master和replica网络链接断掉了,replica会让master从上次的replica offset开始继续复制

可是若是没有找到对应的offset,那么就会执行一次resynchronization(全量复制)

无磁盘化复制

master 在内存中直接建立 RDB,而后发送给 replica,不会在本身本地落地磁盘了。只须要在配置文件中开启 repl-diskless-sync yes 便可。

repl-diskless-sync yes

# 等待 5s 后再开始复制,由于要等更多 replica 从新链接过来
repl-diskless-sync-delay 5
复制代码

过时key处理

replica不会过时key,只会等待master过时key。若是master过时了一个key,或者经过LRU淘汰了一个key,那么会模拟一条del命令发送给replica。

heartbeat

主从节点互相都会发送 heartbeat 信息。

master 默认每隔 10秒 发送一次 heartbeat,replica node 每隔 1秒 发送一个 heartbeat。

master持久化对于主从架构的安全保障的意义

若是采用了主从架构,那么建议必须开启master node的持久化! 如何实现redis的持久化

并且不建议使用replica node做为master node的数据热备若是你关掉master的持久化,可能在master宕机重启的时候数据是空的,而后可能一通过复制,replica node数据也丢了

另外,master 的各类备份方案,也须要作。万一本地的全部文件丢失了,从备份中挑选一份 rdb 去恢复 master,这样才能确保启动的时候,是有数据的 即便采用了后续讲解的高可用机制,replica node能够自动接管master node,可是也可能sentinal尚未检测到master failure,master node就自动重启了, 仍是可能致使上面的全部replica node数据清空故障。

实现redis的主从复制架构(一主一从)

node hostname IP port
master node eshop-cache01 192.168.0.30 6379
replica node eshop-cache02 192.168.0.31 6379

在除了安装redis时配置的参数外,从节点还须要额外配置如下内容

配置主节点(eshop-cache01)配置文件

  • 在配置文件中修改 bind 127.0.0.1bind 192.168.0.30 本身自己的ip地址

或者配置成 bind 0.0.0.0 若是配置成自己ip地址,则须要在使用redis的客户端时,使用redis-cli -h 192.168.0.30进入客户端了

  • 配置认证密码 requirepass redis-pass , 就是登陆redis 的登陆密码

配置从节点(eshop-cache02)配置文件

  • 在配置文件中修改 bind 127.0.0.1bind 192.168.0.31 本身自己的ip地址

  • 配置 replicaofreplicaof eshop-cache01 6379 eshop-cache01我是在 master node /etc/hosts 中配置了映射本机的ip

replicaof 填写主节点的ip 和 端口号

  • 开启安全认证 masterauth redis-pass 填写的就是 master node 的登陆密码,须要在主节点配置文件中配置

  • 强制读写分离 replica-read-only yes 这个默认是开启的

能够自由选择是否开启AOF持久化

测试主从复制(读写分离)

前后启动主节点和从节点的redis实例,进入主节点客户端,set k1 v1 而后在从节点中看是否能读取到数据,读取到数据即表明成功。

master-replica

info replication命令能够查看自己的角色是主节点 仍是 从节点

扩展阅读

相关文章
相关标签/搜索