手写Google第一代分布式计算框架 MapReduce

6.824 lab1 手写Google第一代分布式计算框架 MapReduce

lab1做了快一个礼拜,从最初的一脸茫然,全然不知道让干什么,到学了一点go的知识后重新看论文整理思路设计代码,现在逐渐对这个框架有了自己的理解,感觉真的是一个很有趣也很让人恶心的过程(java选手初写go的时候简直给我恶心吐了,不过现在感觉go的确是一门非常优秀的语言,嘻嘻嘻),感谢XiyouLinux兴趣小组的小伙伴们,没有他们的陪伴一个人真的很难坚持下去。

以下是正文

-----------------------------------分割线-------------------------------------------

1. MapReduce是个什么东西,会比我的酸奶包子好吃吗?

MapReduce是Google在继2003年发表谷歌分布式文件系统(GFS)论文后,于2004年发布的第二篇重量级的关于分布式的文章,论文中描述的MapReduce是一种分布式并行计算框架,通俗来讲从用户角度看(以下内容中如果没有特别指出那么用户指的就是框架使用者),MapReduce框架是这么一个东西,他给出了以下两个接口供用户使用

map(key,value)
reduce(key,list[value])//此key非彼key 

用户交给程序一个任务,框架从形式上对任务进行大化小后,再通过用户定义的Map函数对任务从内涵上进行拆分,从而产生一系列的键值对作为返回值,这些键值对返回值最终会被框架聚合产生key,list[value]作为Reduce的函数的输入进行处理,处理以后会输出到硬盘上供用户查看,当然怎么聚合,怎么调用map和reduce进行分布式处理,怎样输出用户不需要知道,用户只需要完成这两个接口处理任务得到结果就行了。

以上文字是很抽象的,当然在没有具体的问题情景的情况下去讨论任何问题都是抽象的,所以如果没有看懂也没有关系我们先来看看他到底解决了什么问题。再回看这部分。

2. 我们为什么需要 MapReduce(分布式计算框架) 或者说他解决了哪些问题

2.1先来思考思考这些问题

  1. 什么是分布式
    我对他的定义是:通过将一个巨大的计算或者存储任务拆解分布,通过网络协作多台机器,对被分布了的任务进行处理。(很浅陋简单但是至少能看懂吧)
  2. 为什么要搞分布式
    首先我们之间先可以达到这样一种共识,那就是在数据量比较小的时候,搞什么分布式的东西都是扯淡,单机性能一定是优于多机协作的,只有在单机无法满足需求的情况的下才需要另辟蹊径通过分布式去解决问题,可以说分布式实际上是无奈之举(就是说要是那帮搞硬件的能帮我们搞出无限内存无限计算能力的机器来,根本就不需要我们这些搞软件的去优化,所以这都是他们的错!!!狗头)
  3. 为什么是Google最先搞出了MapRduce而不是我
    很简单因为我没有这个需求,谷歌作为一个全世界通用的搜索引擎,他每天不仅要在互联网上爬取巨量的网页信息,还要将这些信息保存起来,保存起来后还得建立索引还得对内容进行分析,可以肯定的是单机肯定满足不了他的需求,他肯定是要搞分布式的,但是大家知道,我们程序员一般卖的都很贵的,而且我们总喜欢摸鱼导致项目开发周期会很长,Google的那些老板们就很气啊,这些老板里边有一些懂技术的比如说像拉里-佩奇(嗯?佩奇)他明白自己的处境后很快概括出了以下需求
    1. 需要一种具有横向扩展能力的软件,这个横向扩展能力可以被理解为,通过买机器加设备就可以提高服务的性能,而不用靠软件人员去优化
    2. 这个机器最好不要太贵能用就行

佩奇不愧是懂技术的他发现很巧的是分布式构建的系统就具有这样的能力,但是大家也知道,每个程序员都有自己的专长,不是所有的人都会分布式的,于是有没有一种可能那些会分布式的同学可以搞一个东西让别的不会搞分布式的同学也能搞分布式(有点绕哈哈),MapReduce应运而生。

我们讲他是一个框架他屏蔽掉了自身分布式实现的细节,将数据分布存储、数据通信、容错处理等并行计算涉及到的很多系统底层的复杂细节交由系统负责处理,大大减少了软件开发人员的负担。他是怎样进行抽象从而将分布式系统与具体任务相分离的呢

2.2 我们的目标是抽象map reduce

手写Google第一代分布式计算框架 MapReduce_第1张图片

我妈喜欢买这种八宝米回来熬稀饭,这种米是超市里的人搅拌均匀然后拿出来卖的,出于好奇我想看看这东西成本价是多少,要是贵的话就自己买食材回来混合了,于是我就将我妈买的米分成了三堆,一堆给我爸,一堆给姐,一堆给我妈,他们三个人,各自将自己面前的米根据种类(小米,红豆,绿豆,枸杞,百合…)分成了8小堆(partition),三个人就是24堆,我看他们数完以后将这24小堆根据种类合成8小堆(shuffle),我姐通过食材的价格乘以重量算出红豆堆价格之后告诉我红豆堆的价格(返回)我记在本子上(落盘),我妈算小米,我爸算绿豆。。。。我最后根据记录算出这些八宝米各自没混合的话应该卖多少钱(reduce)。最后发现其实价钱差不太多

计算出这个结果凭我一个人肯定是不行的,还好我会分布式我可以叫我家里人过来帮忙,他们也不需要知道整个系统的工作过程是什么,他们(worker)只要

  1. 执行归类拆分(map)八小堆
  2. 执行根据每堆算出价格(reduce)并告知我

我(master)只需要

  1. 从形式上将大堆拆分为三小堆(nMap)
  2. 将24堆混成8堆(nReduce)
  3. 将每堆计算结果写到本子上(落盘)

就这样我们愉快的完成了计算任务。

我的意思是所有具象的事物都可以抽象化,如果必要的话,抽象事物也可以具象化,只要模型建的好,任何具象的问题都可以往抽象的模板上套,一个大任务在形式上或者说在任务量上肯定可以拆分,可是如果问题需要某些特性的聚合才能在一起运算的话,拆分就不是一件无脑的事情,我们就需要先从形式上拆分,让任务先变小,之后再从特性上聚合(Map),聚合之后再拆分,这样才能满足的我们的计算要求(reduce)这就是我们的抽象。

3. MapReduce框架设计思路

现在我们改变视角,不从用户角度考虑,而是思考该框架应该怎样进行设计,我们考虑以下问题

  1. 组成
    1. 需要一个中控Coordinator调度任务
    2. 需要很多个worker执行任务
  2. 执行流程
    1. Coordinator
      1. 启动后根据提供的文件初始化生成mapjob列表
      2. 将DistributeJob方法注册供外界进行rpc调用
      3. 当外界有请求的时候,分发map
      4. 当mapJob分发完以后初始化reducejob列表
      5. 分发reduceJob
    2. work
      1. 请求任务
      2. 判断任务类别(reduce/map)
      3. 告知coorfinator自己完成的任务,并重新申请任务
  3. 可能出现的问题
    1. coordinator挂掉怎么办,没办法,单master,master挂掉系统就崩了
    2. worker挂掉怎么办,重新分配原本属于此worker的任务

4. 代码展现

具体细节放在了这里 https://github.com/nobodyw-cell/labs/tree/main/MIT_6.824/src

5. 可优化的细节以及优化了的细节

  1. 并发处理的不是特别好,用了很多锁,而不是基于go的CSP并发模型,用管道去做
  2. worker告知coordinator自己完成的任务的时候没有告知完成的任务类别,容易引起混乱

你可能感兴趣的:(分布式,hadoop,spark)