
写点什么







🕋【Redis 干货领域】彻底走进主从架构的世界(入门篇)

用户头像
李浩宇/Alex
关注
发布于: 2021 年 05 月 13 日
🕋【Redis干货领域】彻底走进主从架构的世界(入门篇)

📕 系列背景 📕


本片文章属于,彻底走进主从架构的世界三部曲中的入门篇,此外之后还有进阶篇和强化篇,前用循序渐进的方式去学习和介绍。

📕 人生箴言 📕


自由只存在于束缚之中,没有堤岸,哪里来江河? —— 金斯伯格

📕 前提摘要 📕


面试不少公司都很重视高并发、高可用和高性能的技术,特别是一线互联网公司:分布式、JVM、

Spring 源码分析、微服务等知识点几乎已是面试的必考题。今天我们就来将一个横跨高并发、高可用、高性能这三大特性集于一身的互联网高并发的“万金油”,它叫做 Redis。


对于 Redis 而言其本身的性能和吞吐率是毋庸置疑的,但是在高可用以及高负载能力,一般会在其主从模式的分布式架构层面进行实现和提升。接下来我们就针对于它的主从模式进行分析,其中会有许多问题需要考虑,这里写了一些关于 Redis 在主从模型下的一些问题分析和总结。

📕 主从模式 📕


「主从复制」可以说是整个 Redis 高可用实现的基石。


  • 架构集群、分片功能实现的基础;

  • 高可用的一种策略。例如,解决单机并发问题、数据安全性等等问题。

💻 问题场景 💻


  • 负载超过了 Redis 单机能够处理的上限,还有一种情况 Redis 也无法保证自身的高可用性。

  • 即便 Redis 能够扛住所有流量,但是如果这个 Redis 进程所在的机器挂了呢?

此时所有的请求会直接调转枪口,大量的流量会瞬间把你的 DB 打挂(所谓缓存雪崩的最糟糕的情况)

💻 六大要素 💻


  • 数据的保障:RDB 和 AOF 再也不怕宕机丢失数据了,这里特别要注意的就是 AOF。

  • 产生的原因:Redis 单节点存在单点故障问题,为了解决单点问题。

  • 解决的方案:一般都需要对 Redis 配置 slave 节点,然后使用哨兵(Sentinel)来监听主节点的存活状态,如果主节点挂掉,从节点能继续提供缓存功能。

  • 主从的特性:Redis 从节点仅提供读操作,主节点提供写操作。对于读多写少的状况,可给主节点配置多个从节点,从而提高响应效率。

  • 数据的同步:Redis 数据的跨主机备份, Master 节点将自己的 RDB 文件同步给 Slave 节点,将数据冗余一份复制到 Slave Redis 服务器。

  • 高可用总结:Redis 主从配置结合哨兵模式能解决单点故障问题,提高 Redis 高可用性(avaliable)。

💻 基本特性 💻


  • 单一性:前者称为主节点 (master),后者称为从节点 (slave);RDB 文件数据的复制是单向的,只能由主节点到从节点。

  • 唯一性:每台 Redis 服务器都是主节点;且一个主节点可以有多个从节点 (或没有从节点),但一个从节点只能有一个主节点。

💻 总体架构 💻


在【主从同步】中,将节点的角色划分为 master(主库)和 slave(从库),形成「一主多从」。slave 负责读操作,而 master 负责写操作,形成一个读写分离的架构,这样就能够承载更多的业务请求。

多数的业务场景下,Redis 的「读操作」都要多于「写操作」,所以当读请求量特别大的时候,我们可以通过增加 slave 节点来使 Redis 扛住更多的流量。


💻 核心流程 💻


Redis(Slave)中我们可以通过 slaveof/replicaof 命令让一个 Redis(Slave)实例去复制另外一台 Redis(Master)的状态。被复制的 Redis 实例就是 Master 节点,而执行 slaveof/replicaof 命令的机器就是 Slave 节点,Slave 会按照某种策略从 Master 同步数据。Redis 的主从复制分为两个步骤,分别是「同步操作」和「命令传播」。


  • 「同步操作」用于将 master 节点内存状态复制给 slave 节点。

  • 「命令传播」在同步时,客户端又执行了一些「写」操作改变了服务器的状态,此时 master 节点的状态与同步操作执行的时候不一致了,所以需要命令传播来使 master 和 slave 状态重新一致(将单独生成的 writer buffer 内的数据信息传递同步给 slave)。


注意:replicaof 是新版本的命令,旧版本是 slaveof 命令,如果你使用的是 Redis 5.0.0 之前的版本,那么请使用 SLAVEOF 命令代替本章中的 REPLICAOF 命令,并使用 slaveof 配置选项代替本章中的 replicaof 配置选项


同步的大致的流程如下:


  1. slave 节点向 master 节点发送 sync 命令。

  2. master 收到 sync 命令之后会执行 bgsave 命令,Redis 会 fork 出一个子进程在后台生成 RDB 文件,同时将同步过程中的写命令记录到 Writer Buffer(缓冲区)中。

  3. RDB 文件生成后,master 会把 RDB 文件发送给 slave,slave 服务器接收到 RDB 文件会将其载入内存。

  4. 然后 master 将记录在 Writer Buffer(缓冲区)的所有写命令发送给 slave,slave 对这些命令进行「重放」,将其数据库的状态更新至和 master 一致


通过图再来了解一下:

以上就是最基本的 Redis【主从同步】架构的基本流程和原理。

🖊如果当从库(Slave)出现的问题🖊


上面讨论的是 slave 第一次连接到 master,会执行「全量复制」,而针对上面这种情况,Redis 新老版本处理方式不一样。这就是接下来要将的新版本优化的功能「断点续传」(psync)了。

  • Redis2.8 之前,当主从完成了同步之后,slave 如果断线重连,向 master 发送 sync 命令,master 会将全量的数据再次同给 slave。(过于庞大的重放数据量以及延迟的恢复时间+重放给 CPU 和 IO 带来的性能损耗),此外 Redis 本来都是串行顺序化处理数据信息,就是大部分数据都是有序的,再次全量同步显得没有必要。


  • Redis2.8 之后,为了解决这个问题,便使用了 psync 命令来代替 sync。简单来说 psync 命令就是将 slave 断线期间 master 接收到的写命令全部发送给 slave,slave 重放之后状态便与 master 一致了。


psync 的实现原理


psync 的实现依赖于主从双方共同维护的 offset 偏移量。


基于 offset,只需要简单的比对就知道当前主从的状态是否是一致的了,然后基于 offset,将对应偏移量所对应的指令传播给 slave 重放即可,所以即使同步的时候 slave 挂掉了,基于 offset,也能达到断点续传的效果。


主库向从库同步数据


  • master 向 slave 进行「命令传播」,传播多少个字节的数据,就将自己的 offset 加上传播的字节数。

  • slave 每次收到多少字节的数据,也会同样的更新自己的 offset。

🖊当主库(Master)出现的问题🖊


  • Redis 的确也有想到,实际上除了 offset 之外,slave 断线重连之后还会带上一个 master 的实例的 runid,每个服务实例都有自己的唯一的 runid,只要 Redis 服务重启,其 runid 就会发生改变。

  • master 收到这个 runid 之后会判断是否与自己当前的 runid 一致,如果一致说明断线之前还是与自己建立的连接,而如果不一致就说明 slave 断线期间,master 也发生了宕机,此时就需要将数据「全量同步」给 slave 了

需要通过这个 offset 去拿到真正需要的数据也就是指令,Redis 是通过「复制积压缓冲区」来实现的。

复制积压缓冲区的默认大小为 1M,Redis 在进行「命令传播」时,除了将写命令发送给 slave,还会将命令写到「复制积压缓冲区」内,并和当前的 offset 关联起来。这样一来就能够通过 offset 获取到对应的指令了。


但是由于缓冲区的大小有限,如果 slave 的断线时间太久,复制积压缓冲区内早些时候的指令就已经被新的指令覆盖掉了,此处可以理解为一个队列,早些时候入队的元素已经被出队了。

由于没有相对应的 offset 了,也就无法获取指令数据,此时 Redis 就会进行「全量同步」。当然,如果 offset 还存在于复制积压缓冲区中,则按照对应的 offset 进行「部分同步」。

基于以上的全量、增量的主从复制,能够在 master 出现故障的情况下,进行主从的切换,保证服务的正常运行。除此之外还能解决异常情况下数据丢失的问题。基于读写分离的策略还能够提高整个 Redis 服务的并发量。

📕 案例操作 📕

环境演示中,有一台主机,启动了两个 Redis 示例。


💻 服务启动配置 💻


该方式通过在启动 Redis 服务时,通过命令行参数,进行启动主从复制功能。该方式的弊端是不能实现配置持久化,当服务停掉之后,启动服务时,需要添加相同的命令参数。


  1. master 服务器事先在 redis.confg 增加 requirepass 项。


requirepass 6379


  1. 启动从服务器


redis-server --port 6380 --replicaof/--slaveof 192.168.2.102 6379

💻 命令行配置 💻


该方式通过使用 redis-cli 进入操作行界面,进行配置。该方式的弊端是不能实现配置持久化,当服务停掉之后,启动服务需要执行同样的命令。


  1. master 服务器执行


127.0.0.1:6379> config set requirepass 6379

OK


  1. slave 服务器执行


127.0.0.1:6380> replicaof 192.168.2.102 6379

OK

127.0.0.1:6380> config set masterauth 6379

OK


💻 配置文件配置 💻


该方式是通过 redis.conf 配置文件进行设置,能够实现配置的持久化,是一种推荐使用的方式。


  1. 配置主服务器,redis.config


requirepass 6379


  1. 配置从服务器,redis.config


masterauth 6379

replicaof 192.168.2.102 6379

💻 配置说明💻

  • masterauth:设置 redis.config 连接密码,如果设置了该值。其他客户端在连接该服务器时,需要添加密码才可以访问。

  • requirepass:设置主服务器的连接密码,和 1 中 masterauth 一致。

  • replicaof:从服务器连接到主服务器的 IP 地址+端口号。

📕 效果测试📕

1.主服务器添加数据。


2.从服务器获取数据。




未完待续...... 后续会有同系列的下一篇(进阶篇),对于更高层次能力的开发者


用户头像

李浩宇/Alex

关注

我们始于迷惘,终于更高水平的迷惘。 2020.03.25 加入

🏆 【酷爱计算机技术、醉心开发编程、喜爱健身运动、热衷悬疑推理的”极客狂人“】 🏅 【Java技术领域,MySQL技术领域,APM全链路追踪技术及微服务、分布式方向的技术体系等】 🤝未来我们希望可以共同进步🤝







评论

发布
暂无评论
🕋【Redis干货领域】彻底走进主从架构的世界(入门篇)