如何认识分布式系统

写这篇文章之前,给文章起标题想了很久。首先,我想写的不是介绍任何一个商用或开源的分布式系统,这种文章网上太多的教程了,而且质量很高,我觉得我无法写出更好的,也没有这个必要。如果起名叫分布式系统概述之类,感觉题目就太大了,我现在还没有这样的层次去对某一个技术方向去“概述”。所以思来想去呢,给的标题是--如何认识分布式系统。某种程度上就是我本人怎么来认识和理解分布式系统的一个过程,使用一篇文章将其记录下来,将工作学习过程中的一些片段,细节梳理到一起,但是由于篇幅原因,在文章中基本只提到一些分布式中的细分方向,不会进行展开阐述,主要是希望这篇文章成为认识分布式的线索,能根据这条线索去按图索骥,形成一个全局观。希望能帮助到各位看客,如果对您有所启发,帮助或者很好的打法了您的时间,请点赞一下。

一. 为什么有分布式

世界本没有分布式,用的人多了,就有了分布式。这句话是我临时起意编的,但是我觉得很好的说明了为什么要有分布式系统。学习一个技术呢,一定要了解这门技术是解决一个什么问题。那么分布式是解决什么问题呢,就是解决用的人太多了的问题。

以前的软件系统一般都是单机版的,自己一个人用用就好。随着网络,移动互联网的兴起,大型的网站、系统逐步构建起来。刚开始我们可以把所有的应用全部放在一台服务器上,1G内存不够用10G,再不够用100G。随着单台已经无法支持用户和数据规模后,工程师们自然而然的就想到了将一些东西分到不同的机器上去,使用多台机器来协作。于是,分布式就出来了。

二. 如何分,谁来当头儿?(分布式集群结构)

有人的地方就有江湖,江湖中流传着两大组织方式:民主和专制。同样的,机器一多了,也有了江湖。如何组织这帮“江湖机器”,就成为了分布式要处理的第一个问题。

1 专制制度:一群机器里面,有一个特别厉害的,性能特别强悍的,就成为了这些机器里面的头儿,负责协调和指挥所有其他机器,来活了也是这台机器来分配任务。而其他的机器需要定时想它汇报近况:是否还活着(心跳机制),我是不是闲下来了(资源上报),当前的活还有多少没做完(任务上报)等等。新来的菜鸟必须到老大拜完码头才能入伙(注册)。这样一种组织方式,就是集中式结构。一般还有Master-Slave/Leader-Worker等类似的名称。

2 民主制度:大家都差不多,不好指定谁来当老大。那么大家就一起协商着来做事。这样也可以分成两种方式:

2.1 大家做事之前,先选举一个牵头的出来,好协调大家的事情,自然这个协调者就不需要干什么活了,给大家当个秘书啥的就挺好。和专制制度不一样,这个头头是通过一定的规则选举出来的(分布式选举),当他挂了或者出了什么西西的时候,大家可以再通过同样的规则再选一次,不至于所有人一起完蛋。而专制制度中,如果老大挂了,整个群体就GAME OVER了。

选举的话,一般采用的方式有几种。

年龄大的资历老,那最老的来当老大(基于序号ID,当然也有可能是选ID最小的)。

入会时间长的来当老大(时间戳)

一般来说,选举都会根据某个因素来排序,或者是少数服从多数。同样,最好是奇数个节点进行选举。

2.2 所有的人完全一样,所有的事情都大家一起来做决策,事情也一起做。这样的话,每一个人作出来一点东西或者有一点变动都需要知会到其他所有人,来作出相应的改动。另外,如果是一群陌生人一起共事的话,其中的信任度是一个极大的问题,需要有一套机制来保证没有人弄虚作假(分布式共识)。

三. 谁做多,谁做少(任务调度)

团队的结构定好了之后,就需要开始干活了。一个活来了,自然是团队里的兄弟们分着做了。但是怎么分合理,怎么分做的最快,这就是分布式调度的问题了。

不让马儿吃草,马儿就跑不快,干多少活就要匹配相应的资源。就这个事儿也可以分成几种方式来做。

  • 活(作业 job)和资源统一管理,活来了,决定给谁做,再从资源池里分配相应的资源给谁做,都由一个人管着。这个人可以从全局考虑,能将任务和资源统一调度和优化。但是这个人也有可能被累趴下,他一趴下,大家就都没法干活了。就算没累趴下,一堆人在外面排队等着他算清账,也是对人力极大的浪费(资源 + 作业统一调度,hadoop 1.0调度方式)。
  • 假设你是分活的老大,给活的时候也有两种给法,先把一个人玩命的分活,让他尽量不要歇着,其他人歇着,避免万一来了一个大活就免得没人能领走(最佳匹配)。你也可以不让一个人太累,这个分一点,那个分一点,大家都有事情做。缺点就是万一有一个大活来了,大家都忙着呢,就没人来领活(最差匹配)
  • 专人分活,锄头去其他地方领。我们也可以将作业调度和资源调度分开。那就变成,首先去找给你分活的老大,老大给你分了活,说让你去领5把锄头,你吭哧吭哧跑到资源大主管那里,资源老大告诉你锄头不够了,下次再来,你就只能回去把活退了重新领活(回滚),或者继续等在资源老大的办公室门口,啥时候锄头够了啥时候拿锄头去干活(等待)。这就是因为分工了,分活的老大不清楚资源那边的情况,造成了一些资源的浪费。这就引出了另外的一种调度模式
  • 设立一个军机处(State Storage),保存所有全局的资源状态和任务状态。军机处里面养了一堆监工,负责分活(Scheduler)。分活之前来军机处报到注册,领走相应的资源并得到授权,然后就可以拿着授权去找人干活了(resource pool),工作的监督也是又监工来保证,只是做完了回来注销就行。

四. 不同的活儿不同的做法(分布式计算方式)

一般来说,有两种形式的活儿会给到团队来做。一个是一次性的大工程,整体包给你了(批量任务)。还有就是细水长流行的,每天给一点,每天给一点(流数据)。自然,我们的团队要生存下去,对这种不同性质的活儿是要区分来对待的。

先说批量任务,一个大的任务来了,第一想法自然是拆,分而治之。你做一点,我做一点,然后大家一起汇总(MapReduce)。

然后就是流数据,流数据是时时刻刻来的,不能像批量任务一样,先拆任务,然后得到任务的人去领锄头,然后再来干活,活干完了再去还锄头。等搞完这套下来,后面的数据都已经流走了,数据的时效性早就过了,你也就接不到活了。最好是团队的人每时每刻都拿着锄头等活(常驻进程),来一点活立刻就给他按照规定动作给做完(Storm,Spark,Flink)。

五. 如何呼叫同伙支援(分布式通信)

大家分工合作完成一件事情,自然有一个前后顺序,我怎么知道我前面的人做完了呢?我 做完了怎么告诉我后面的同伴呢?这就是分布式通信的范畴了。

首先大家要有一个通信渠道,是拉电话线还是每人发个手机(使用RPC远程调用,还是使用HTTP协议,或者其他的通信协议)。

其次,团队之间要协商好交付方式,是你先告诉我你要什么,我做好了给你送上门呢?(发布-订阅模式,kafka),还是我放我家里,你自己定时来拿(生产者-消费者模式,RocketMQ)。

六. 货怎么保存(分布式存储)

大家为了干活,可能要近一些货物进来存着。货物太多,一个人家里的仓库太小放不下,自然就要分开放着了。那么这就需要考虑下怎么个分法了(数据分片)。

  • 团队总共100个人,根据货物上面的编号(ID)来,最后两位数是谁,那就放到谁家里(哈希)
  • 第一个方法的话,万一团队来了新人,那么这个ID与货物的对应关系就乱了(数据稳定性差),所以必须要想一个新的办法。把货物编号按照哈希分成1000份,收尾相连。再把100个人的仓库均匀分布在这个数字环里,如果货物来了,编号离谁家仓库编号最近,就放到谁家里(一致性哈希)
  • 万一谁家放不下了呢,只能是在仓库门口放一个已满,或者提前跟大家知会,我家只能放10吨货(带负载的一致性哈希)。
  • 更一般的,每个人家里的仓库大小都不一样(异构性),没法标准化,只能把每个人家里按照统一的标准划分成一个一个的隔间,把割接对应到哈希环中去,货物就按照隔间来分发(虚拟一致性哈希)。

数据是存下来了,还有一个问题是,万一你家里仓库着火了怎么办,恰好你又是保存的最关键的那批货,那不整个团队都跟着倒霉?必须想个办法多存一份(数据备份)。

  • 货物买两份,往你家里搬一份的同时,再往另外的仓库也搬一份,才算入库(同步复制)
  • 货物买两份,先往你家里搬一份,就算入库了,后面的那一批后续再说(异步复制)。

整个故事讲完了,当然这个里面还有很多分布式的其他内容(集群,监控等等)没有提到,而且也没有提到具体的一些软件系统,因为每个商用或者开源软件都是会同时解决这个分布式范畴里面的一个或者多个问题,后续可能考虑再组织一篇文章吧。但是我觉得主要的流程就是这些。希望这篇文章能将纷纷繁杂的内容串起来,形成一个关于分布式系统的结构性的思路。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

新兴AI民工

码字不易,各位看客随意

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值