Redis读写分离

  • 概述:

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

    2. 相关配置:

    3. repl-diskless-sync

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

    5. 当启动一个slave node的时候,它会发送一个PSYNC命令给master node。开始主从复制的时候,master会启动一个后台线程,开始生成一份RDB快照文件,同时还会将从客户端收到的所有写命令缓存在内存中。RDB文件生成完毕之后,master会将这个RDB发送给slave,slave会先写入本地磁盘,然后再从本地磁盘加载到内存中。然后master会将内存中缓存的写命令发送给slave,slave也会同步这些数据。slave node如果跟master node有网络故障,断开了连接,会自动重连。master如果发现有多个slave node都来重新连接,仅仅会启动一个rdb save操作,用一份数据服务所有slave node。

    6. 如果这是slave node重新连接master node,那么master node仅仅会复制给slave部分缺少的数据;

    7. 否则如果是slave node第一次连接master node,那么会触发一次full resynchronization。Redis读写分离

    8. redis采用异步方式复制数据到slave节点,不过redis 2.8开始,slave node会周期性地确认自己每次复制的数据量

    9. 一个master node是可以配置多个slave node的

    10. slave node也可以连接其他的slave node

    11. slave node做复制的时候,是不会block master node的正常工作的

    12. slave node在做复制的时候,也不会block对自己的查询操作,它会用旧的数据集来提供服务; 但是复制完成的时候,需要删除旧数据集,加载新数据集,这个时候就会暂停对外服务了

    13. slave node主要用来进行横向扩容,做读写分离,扩容的slave node可以提高读的吞吐量

    14. 为什么要用redis读写分离:单机情况下redis能承受大约2万的QPS(具体数据因机器配置与业务场景而异),如果想要承接更高数值的QPS(10万以上),则需要用到读写分离的redis集群。

    15. 读写分离的原理:对于缓存而言,读的需求量是远大于写的需求量的,而读写分离的机制就是在主机上执行写操作,然后异步地将数据复制到从机上,而从机只负责读操作,假设一台从机具有2万QPS,当业务场景需要10万的QPS时,只需要横向扩展5台redis从机即可(可支持水平扩展的读高并发架构):
      Redis读写分离

    16. 如果采用了主从架构,那么建议必须开启master node的持久化!

    17. redis replication的核心机制

    18. 主从架构的核心原理

    19. 主从复制的断点续传:从redis 2.8开始,就支持主从复制的断点续传,如果主从复制过程中,网络连接断掉了,那么可以接着上次复制的地方,继续复制下去,而不是从头开始复制一份

    20. 无磁盘化复制

    21. 过期key处理:slave不会过期key,只会等待master过期key。如果master过期了一个key,或者通过LRU淘汰了一个key,那么会模拟一条del命令发送给slave。

  • redis replication的完整运行流程与原理

    1. 如果全量复制过程中,master-slave网络连接断掉,那么salve重新连接master时,会触发增量复制

    2. master直接从自己的backlog中获取部分丢失的数据,发送给slave node,默认backlog就是1MB

    3. msater就是根据slave发送的psync中的offset来从backlog中获取数据的

    4. master执行bgsave,在本地生成一份rdb快照文件

    5. master node将rdb快照文件发送给salve node,如果rdb复制时间超过60秒(redis-cli的repl-timeout配置项),那么slave node就会认为复制失败(可以适当调节大这个参数)

    6. master node在生成rdb时,会将所有新的写命令缓存在内存中,在salve node保存了rdb之后,再将新的写命令复制给salve node

    7. lient-output-buffer-limit slave 256MB 64MB 60:如果在复制期间,内存缓冲区持续消耗超过64MB,或者一次性超过256MB,那么停止复制,复制失败

    8. slave node接收到rdb之后,清空自己的旧数据,然后重新加载rdb到自己的内存中,同时基于旧的数据版本对外提供服务

    9. 如果slave node开启了AOF,那么会立即执行BGREWRITEAOF,重写AOF

    10. 2个名词:
      runid:主服务器ID offset:从服务器最后接收命令的偏移量

    11. master和slave都会维护一个(各自的)offset:
      master会在自身不断累加offset,slave也会在自身不断累加offset。slave每秒都会上报自己的offset给master,同时master也会保存每个slave的offset(不一定就用在全量复制的,主要是master和slave都要知道各自的数据的offset,才能知道互相之间的数据不一致的情况)

    12. backlog(后面章节会详说):
      master node有一个backlog,默认是1MB大小,master node给slave node复制数据时,也会将数据在backlog中同步写一份。backlog主要是用来做全量复制中断候的增量复制的

    13. psync:从节点使用psync从master node进行复制,psync runid offset,master node会根据自身的情况返回响应信息,可能是FULLRESYNC runid offset触发全量复制,可能是CONTINUE触发增量复制

      
       
    14. master的runid:
      redis每次启动的时候都会有一个随机的id来保障redis的标识,重启后会重新生成,这就是redis的runid。如果master node重启(例如手动数据还原),那么slave node在重连后进行数据同步时,使用PSYNC <runid> <offset>将之前保存的master node的runid发送到重启后的master node,由master node告知slave node是执行全量复制还是增量复制。如果需要不更改run id重启redis,可以使用redis-cli debug reload命令

    15. PSYNC <runid> <offset>

    16. 复制代码

    17. slave node启动,仅仅保存master node的信息,包括master node的host和ip(由slave node中的redis.conf里面的slaveof属性配置)

    18. slave node内部有个定时任务,每秒检查是否有新的master node要连接和复制,如果发现,就跟master node建立socket网络连接

    19. slave node发送ping命令给master node

    20. 口令认证,如果master设置了requirepass,那么salve node必须发送masterauth的口令过去进行认证

    21. master node第一次执行全量复制,将所有数据发给slave node

    22. master node后续持续将写命令,异步复制给slave nodeRedis读写分离

    23. 复制的完整流程

    24. 数据同步相关的核心机制(指的就是第一次slave连接master的时候,执行的全量复制里面的一些细节的机制)

    25. 全量复制

    26. 增量复制

    27. heartbeat:主从节点互相都会发送heartbeat信息,master默认每隔10秒发送一次heartbeat,salve node每隔1秒发送一个heartbeat

    28. 异步复制:master每次接收到写命令之后,现在内部写入数据,然后异步发送给slave node

  • 部署redis的读写分离架构:

    1. bind 192.168.0.111

    2. 复制代码

    3. bind 192.168.0.112

    4. # 据说是外国的猿们请愿master-slave的说法涉嫌种族歧视,

    5. # 于是redis5.0中众多涉及到slave的名词都改成了replica,开源不易

    6. slaveof 192.168.1.1 6379

    7. # redis 5.0 对应的配置项:replicaof

    8. slave-read-only yes # 默认开启,会拒绝所有的写操作,强制搭建成读写分离的架构

    9. # redis 5.0对应的配置项:replica-read-only

    10. 复制代码

    11. (完成redis的单机安装与部署)

    12. 修改redis.conf(6379.conf):

      
       
    13. 修改主机的redis.conf(6379.conf):

      
       
    14. 主机效果:
      Redis读写分离

    15. 从机效果:

      Redis读写分离