zoukankan      html  css  js  c++  java
  • redis主从复制机制

    单机redis理想状态可以承受将近每秒10万的读操作,实际情况还会少一些,那么如果想支持更高的访问量就需要通过redis的主从架构来实现读写分离。

    redis天然支持集群cluster,一主多从,一个master node可以有多个slave node,横向扩展非常方便。

    master的数据持久化可以保障数据安全

    采用主从架构必须开启master的数据持久化,不建议将slave当做master的热备份。虽然redis的哨兵模式sentinal检测到master failure会进行选举推选出新的mater,但是不排除原mater自动重启丢失数据后将整个集群的数据全部同步为空。

    redis replication

    核心机制:
    • master采用异步复制的方式将数据同步给slave,从2.8版本后出现了slave周期拉取需要复制的数据量。
    • slave node也可以连接slave node
    • slave node做复制的时候不会阻塞master node
    • slave node做复制是也不会停止本机的读造作,会用旧数据提供服务
    • 添加slave node做读写分离,提高读操作的吞吐量
    工作原理:

    当启动一个slave node,会发送PSYNC命令给master。

    若slave第一次连接master,则触发full resynchronization。master异步生成rdb文件,前台同时正常提供服务并将写操作缓存,rdb生成好了发送给slave,slave现将文件写入其所在的磁盘然后加载到内存中,master再把期间缓存的写命令同步给slave,完成同步。

    如果不是第一次连接,master仅将slave缺少的数据复制过去。

    出现了网络故障,slave node自动重新连接master,master只启动一个rdb save操作,等待5秒后如果有更多slave node重连,就只需要将刚刚备份好的rdb发送就可以。

    断点续传:

     redis2.8后支持断点续传,主从复制过程中出现故障后重连可以从上次的断点继续复制。master在内存中创建了一个backlog,双方都保存一个replica offset和master id,offset也保存在backlog中。

    无磁盘化复制:

    master在内存中直接创建rdb,然后发送给slave,不会在自己本地落地磁盘了

    repl-diskless-sync
    repl-diskless-sync-delay,等待一定时长再开始复制,因为要等更多slave重新连接过来

    过期key处理:

    slave不会自己过期key,等master的key过期或者LRU内存淘汰了一些key,会模拟del命令给slave。

    主从复制完整流程

    1. slave启动,从redis.conf中读取到master的ip和port。
    2. slave中有定时任务,每秒检查是否有新的master需要连接,如果有则建立socket连接。
    3. slave发送ping命令给master。
    4. 口令认证,如果master设置了requirepass,那么salve必须发送masterauth进行认证。
    5. master第一次进行全量复制,后续持续将写命令异步发送给slave。

    全量数据同步相关核心机制

    • offset:master和slave都会维护一个offset,不断累加。slave每秒将自己的offset上报给master保存。通过这种方式知道互相之间数据不一致的情况。
    • backlog:master的backlog默认1MB大小,在做全量复制时会假数据同时记录到backlog中,用来复制中断后的断点续传。
    • master run id:使用info server命令即可观察到,如果master发生了变化,集群的master run id就会变化,slave检测到其变化就会做全量复制。如果需要不更改run id重启redis,可以使用redis-cli debug reload命令。
    • psync:slave发送该psync runid offset给master进行复制,master检查后响应,根据runid和offset判断触发full resynchronization或者continue触发增量复制。

    全量复制

    1. master执行bgsave,在本地生成一份rdb快照文件。
    2. 将rdb发送给slave,如果时间超过60秒(repl-timeout),那么认为复制失败,可以适当调大该参数。千兆网卡一般每秒100M,6G多文件就可能超过60S。
    3. 在rdb生成和复制过程中master会将新的写命令缓存在内存,slave保存了rdb文件后再将新的写命令发送。
    4. client-output-buffer-limit slave 256MB 64MB 60 此配置规定了在复制期间,如果大小超过256M,或者缓存大于64MB,或者时间超过60S,就停止复制,复制失败。
    5. slave node接收到rdb之后,清空自己的旧数据,然后重新加载rdb到自己的内存中,同时基于旧的数据版本对外提供服务。
    6. 如果slave开启AOF,会立即执行bgrewriteraof,重写AOF。rdb生成、rdb通过网络拷贝、slave旧数据的清理、slave aof rewrite,很耗费时间,如果复制的数据量在4G~6G之间,那么很可能全量复制时间消耗到1分半到2分钟。

    增量复制

    1. 如果全量复制过程中网络断开,那么slave重新连接master时会触发增量复制。
    2. master直接从自己的backlog中获取部分丢失的数据发送。
    3. master根据slave发送的psync中的offset从backlog中获取数据。

    heartbeat

    主从节点互相发送心跳。master默认10秒发送一次,slave1S发送一次。

    异步复制

    master接收到写命令后,先在内部写入,再异步发送给slave。

  • 相关阅读:
    如果拷贝项目出现各种找不到文件的时候,基本就是没有标记,或者文件名的问题,Could not find resource mybatis.xml,解决方法
    The error may exist in com/bjpowernode/dao/StudentDao.xml ### Cause: org.apache.ibatis.builder.BuilderException: Error parsing SQL Mapper Configuration. Cause: org.apache.ibatis.builder.BuilderExcept
    一个简单jpa例子
    @PathVariable
    java.lang.NoClassDefFoundError: org/apache/log4j/Priority的问题解决
    yml中driver-class-name: com.mysql.jdbc.Driver 解析不到的问题
    docker 操作镜像的基本操作
    Navicat 远程连接Docker容器中的mysql 报错:1251
    spring boot中常用的配置文件的重写
    MVC最全jar包
  • 原文地址:https://www.cnblogs.com/ren-kai/p/12764431.html
Copyright © 2011-2022 走看看