【软件开发】大规模分布式系统的容错架构设计

阿里云国内75折 回扣 微信号:monov8
阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6

大规模分布式系统的容错架构设计

假设有一个数据库数据库里有一张特别大的表里面有几十亿甚至上百亿的数据。更进一步说假设这一张表的数据量多达几十个 TB甚至上百个 TB那么如果用 MySQL 之类的数据库单台数据库服务器上的磁盘可能都不够放这一张表的数据
在这里插入图片描述

假如你手头有一个超大的数据集几百 TB那你还是别考虑传统的数据库技术来存放了。因为用一台数据库服务器可能根本都放不下所以我们考虑一下分布式存储技术对了这才是解决这个问题的办法。

咱们完全可以搞多台机器嘛比如搞 20 台机器每台机器上就放 1 / 20 1/20 1/20 的数据。举个例子比如总共 20TB 的数据在每台机器上只要把 1TB 就可以了1TB 应该还好吧每台机器都可以轻松加愉快的放下这么多数据了。

所以说把一个超大的数据集拆分成多片给放到多台机器上去这就是所谓的分布式存储。
在这里插入图片描述

那分布式存储系统是啥呢分布式存储系统当然就是负责把一个超大数据集拆分成多块然后放到多台机器上来存储接着统一管理这些分散在多台机器上存储的数据的一套系统。

比如说经典的 Hadoop 就是这类系统然后 FastDFS 也是类似的。如果你可以脑洞打开从思想本质共通的层面出发那你会发现其实类似 Elasticsearch、Redis Cluster 等等系统本质都是如此。这些都是基于分布式的系统架构把超大数据拆分成多片给你存放在多台机器上。

咱们这篇文章是从分布式系统架构层面出发不拘泥于任何一种技术所以姑且可以设定这套分布式存储系统有两种进程。

  • 一个进程是 Master 节点就在一台机器上负责统一管控分散在多台机器上的数据。
  • 另外一批进程叫做 Slave 节点每台机器上都有一个 Slave 节点负责管理那台机器上的数据跟 Master 节点进行通信。

在这里插入图片描述

这个时候又有一个问题了那么万一上面那 20 台机器上其中 1 台机器宕机了咋整呢这就尴尬了兄弟这会导致本来完整的一份 20TB 的数据最后有 19TB 还在了有 1TB 的数据就搞丢了因为那台机器宕机了啊。所以说你当然不能允许这种情况的发生这个时候就必须做一个数据副本的策略。

比如说我们完全可以给每一台机器上的那 1TB 的数据做 2 个副本的冗余放在别的机器上然后呢万一说某一台机器宕机没事啊因为其他机器上还有他的副本。我们来看看这种多副本冗余的架构设计图。
在这里插入图片描述

上面那个图里的深蓝色的 1TB 数据 01代表的是 20TB 数据集中的第一个 1TB 数据分片。从上图中可以看到它有 3 个副本分别在三台机器中都有浅蓝色的方块代表了它的三个副本。这样的话一份数据就有了 3 个副本了。其他的数据也是类似。

这个时候我们假设有一台机器宕机了比如下面这台机器宕机必然会导致 1TB 数据 01 这个数据分片的其中一个数据副本丢失。如下图所示
在这里插入图片描述

那这个时候要紧吗不要紧因为 1TB 数据 01 这个数据分片他还有另外 2 个副本在存活的两台机器上呢所以如果有人要读取数据完全可以从另外两台机器上随便挑一个副本来读取就可以了数据不会丢的。

现在有一个问题比如说有个兄弟要读取 1TB 数据 01 这个数据分片那么他就会找 Master 节点说你能不能告诉我 1TB 数据 01 这个数据分片人在哪里啊在哪台机器上啊我需要读他啊

那么这个时候Master 节点就需要从 1TB 数据 01 的 3 个副本里选择一个出来告诉人家说兄弟在哪台机器上有 1 个副本你可以去那台机器上读 1TB 数据 01 的一个副本就 OK 了。

但是现在的问题是Master 节点此时还不知道 1TB 数据 01 的副本 3 已经丢失了那万一 Master 节点还是通知人家去读取一个已经丢失的副本 3肯定是不可以的。

所以我们怎么才能让 Master 节点知道副本 3 已经丢失了呢

其实也很简单每台机器上负责管理数据的 Slave 节点都每隔几秒比如说 1 秒给 Master 节点发送一个 心跳。那么一旦 Master 节点发现一段时间比如说 30 秒内没收到某个 Slave 节点发送过来的心跳此时就会认为这个 Slave 节点所在机器宕机了那台机器上的数据副本都丢失了然后 Master 节点就不会告诉别人去读那个丢失的数据副本。

大家看看下面的图一旦 Slave 节点宕机Master 节点收不到心跳就会认为那台机器上的副本 3 就已经丢失了此时绝对不会让别人去读那台宕机机器上的副本 3。
在这里插入图片描述

那么此时Master 节点就可以通知人家去读 1TB 数据 01 的副本 1 或者副本 2哪个都行因为那两个副本其实还是在的。举个例子比如可以通知客户端去读副本 1此时客户端就可以找那台机器上的 Slave 节点说要读取那个副本 1。

这个时候又有另外一个问题那就是 1TB 数据 01 这个数据分片此时只有副本 1 和副本 2 这两个副本了这就不足够 3 个副本啊。因为我们预设的是每个数据分片都得有 3 个副本的。大家想想此时如何给这个数据分片增加 1 个副本呢

很简单Master 节点一旦感知到某台机器宕机就能感知到某个数据分片的副本数量不足了。此时就会生成一个副本复制的任务挑选另外一台机器来从有副本的机器去复制一个副本。

比如看下面的图可以挑选第四台机器从第二台机器去复制一个副本。
在这里插入图片描述

但是现在这个复制任务是有了我们怎么让机器 4 知道呢其实也很简单机器 4 不是每秒都会发送一次心跳么当机器 4 发送心跳过去的时候Master 节点就通过心跳响应把这个复制任务下发给机器 4让机器 4 从机器 2 复制一个副本好了。

同样我们来一张图看看这个过程
在这里插入图片描述
看上图现在机器 4 上是不是又多了一个 1TB 数据 01 的副本 3 那么 1TB 数据 01 这个数据分片是不是又变成 3 个副本了

那反过来如果说此时机器 3 突然恢复了他上面也有一个 1TB 数据 01 的副本 3相当于此时 1TB 数据 01 就有 4 个副本了副本不就多余了吗

没关系一旦 Master 节点感知到机器 3 复活会发现副本数量过多此时会生成一个删除副本任务。他会在机器 3 发送心跳的时候下发一个删除副本的指令让机器 3 删除自己本地多余的副本就可以了。这样就可以保持副本数量只有 3 个。

一样的大家来看看下面的图。
在这里插入图片描述

实际上这种 数据分片存储 、多副本冗余、宕机感知、自动副本迁移、多余副本删除这套机制对于 Hadoop、Elasticsearch 等很多系统来说都是类似的。

所以笔者在这里强烈建议大家一定好好吸收一下这种分布式系统、中间件系统底层数据容错架构的思想。

阿里云国内75折 回扣 微信号:monov8
阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6