MIT 6.824 Distributed System Lecture 1阅读笔记
导入/Intro
MapReduce是一种从函数式编程中取经、用于分布式系统中数据处理的设计范式。简单来说,MapReduce将对于分布式系统中典型的一种(key,value)式结构(例如SQL)的数据处理抽香味Map和Reduce两个过程:
- Map:输入一对(key,value),映射到一个中间键值对的集合,MapReduce本身会将这个集合里key同为某个\(I\)的中间值聚在一起(总之类似于一个\(\text{Map<K,Set<V>>}\))需要注意的是这里似乎输入输出键值对类型好像要是一样的?不过这不重要,毕竟只是个抽象。
- Reduce:对某个特定的key值\(I\)和对应的value的集合进行合并,输出一个小一点的集合。一般来说Reduce的返回值只有零个或一个元素(例如,sum,max等)
例子
统计一堆文档内每个单词的出现次数
map(key=document name, value=document content):
for word in value:
EmitIntermediate(word, 1) //count the word into the intermediate set
reduce(key=word,values= list of count, i.e. lots of 1):
Emit(sum(values))
分布式grep(linux的正则表达式命令)
map(key=string, value=string content):
for line in string:
if match(line):
Emit(..)
reduce=(_,value=list of mathced command) -> value
实现/Impl
场景
本质上看MapReduce只是一个Interface,资瓷:
- \(\text{Map(K key, V value)} \rightarrow\text{ Map<K, Set<V> >}\)
- \(\text{Reduce(K, Set<V>)}\rightarrow\text{Set<V>}\)
关键在于我们在将模型套用到现实场景落地的用户场景。以当时(Google 2004)的节点情况为例: - dual core x86, 2-4G memory
- 100Mbps~1Gbps互联
- ~数百个运算节点,因此经常会有一些挂掉
- 远程HDD大容量廉价存储
- 用户将任务提交到一个调度系统上,由调度系统进行分配执行
可以看出: - 需要一定容错率
- 传输速率不低
- 存储空间大
- 考虑到04年的水平,各种编程任务实际上占用会很低(?)所以其实内存不小
Google's MapReduce Impl
考虑我们现在有一个巨大的文件作为程序输入:
- 将输入文件分块(文中16M-64M一块),并将程序拷贝到各台电脑上
- 其中有一个Master程序,剩余的是Worker程序,Master程序给Worker分配对应的那一块做Map还是Reduce
- 被分配到Map的Worker Map完后将中间集合放在内存上做缓冲
- 中间集合被写入到远程大容量存储上,写入的位置被分成若干个区(分布式存储),对应的位置被传回master
- 某个被分配到Reduce的Worker使用RPC下载中间集合并按照key做排序(以聚堆),假如中间集合太大(超出内存)将使用external sort
- For each value sets with respect to each keys in intermediate set, 进行Reduce()
- 所有Map和Reduce的活干完之后返回给用户的程序
实际上可以看出,这个MapReduce的Impl在Reduce方面非常直接暴力,也就是说大部分运算在构建Map上,这就很Functional Programming.
Data Structures
没用到什么特别的东西,主要总结一下都存了啥,主要重要的是Master节点,显然需要存:
- 每个map-task和reduce-task的状态(等待、执行中、完成)
- 各Worker的地址
以及文中提到的 - Intermediate Set的存储位置
本文来自博客园,作者:WenDavid552,转载请注明原文链接:https://www.cnblogs.com/wdmath/p/17238565.html