天天看点

大厂面试系列-面试被问到Redis集群数据是如何复制的?

大厂面试系列-面试被问到Redis集群数据是如何复制的?

首先对于Redis集群来讲有三种模式,主从复制模式、Sentinel(哨兵)模式、Cluster模式。下面我们就来分别看一下Redis的三种集群方案。

主从复制模式

大厂面试系列-面试被问到Redis集群数据是如何复制的?

首先来讲,我们可以通过持久化的手段,来保证Redis在服务重启的情况下数据不会丢失,或者说是丢失的数据很少。因为持久化的的时候会把内存中的数据保存到磁盘上,然后我们重启服务器的时候会从磁盘上加载数据,这样就保证了数据的持久化。但是由于数据是被存储到单个的服务器上,容易因为单点故障导致数丢失的问题。

这个时候我们为了避免单点故障,就出现了将数据多复制几份然后存储到不同的服务器上,这样即便是有服务器出现了故障,也不会导致数据丢失。因为其他服务器还是会提供服务。

为此,Redis提供了复制功能Replication。用来实现当一台数据库的数据更新之后,自动将数据同步到其他服务器数据库上的操作。

在这个Replication 的概念中,将数据库分成了两种,一种是主数据库(Master),一种是从数据库(Slave)。

其中主数据库主要完成对于数据的读写操作,其实主要是写操作。当写操作导致数据库的数据发生变化的时候,会自动通过同步机制将数据更新到从数据库中。而从数据库一般只支持读操作,并且接受来自主数据库的数据同步操作,相当于写。一个主数据库可以有多个从数据库,而一个从数据库只能有一个主数据库。

主从复制的原理

图片来源网络

大厂面试系列-面试被问到Redis集群数据是如何复制的?
  1. 从数据库搭建好之后,连接到主数据库,并且发送了一个SYNC命令。
  2. 主数据库收到从数据库发送的SYNC命令之后,开始执行BGSAVE命令用来生成RDB的快照文件并且使用缓冲区记录执行了BGSAVE命令之后的数据命令。
  3. 主数据库的BGSAVE命令执行完成之后,向所有的从数据库发送快照文件,并且记录在发送的过程中从缓存中同步的数据执行命令。
  4. 从数据库在收到了新的亏按照之后就会丢弃掉所有的旧数据,然后载入新的快照。
  5. 主数据库发送完快照之后,就会开始向从数据库发送缓存区中的命令。
  6. 从数据库按照快照载入完成之后,开始接收主数据库发送的命令,并且执行来自主数据库缓冲区中的命令。这个时候从数据库就算是初始化完成了。
  7. 主数据库执行了一条数据命令,就会向从数据库发送相同的命令,从数据库接收到命令之后执行,就完成了一条增量同步数据操作。
  8. 如果出现断线重连,主数据库将会将所有的增量数据与从数据库进行同步。

也就是说当主从连接刚刚建立的时候,进行全量的数据同步操作。全量数据同步结束之后,如果有需要从数据库可以发起全量同步,但是Redis提供的策略是无论如何都是先进行增量同步,如果没有成功,才会进行全量同步。

主从复制的优缺点

优点

  • 主从复制,主数据库会主动的将数据同步到从数据库中,可以有效的实现读写分离操作。这样从数据库就分担了主数据库的读操作的压力,因为从数据库也会为客户端提供读操作服务,但是根据上面的逻辑,写操作还是由主库来完成。
  • 从库也可以接收其他从库的连接请求和数据同步请求,也就是说从库搭建好了之后不一定非要从主库上去进行请求连接,也可以将请求连接与其他的从库进行连接,这样可以有效的减轻主库的同步压力。
  • 主库是以非阻塞的方式为从库提供服务,所以在主从同步的过程中,客户端仍然可以执行提交或者修改请求。
  • 从库也是同样采用非阻塞的方式完成数据同步的,也就是说在同步数据的时候,如果客户端有查询请求进入,Redis从库依然会返回之前的数据。

缺点

  • Redis 由于不具备自动容灾和恢复的能力,主库和从库的宕机都会导致部分读写请求的失败,这个是无可避免的,因为如果当前机器突然宕机,那么当前机器上所有的请求都将会失败,所以需要等到机器恢复或者是进行IP切换之后才能正常的访问,而这个操作在没有特殊处理手段的时候都是由人工来完成的。
  • 如果出现了多个从库宕机重启的时候,不能同时进行重启,因为数据同步机制会使得主库的IO剧增,导致主库宕机。
  • Redis很难支持在线扩容的操作,当集群的容量增加到一定程度之后,在线扩容机制就会变的非常的复杂。

Sentinel(哨兵)模式

根据上面的分析,主从复制模式,当主库宕机之后,需要手动的将其中一台服务器切换为主服务器,这就需要人力的干预,不仅费时费力,还会导致一部分损失。所以一般不推荐这种方式,当然在数据较少的情况下也可以采用。

为了解决上面这种问题就出现了哨兵模式。哨兵模式是一种特殊的模式,首先Redis中提供了哨兵的命令,并且这里所说的哨兵是一个独立的进程,作为进程来讲,它具有独立运行的特点就相当于我们的一个应用程序。而哨兵模式的原理就是哨兵通过发送命令的方式,等待Redis服务器响应,从而实现对于Redis实例的运行监控操作。如图所示。图片来源于网络

大厂面试系列-面试被问到Redis集群数据是如何复制的?

哨兵模式的作用就是要让哨兵发送命令,让Redis服务能够响应并且返回其对应的运行状态。并且当哨兵监听到主库宕机之后,会自动的将从库提升为主库,然后通过Redis的发布订阅模式将修改发布给其他服务的配置,从而实现主库的切换。

大厂面试系列-面试被问到Redis集群数据是如何复制的?

但是这里有个问题如果当我们的哨兵进程被卡死之后,没有办法进行监控了,那么我们之前遇到的问题还是得需要人工来解决。这个时候就有人提出了多哨兵模式,如上图所示。

假设主库宕机了,按照之前的说法,哨兵会立即知道主库宕机,这个时候仅仅只是哨兵知道主库宕机了,从库还在等待主库同步数据呢,然后当其他的哨兵同样也检测到了主库不能用了,这个时候就所有的哨兵都要进行投票了,从剩下的从库中选择一个从库将其设置为主库了。设置完成之后就会通过发布订阅将消息发送到其他从库。然后进行主库配置的切换。那么哨兵模式究竟是如何工作呢?

哨兵模式的工作机制

  • 对于每个哨兵来讲,其对应的进程会在规定的时间内向集群中的Master服务器、Slave服务器、以及其他哨兵发送一个消息。
  • 如果在指定的时间内没有收到响应的消息,则会被当前这个哨兵进程标记为对应的服务已经下线了。
  • 如果这个时候被标记下线的正好是一个Master服务器,那么当其他的哨兵线程也监听到了同样的下线消息之后,那么Master服务器就确认已经下线了。
  • 那么这个时候,就要将集群中的一个Slave节点升级成Master节点。当然这里需要注意点。如果在此过程中只有少部分的哨兵进程监听到了Master下线,那么哨兵就会修改对于Master服务器的监听时间,可能从10秒一次变成1秒一次的监听频率。
  • 如果这个时候监听到的Master并没有出现问题。那么就会将Master的下线标志移除。集群进入正常状态。

这里需要注意一个就是哨兵模式对于Redis集群的选主操作。其实这个我们可以参考Zookeeper集群的选主操作,其采用的都是Paxos算法。有兴趣的读者可以自己研究,笔者也会在后续的分享中介绍与之相关的内容。

从上面的机制来看,哨兵模式要比主从复制模式要高级一点,至少是可以进行主从切换,提升了集群的健壮性。

Cluster 集群模式

Cluster集群是Redis官方提供的模式,也是在实际开发中使用的比较多的一种模式。在Redis哨兵模式中基本上是实现了高可用、读写分离等。但是在哨兵模式下还是没有解决主从同步模式中的数据同步带来的数据冗余问题。因为在这两种模式下,主库和从库存储的都是相同的数据,会导致大量存储的浪费。而Redis官方提供的Cluster模式就实现了Redis数据的分布式存储,也就是说每个节点上存储的是不同的数据。

这样就不会出现数据冗余,存储资源浪费的问题,同时也减少了由于主从同步而带来的IO资源消耗等问题。

大厂面试系列-面试被问到Redis集群数据是如何复制的?

如图所示,图中的每个Redis节点都是相互连通的,并且客户端可以与其中的任意节点进行连接,并且可以访问到其中任意节点上的数据,并且对数据进行读写操作。

这种模式将整个的Redis集群看作一个存储整体,并且每个节点又可以独立存储,在提升了集群可用性的同时,既没有引入主从复制的消耗,也不会出现哨兵模式所带来的性能消耗。可以说将集群存储的概念利用到了极致。当然有优势就有劣势,这种模式在数据节点较少的情况下几乎是与主从模式性能相仿,而且在有些保证数据高可用的场景下甚至不如主从复制。

因为这种模式每个节点中存储的只是一部分数据,而如果在节点较少的情况下,一个节点宕机,就会导致对应节点上的数据丢失。所以有点得不偿失。

总结

在实际开发中,我们要根据自己具体的业务需求来选择合适的集群模式。根据上面的内容我们也知道,对于技术选择,没有最好只有最合适。

继续阅读