这篇文章,我们将用非常通俗易懂的语言和大家聊聊大型分布式系统的容错架构设计。虽然定位上有“分布式”、“容错架构”等看似复杂的词汇,但我们还是按照老规矩:大白话+手绘几张彩图,循序渐进,让每个同学都能理解这个复杂的设计思路架构。1.将数TB的数据放在一台机器上:很难!下面以分布式存储系统为例,谈谈容错架构的设计。首先我们来看一下,什么是分布式存储系统?其实很简单,我们以数据库中的一张表为例。比如你手头有一个数据库,数据库里面有一个非常大的表,里面有几十亿甚至上百亿的数据。再者,假设这张表的数据量有几十TB,甚至几百TB,这时候你怎么想?当然,我的内心感到恐慌和无助,因为如果使用MySQL这样的数据库,单台数据库服务器上的磁盘可能是不够放这张表的数据的!让我们看看下面的图片来感受一下。2、什么是分布式存储?所以,如果您手头有一个非常大的数据集,数百TB!那你就不应该考虑用传统的数据库技术来存储。因为使用数据库服务器可能根本放不下,那我们考虑一下分布式存储技术吧?正确的!这是这个问题的解决方案。我们完全可以搞多台机器!比如你有20台机器,每台机器放1/20的数据。比如你总共有20TB的数据,那么每台机器只需要放1TB。1TB应该没问题吧?每台机器都能轻松愉快地放下这么多数据。因此,将一个大数据集拆分成多个块,放在多台机器上,就叫分布式存储。我们再看下图。3.那么什么是分布式存储系统?什么是分布式存储系统?分布式存储系统当然是负责将一个大的数据集拆分成多个块,存储在多台机器上,然后统一管理存储在多台机器上的数据的系统。比如经典的hadoop就是这样一个系统,fastdfs也是类似的。如果你能敞开心扉,从思想本质的共同层面出发,那么你会发现像elasticsearch、rediscluster等系统,本质上都是一样的。这些基于分布式系统架构,将大数据拆分为多个部分,并为您将它们存储在多台机器上。我们的文章从分布式系统架构层面出发,不拘泥于任何一种技术,所以我们可以这样设置:这个分布式存储系统有两个进程。一个进程就是Master节点,它位于一台机器上,负责对分散在多台机器上的数据进行统一管控。另一批进程称为从节点。每台机器都有一个Slave节点,负责管理本机上的数据,并与Master节点通信。我们先看看下图,再通过图片直观的看一下上面的描述。4.我的天哪!如果机器坏了怎么办?这时候还有一个问题,如果上面20台机器有一台宕机了怎么办?就尴尬了,兄弟,这样会导致20TB的数据完整拷贝,最后19TB还在,1TB的数据就会丢失,因为机器宕机了。所以你当然不能允许这种情况发生。这时候就必须制定数据复制策略。比如我们可以把1TB的数据在每台机器上做两份冗余副本,放到其他机器上。那么,如果某台机器宕机了,那也没关系,因为其他机器上也有他的副本。我们来看看这个多副本冗余的架构设计图。上图中淡蓝色的“1TB数据01”代表20TB数据集中的第一个1TB数据片段。图中可以看到,他有3份,三台机器中各有淡蓝色的方块,代表他的三份。在这种情况下,一份数据有3个副本。其他数据类似。这时候我们假设有一台机器宕机了,比如下面这台机器宕机了,必然会导致数据分片“1TB数据01”的其中一份数据丢失。如下图所示:此时重要吗?没关系,因为“1TB数据01”这个数据碎片,他在两台幸存的机器上还有另外两份!所以如果有人要读取数据,他们可以从其他两台机器上取一份读取。数据不会丢失。别紧张,大哥。5、Master节点如何感知数据副本的消失?现在有一个问题。比如有兄弟要读取“1TB数据01”的数据分片,他会找到Master节点说,“你能告诉我‘1TB数据01’的数据分片在Where吗?在哪台机器上?”?我需要读他!让我们看看下面的图片。此时Master节点需要从“1TB数据01”的3份中选择一份,告诉别人:“兄弟,哪台机器上有1份,你去那台机器上读一个就可以了“1TB数据01”的副本。》但是现在的问题是Master节点并不知道“1TB数据01”的副本3已经丢失,所以如果Master节点还通知其他人去读取已经丢失的副本3,那肯定是不可能的那么,如何让Master节点知道副本3已经丢失了呢?其实很简单,每台机器上负责管理数据的Slave节点每隔几秒就向Master节点发送一次心跳(比如,1秒),那么一旦Master节点发现有一段时间(比如30秒内)没有收到Slave节点发送的心跳,就会认为Slave节点所在的机器是down了,那台机器上的数据副本就丢失了,那么Master节点就不会告诉其他人读取丢失的数据副本了。看下图,一旦Slave节点宕机,Master节点就收不到了heartbeat,它会认为那台机器上的copy3已经丢失了,所以不允许任何人再找d此时在down机上copy3。那么这个时候Master节点就可以通知其他人读取“1TB数据01”的copy1或者copy2,哪个都可以,因为那两个copy还在。比如你可以通知客户端去读副本1,这时候客户端可以请求那台机器上的Slave节点去读那个副本1,整个过程如下图6所示。replicas不够,这时候还有一个问题,就是“1TB数据01”的数据分片只有replica1和replica2两个副本,不够用。复印件。因为我们默认是每个数据分片必须有3份。想一想,这个时候怎么给这个数据分片增加1份呢?这很简单。一旦Master节点感知到某台机器宕机,就可以感知到某个数据分片的副本数不足。这时候会产生一个副本复制任务,会选择另一台机器从有副本的机器上复制一份。例如,见下图,你可以选择第四台机器从第二台机器上复制一份。但是,既然复制任务可用,我们如何让机器4知道呢?其实很简单,机器4不是每秒发送一次心跳吗?当机器4发送心跳时,主节点通过心跳响应将复制任务发送给机器4,这样机器4就可以从机器2复制一份。同样的,我们来一张图看看这个过程:看上图,机器4上是不是还有“1TBdata01”的copy3?那么,“1TB数据01”的数据片段是不是又变成了3份呢?7.删除多余的副本。反之,如果这时候机器3突然恢复,上面还有一个“1TB数据01”的副本3,也就是说此时“1TB数据01”有4个副本。它是多余的吗?没关系,一旦master节点感知到机器3复活了,就会发现副本太多了,这时候就会产生一个删除副本的任务。他会在机器3发送心跳的时候发出删除副本的命令,让机器3删除自己本地冗余的副本。这样,副本数就可以保持在只有3个了。同理,请看下图。8.全文总结。至此,通过超大白话的讲解和十多张图的逐步演进,相信即使你之前不了解分布式系统,也一定能理解分布式系统的完备性。数据容错架构是如何设计的。其实这种数据分片存储、多副本冗余、宕机感知、副本自动迁移、冗余副本删除的机制和hadoop、elasticsearch等很多系统都是类似的。所以笔者在这里强烈建议大家一定要吸取分布式系统和中间件系统底层数据容错架构的思想。这样,以后学习一些类似的技术时,就会对他们的原理和思想产生一种似曾相识的感觉。
