从零单排学Redis【铂金一】

前言

只有光头才能变强

好的,今天咱们要上铂金段位了,若是还没经历过青铜和白银和黄金阶段的,能够先去蹭蹭经验再回来:git

这篇文章主要讲的是Redis主从复制。由于Redis集群的知识点有点多,因此铂金上分得要好几篇~github

文本力求简单讲清每一个知识点,但愿你们看完能有所收获数据库

1、主从架构

1.1为何要主从架构

Redis也跟关系型数据(MySQL)同样,若是有过多请求仍是撑不住的。服务器

一台Redis撑不住

由于Redis若是只有一台服务器的话,那随着请求愈来愈多:网络

  • Redis的内存是有限的,可能放不下那么多的数据
  • 单台Redis支持的并发量也是有限的
  • 万一这台Redis挂了,全部的请求全走关系数据库了,那就更炸了。

显然,出现的上述问题是由于一台Redis服务器不够,因此多搞几台Redis服务器就能够了架构

多搞几台Redis服务器

为了实现咱们服务的高可用性,能够将这几台Redis服务器作成是主从来进行管理并发

主从架构

tip:Redis做者已将Master/Slave架构更名为Master/Replica

1.2主从架构的特色

下面咱们来看看Redis的主从架构特色:spa

  • 服务器负责接收请求
  • 服务器负责接收请求
  • 从服务器的数据由主服务器复制过去。主从服务器的数据是一致

主从架构特色

主从架构的好处设计

  • 读写分离(主服务器负责写,从服务器负责读)
  • 高可用(某一台从服务器挂了,其余从服务器还能继续接收请求,不影响服务)
  • 处理更多的并发量(每台从服务器均可以接收读请求,读QPS就上去了)

主从架构除了上面的形式,也有下面这种的(只不过用得比较少):3d

从服务器又挂着从服务器

2、复制功能

主从架构的特色之一:主服务器和从服务器的数据是一致的。

由于主服务器是能接收写请求的,主服务器处理完写请求,会作什么来保证主从数据的一致性呢?若是主从服务器断开了,过一阵子才重连,又会怎么处理呢?下面将会了解到这些细节~

在Redis中,用户能够经过执行SALVEOF命令或者设置salveof选项,让一个服务器去复制(replicate)另外一个服务器,咱们称呼被复制的服务器为主服务器(master),而对主服务器进行复制的服务器则被称为从服务器(salve)

复制

2.1复制功能的具体实现

复制功能分为两个操做:

  • 同步(sync)

    • 将从服务器的数据库状态更新至主服务器的数据库状态
  • 命令传播(command propagate)

    • 主服务器的数据库状态被修改,致使主从服务器的数据库状态不一致,让主从服务器的数据库状态从新回到一致状态

主从数据一致性

从服务器对主服务器的同步又能够分为两种状况

  • 初次同步:从服务器没有复制过任何的主服务器,或者从服务器要复制的主服务器跟上次复制的主服务器不同
  • 断线后同步:处于命令传播阶段的主从服务器由于网络缘由中断了复制,从服务器经过自动重连从新链接主服务器,并继续复制主服务器

在Redis2.8之前,断线后复制这部分其实缺乏的只是部分的数据,可是要让主从服务器从新执行SYNC命令,这样的作法是很是低效的。(由于执行SYNC命令是把全部的数据再次同步,而不是只同步丢失的数据)

接下来咱们来详细看看Redis2.8之后复制功能是怎么实现的:

2.1.1复制的前置工做

首先咱们来看一下前置的工做

  • 从服务器设置主服务器的IP和端口
  • 创建与主服务器的Socket链接
  • 发送PING命令(检测Socket读写是否正常与主服务器的通讯情况)
  • 身份验证(看有没有设置对应的验证配置)
  • 从服务器给主服务器发送端口的信息,主服务器记录监听的端口

Redis复制的前置工做

前面也提到了,Redis2.8以前,断线后同步会从新执行SYNC命令,这是很是低效的。下面咱们来看一下Redis2.8以后是怎么进行同步的。

Redis从2.8版本开始,使用PSYNC命令来 替代SYNC命令执行复制时同步的操做。

PSYNC命令具备完整重同步和部分重同步两种模式(其实就跟上面所说的初次复制和断线后复制差很少个意思)。

2.1.2完整重同步

下面先来看看完整重同步是怎么实现的:

  • 从服务器向主服务器发送PSYNC命令
  • 收到PSYNC命令的主服务器执行BGSAVE命令,在后台生成一个RDB文件。并用一个缓冲区来记录从如今开始执行的全部写命令
  • 当主服务器的BGSAVE命令执行完后,将生成的RDB文件发送给从服务器,从服务器接收和载入RBD文件。将本身的数据库状态更新至与主服务器执行BGSAVE命令时的状态。
  • 主服务器将全部缓冲区的写命令发送给从服务器,从服务器执行这些写命令,达到数据最终一致性。

完整重同步

2.1.2部分重同步

接下来咱们来看看部分重同步,部分重同步可让咱们断线后重连只须要同步缺失的数据(而不是Redis2.8以前的同步所有数据),这是符合逻辑的!

部分重同步功能由如下部分组成:

  • 主从服务器的复制偏移量
  • 主服务器的复制积压缓冲区
  • 服务器运行的ID(run ID)

首先咱们来解释一下上面的名词:

复制偏移量:执行复制的双方都会分别维护一个复制偏移量

  • 主服务器每次传播N个字节,就将本身的复制偏移量加上N
  • 从服务器每次收到主服务器的N个字节,就将本身的复制偏移量加上N

经过对比主从复制的偏移量,就很容易知道主从服务器的数据是否处于一致性的状态!

复制偏移量

那断线重连之后,从服务器向主服务器发送PSYNC命令,报告如今的偏移量是36,那么主服务器该对从服务器执行完整重同步仍是部分重同步呢??这就交由复制积压缓冲区来决定。

当主服务器进行命令传播时,不只仅会将写命令发送给全部的从服务器,还会将写命令入队到复制积压缓冲区里面(这个大小能够调的)。若是复制积压缓冲区存在丢失的偏移量的数据,那就执行部分重同步,不然执行完整重同步。

服务器运行的ID(run ID)实际上就是用来比对ID是否相同。若是不相同,则说明从服务器断线以前复制的主服务器和当前链接的主服务器是两台服务器,这就会进行完整重同步。

因此流程大概如此:

同步的流程

2.1.3命令传播

当完成了同步以后,主从服务器就会进入命令传播阶段。这时主服务器只要将本身的写命令发送给从服务器,而从服务器接收并执行主服务器发送过来的写命令,就能够保证主从服务器一直保持数据一致了!

在命令传播阶段,从服务器默认会以每秒一次的频率,向服务器发送命令REPLCONF ACK <replication_offset> 其中replication_offset是从服务器当前的复制偏移量

发送这个命令主要有三个做用:

  • 检测主从服务器的网络状态
  • 辅助实现min-slaves选项
  • 检测命令丢失

5、最后

画了很久很久的图,终于写完啦。

抛个问题:若是从服务器挂了,不要紧,咱们通常会有多个从服务器,其余的请求能够交由没有挂的从服务器继续处理。若是主服务器挂了,怎么办?由于咱们的写请求由主服务器处理,只有一台主服务器,那就没法处理写请求了?

问题留到下篇解决~~

参考资料:

  • 《Redis设计与实现》
  • 《Redis实战》

若是你以为我写得还不错,了解一下:

帅的人都关注了

相关文章
相关标签/搜索