Fork me on GitHub

MapReduce排序过程详解

Hadoop、Spark等分布式数据处理框架在宣传自己的性能时大都以排序效果来做比较,各种类别的Sort Benchmark已成为行业基准测试。之所以选择排序是因为排序的核心是shuffle操作,数据的传输会横跨集群中所有主机,Shuffle基本支持了所有的分布式数据处理负载。

下面就来详细分析一下使用mapreduce实现排序的基本过程。先看一些准备知识。

MapReduce中的数据流动

  • 最简单的过程: map - reduce
  • 定制了partitioner以将map的结果送往指定reducer的过程: map - partition - reduce
  • 增加了在本地先进行一次reduce(优化)的过程: map - combine - partition - reduce

Partition的概念和使用

得到map产生的记录后,他们该分配给哪些reducer来处理呢?hadoop默认是根据散列值来派发,但是实际中,这并不能很高效或者按照我们要求的去执行任务。例如,经过partition处理后,一个节点的reducer分配到了20条记录,另一个却分配到了10W万条,试想,这种情况效率如何。又或者,我们想要处理后得到的文件按照一定的规律进行输出,假设有两个reducer,我们想要最终结果中part-00000中存储的是”h”开头的记录的结果,part-00001中存储其他开头的结果,这些默认的partitioner是做不到的。所以需要我们自己定制partition来选择reducer。自定义partitioner很简单,只要自定义一个类,并且继承Partitioner类,重写其getPartition方法就好了,在使用的时候通过调用Job的setPartitionerClass指定一下即可。

Promise之回调金字塔篇

学习Node.js已经两周了,之前一直比较迷惑promise的使用,现在终于有所理解。这篇文章将主要以解决回调金字塔的角度来看待promise,至于控制权转换以及LEGO等更深入的角度将在后续文章中剖析。通过这篇文章将基本理解promise的用法。

什么是promise

promise是JavaScript实现优雅编程的一个非常不错的轻量级框架。该框架可以让你从杂乱的多重异步回调代码中解脱出来,并把精力集中到你的业务逻辑上。

promise是为解决问题而生的,先看看下面这段代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
function main(data, cb){
fun1(data, function(err, data){
if(!err){
fun2(data, function(err, data){
if(!err){
fun3(data, cb);
}else{
cb(err);
}
});
}else{
cb(err);
}
});
}