Redis(6):主从架构简介

1.redis主从架构的主要意义

(1).redis高并发对于高并发系统的意义

        我们从高并发这个角度来探讨一下这个问题,要应对高并发场景的话,仅仅就使用MySQL的话是不够的,一般情况下MySQL能够做到QPS2000左右,不过也不排除做了一系列复杂的分库分表的MySQL,比如强事务要求的订单系统,QPS做到几万也算很高了,但是这样代价是很高的。但是一个单机的redis如果只是做一些简单的k,v操作的话很容易就可以做到几万。所以说,要做一个高并发系统的话,把底层缓存做得很好是不可避免的,但是仅仅使用Redis是不够的,但是redis是整个大型的能够支撑高并发的缓存架构中非常重要的一个环节。要做一个能够支撑起数十万甚至上百万并发的系统,底层的缓存中间件、缓存系统要能支撑这种程度的高并发,其次还需要良好的缓存架构设计,比如多级缓存架构、提高热点缓存的命中。

(2).Redis用来做高并发的瓶颈在哪?

        其实这个问题的的答案就两个字:单机。

(3).怎样才能使redis能够支撑起超过10万+的并发?

        首先说一下特殊情况,如果你的服务器配置超级高,维护也做得很到位,对于Redis的操作也很简单,那么QPS过十万是很有可能的,但是在一般情况下单机的Redis只能有几万的QPS。

如果用Redis做读写分离架构,面对那种读请求很多,写请求不是很多的场景是非常好的。(如果读请求很多的话,可以使用异步队列实现,这里因为能力有限就不介绍了。)采用读写分离的Redis主从架构破10万的QPS还是不是很难。


Redis的主从架构

上图为Redis的主从架构的简单说明。

(4).redis主从复制的机制

(a).redis采用异步方式复制数据到slave节点,slave node会周期性地确认自己每次复制的数据量。

(b).一个master node是可以配置多个slave node的。

(c).slave node也可以连接其他的slave node。

(d).slave node做复制的时候,是不会影响master node的正常工作的。

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

(f).slave node主要用来进行水平扩容,做读写分离,扩容的slave node可以提高读的吞吐量。

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

        如果是使用了redis的主从架构的话,建议要打开master节点的持久化,不建议使用slave节点进行热备,如果你的master节点没有持久化的话,master节点如果宕机重启的话,master节点里面的数据都是空的,可能一经过复制,slave节点里的数据全部被清空。所以说,master节点要把持久化开起来。而且master节点的冷备也要做起来,万一数据没有恢复成功,拷贝一份RDB过来,只有master节点的数据恢复了,slave节点的数据也就恢复了。

        还有就是redis的哨兵机制,如果结合哨兵机制来做高可用性的话,也需要对master做持久化,因为很可能哨兵机制还没有检测到master节点宕机,然后master节点重启后就把数据清空了。

2.主从架构的一些原理简介

(1).全量复制的原理简介

        首先slave节点会先ping一下master节点,看能不能ping通,如果slave节点是第一次连接master节点,那么master节点会执行一个操作:全量从复制(full resynchronization),即master将他所有的数据一次性给这个slave节点。如果这个节点是重新连上master节点,那么master节点不会把全部的数据给他,而是给他部分新的数据。

        开始full resynchronization的时候,master会启动一个后台线程,开始生成一份RDB快照文件,同时还会将从客户端收到的所有写命令缓存在内存中。RDB文件生成完毕之后,master会将这个RDB发送给slave,slave会先写入本地磁盘,然后再从本地磁盘加载到内存中。然后master会将内存中缓存的写命令发送给slave,slave也会同步这些数据。

        slave node如果跟master node有网络故障,断开了连接,会自动重连。master如果发现有多个slave node都来重新连接,仅仅会启动一个rdb save操作,用一份数据服务所有slave node。


正常连接的主从复制
第一次连接上master,进行全量复制

(2).主从复制的断点续传

        从redis 2.8开始,就支持主从复制的断点续传,如果主从复制过程中,网络连接断掉了,那么可以接着上次复制的地方,继续复制下去,而不是从头开始复制一份,master node会在内存中创建一个backlog,master和slave都会保存一个replica offset还有一个master id,offset就是保存在backlog中的。如果master和slave网络连接断掉了,slave会让master从上次的replica offset开始继续复制,但是如果没有找到对应的offset,那么就会执行一次resynchronization。

(3).无磁盘化复制

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


无磁盘化复制的配置

        repl-diskless-sync 开关。

        repl-diskless-sync-delay 生成完RDB文件之后可以设置等待一段时间,这样可以给更多的slave节点复制。传输一旦开始就不会接受新的slave节点的复制请求,

(4).过期key处理

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

3.redis主从架构的一些核心机制笔记

(1).主从复制的完整流程介绍

a.slave node启动,保存master node的信息,包括master node的host和ip,但此时复制流程没开始,master host和ip保存在redis.conf里面,配置项为:slaveof

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

c.slave node发送ping命令给master node。

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

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

f.master node后续持续将写命令,异步复制给slave node。


完整流程

(2).数据同步相关的核心机制

a.master和slave都会维护一个offset

        master会在自身不断累加offset,slave也会在自身不断累加offset,slave每秒都会上报自己的offset给master,同时master也会保存每个slave的offset,由offset来判断两者的数据是否一致。

b.backlog

        master node有一个backlog,默认是1MB大小,master node给slave node复制数据时,也会将数据在backlog中同步写一份,backlog主要是用来做全量复制中断后的增量复制。

c.master run id

        通过host+ip我们可以定位master node,但是我们不能通过他们来判断master的数据是否同步,如果master node重启或者数据出现了变化,那么slave node应该根据不同的run id区分,比如说,你使用一份RDB冷备来恢复master的数据,master不仅仅是数据产生了变化,runid也会发生变化,run id不同就马上进行全量复制。如果需要不更改run id重启redis,可以使用redis-cli debug reload命令。

d.psync

        slave节点发送psync相关的指令给master node进行复制,使用psync将 runid和 offset发送给master,master node会根据自身的情况返回响应信息,如果是runid发生了变化,他就会返回FULLRESYNC runid offset触发全量复制,如果runid没有发生变化则返回CONTINUE触发增量复制。

(3).全量复制的流程

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

b.master node将rdb快照文件发送给salve node,如果rdb复制时间超过60秒(可以通过配置repl-timeout来设定),那么slave node就会认为复制失败,可以根据实际情况适当调节大这个参数。(对于千兆网卡的机器,一般每秒传输100MB,6G文件,很可能超过60s)。

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

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

e.slave node接收到rdb之后,先将RDB文件持久化到硬盘中,然后清空自己的旧数据,然后重新加载rdb文件到本机的内存中,同时基于旧的数据版本对外提供服务。

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

ps:全量复制还是很耗费时间的,因为其间有rdb文件的生成,通过网络传输rdb文件,slave旧数据的清理,salve aof开启的话还需要进行rewrite,所以很耗费时间,如果复制的数据量在4G~6G之间,那么很可能全量复制时间消耗到1分半到2分钟。

(4).增量复制

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

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

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

(5).heartbeat

当全量复制完毕之后,主从节点互相都会发送heartbeat信息,master默认每隔10秒发送一次heartbeat,salve node每隔1秒发送一个heartbeat。

(6).异步复制

主从节点正常工作时,master每次接收到写命令之后,先在内部写入数据,然后异步发送给slave node。

你可能感兴趣的:(Redis(6):主从架构简介)