MIT6.824分布式系统课程 翻译&学习笔记(一)介绍 & MapReduce【持续更新中】

说明

本系列文章是对大名鼎鼎的 MIT6.824分布式系统课程 的翻译补充和学习总结,算是自己一边学习一边记录了。

如有疏漏错误,还请指正:)

持续更新ing。。。

翻译&补充

内容

本课程主要涉及应用的基础架构,包括:

  • 存储
  • 通信
  • 计算

终极目标

隐藏分布式复杂性的抽象。
在我们的研究中,还有大量的主题重复出现。

主题:实现

RPC,线程,并发控制。
【多个实验】

主题:性能

目标:可扩展的吞吐量

N倍服务器 -> N倍吞吐量,通过并行的CPU、硬盘、网络。
【图表:用户,应用服务器,存储服务器】
所以承担更多的负载只需要购买更多的机器,而不是花费昂贵的人力成本重新设计。
如果切分任务不需要太多通信成本,则是高效的。

当N增加时扩展变得更难:

负载不均衡,落后者,N中最长的延迟。
无法并行化的代码:初始化,交互。
共享资源造成的瓶颈,比如:网络。

有些性能问题在扩展时并不容易处理

例如:减小单个用户请求的相应时间
例如:所有用户想更新相同的数据
这些问题通常需要更好的设计,而不是更多的机器。
【实验 4】

主题:容错

千级台服务器,大网络 -> 总是会出现部件损坏。
我们希望向应用隐藏这些错误。
我们通常需要:

  • 可用性 —— 应用可以不管错误,继续工作;
  • 可恢复 —— 当错误被修复时,应用可以重新工作。

好主意
机器备份,如果一台服务器宕机,可以再其他机器上执行。
【实验 1, 2, 3】

主题:一致性

通用的基础架构需要明确定义的行为

例如:“Get(k)获得最近一次Put(k,v)的值。”

能够明确定义行为是很困难的!

多个备份机器很难保持一致。
客户端可能会在多步骤执行的中途崩溃。
机器可能会宕机,比如:在执行请求后但回复之前。
网络分区可能会导致活跃的服务器看起来已经死机;脑裂的风险。

一致性和性能不可兼得

强一致性需要通讯,例如:Get()需要检查最近一次的Put()。
大多情况下的设计仅提供弱一致性,用来提高执行效率。例如:Get()不需要检查最近的Put()!对于应用开发程序员很痛苦,但可能是一种好的权衡。

在一致性和性能的权衡上,有很多可行的设计方法!

案例学习:MapReduce

我们将讨论MapReduce(MR),并作为一个案例学习
在6.824的多个主题中是一个良好实现;
巨大的影响力;
重点在实验1。

MapReduce概览

场景

在TB级的数据集上进行多小时的计算,例如:计算搜索用的索引,排序,分析网络结构。
在千级数目的计算机上进行。
没有分布式系统专家来编写应用。

总体目标

对于非专业的程序员操作简单。
程序员只需要通过定义Map和Reduce函数,通常是很短小的面向过程的代码。
MR负责管理、隐藏分布式的所有内容!

MapReduce Job的逻辑视图

输入已经切分为M个文件。
MIT6.824分布式系统课程 翻译&学习笔记(一)介绍 & MapReduce【持续更新中】_第1张图片
MR对每个输入文件调用Map(),产生成(k2,v2)键值对,这是“临时”的数据。每个Map()调用时一个“任务”。
MR收集指定k2的所有临时v2,传递所有键值对到Reduce调用。
最终的输出是来自所有Reduce()的键值对。

示例:单词统计

输入是千级数量的文本文件

Map(k, v)
    split v into words
    for each word w
      emit(w, "1")
  Reduce(k, v)
    emit(len(v))

优势及缺陷

MapReduce易于扩展

N个“worker”计算机可以带来N倍的吞吐量。

  • Map函数可以并行运行,因为它们不需要通信;
  • Reduce函数也是一样。

所以你可以通过购买更多的机器来获得更高的吞吐量。

MapReduce隐藏了许多细节

发送应用代码到服务器;
跟踪已经完成的任务;
从Map到Reduce传递数据;
服务器间的负载均衡;
从失败中恢复。

然而MapReduce也限制了应用可以做的事情

没有通信和状态(除了通过中间临时数据);
没有迭代,没有多阶段的管道;
没有实时处理或流处理。

实现细节

输入和输出都存储在GFS集群文件系统上

MR需要大量并行的输入和输出吞吐量。
GFS以64MB的chunk来切分文件,存储在多个服务器上。Map并行读,Reduce并行写。
GFS还会在2-3台服务器上备份每个文件。
使用GFS对于MapReduce来说是一个巨大的成功。

什么有可能影响到性能?

我们需要考虑下可以优化的地方:CPU?内存?硬盘?网络?
在2004年,作者们受限于网络的容量:

  • MR将什么发送到网络中?Map从GFS读取输入;Reduce读取Map的输出,可能和输入一样大,比如,排序;Reduce向GFS写入输出文件。【图表:服务器,网络交换机的树形图】
  • 在MR中所有节点之间随机调度,一般的网络请求都会通过核心交换机。
  • 论文中的核心交换机:总共100-200 Gb/s;1800台机器,所有每台机器 55 Mb/s。55这个数值是小的,比磁盘或内存的速度还要慢。

今天,网络和核心交换机相对于CPU/硬盘要快得多

一些细节(论文的图表1)

一个master,向worker分发工作并记录进展。

  1. master发送Map任务给worker,直到所有Map完成。Map输出到本地磁盘(中间临时数据);Map通过hash切分输出,每个Reduce任务一个文件。
  2. 在所有Map完成以后,master发送Reduce任务。每个Reduce获取来自所有Map worker的中间临时数据;每个Reduce任务将输出写到GFS上的一个不同文件。
MR如何最小化网络使用?

master试图在GFS服务器上执行Map任务,可以存储自己的输入。所有的机器运行GFS和MR worker,因此输入是从GFS的本地磁盘读取,不是通过网络。
中间临时数据只在网络上传递一次。Map worker写到本地磁盘,Reduce worker直接从所有map worker读取,不是通过GFS。
中间临时数据通过不同的key划分为不同文件。R 的数目比key的数目小很多,大的网络转发会更有效率。

MR是如何获得良好的负载均衡?

如果N-1台服务器在等待1台服务器,是浪费和缓慢的。
但是一些任务可能会比其他的任务需要更久。
解决方案
任务数目大于worker数目。

  • master向已经完成之前任务的worker发送新的任务;
  • 因此没有太大的任务时需要占用所有完成时间的(但愿如此);
  • 所以快服务器可以比慢服务器执行更多的任务,使得所有服务器可以在差不多的时间完成。

容错

如何容错呢?

也就是说,如果worker在执行MR job的途中崩溃了,怎么办?
我们想要对应用开发者完全隐藏失败!

MR需要从头开始重新执行整个job吗?为什么不呢?
MR重新执行失败的Map和Reduce。
假如MR执行Map两次,一个Reduce看见之前执行的结果,另一个Reduce看到第二次执行的结果,怎么办?
只有重新执行输出相同的结果,才可以保证正确。
所以Map和Reduce需要是完全确定性的函数:

  • 它们只依赖于输入参数。
  • 没有状态,没有文件I/O,没有交互,没有其他的通信。

如果你需要运行非函数的map或reduce,怎么办?
worker失败需要整个job重新执行,或者你自己创建同步的全局检查点。

worker崩溃后恢复的细节:

Map worker崩溃
master发现worker很久没有回应ping。
master知道worker上执行的任务,这些任务的之间临时输出已经丢失,需要重新创建;master告诉其他worker重新执行这些任务。
如果reduce已经获得中间临时数据,可以不用重新执行

Reduce worker崩溃
已经完成的任务是ok的 —— 在GFS上存储,有备份。
master在其他worker上重新开始未完成的任务。

其他失败/问题:
如果master发送给两个worker相同的Map任务,怎么办?

或许master是错误地认为其中一个worker已经死掉。
它只会告诉所有Reduce worker其中一个Map worker。

如果master发送给两个worker相同的Reduce任务,怎么办?

它们将会同时写到GFS上相同的输出文件!
原子的GFS重命名操作可以防止文件内容混淆;只有一个完整的文件是可见的。

如果某个worker很慢——“落伍者”?

也许是因为硬件容易出故障。
master对于剩下的最后一小部分任务开启第二个副本。

如果一个worker由于硬件或软件错误,计算出错误的输出,怎么办?

太糟了!MR只能识别CPU和软件的停止错误(fail-stop)

如果master崩溃呢?

现在的情况?

巨大的影响力(Hadoop,Spark等等)。
可能在Google内部不再使用:

  • 被Flume / FlumeJava替代(看 Chambers等人的论文);
  • GFS被Colossus(没有好的论文描述)和BigTable替代。

总结

MapReduce只手将大集群计算发扬光大。

缺点

不是最有效率或者最灵活的。

优点
  • 扩展性良好;
  • 容易编程 —— 错误和数据的移动都是隐藏的。

这些都是在实践中良好的权衡。
我们会在后续课程中看到更多的成功的后继者。

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