Spark的计算的基本单位一个一个的算子,其计算流程也是由一个个基本的算子构成的,这些算子之间的依赖关系可以分为宽依赖和窄依赖。

Spark是分布式计算,其数据也是分布式的,即所计算的数据可能分为好多个块。有些计算对数据的操作相对简单,即某一块儿的数据处理不需要涉及到其他块的数据,就是对本块数据处理完可以直接输出到下一个数据块,中间不需要更多的过程参与。比如map()算子,本身就是对每个数据进行循环处理,一条数据基本上对应一条输出结果,继而一个数据块儿也是对应的输出一个数据块儿。即父数据块的结果只输出到一个子数据块儿中,这就是所说的窄依赖。如下图所示:

spark依赖包和Java版本 spark 窄依赖_数据

上面三个图中,可以看到父块的数据经过算子处理后都输出到了唯一的子块儿,每一个父块儿数据的产生不需要和其他父块儿的数据进行运算和操作,直接输出到子块儿中。像上图中的map,filter,union都是窄依赖操作的算子,foreach也是,只不过他不会产生下一个rdd,即没有返回值。而join操作可能是窄依赖,就需要看这个join对数据的操作符不符合上面所说的现象,否则就不是窄依赖。

上面说了窄依赖,与其对应的就是宽依赖。宽依赖中,父数据块中的数据会经过处理后会输出到多个子数据块儿,如下图所示:

spark依赖包和Java版本 spark 窄依赖_数据_02

一个父块儿对应多个子块儿的输出,举个例子:假设有两个数据块,一个数据块中有(one,tow)两个单词,两外一个数据块儿中有(one,tow)两个单词,现在我们需要对这两个块儿的数据进行groupByKey的操作,那么数据的输出结果是两个数据块,one一个,two一个。这个可以看到每个父块儿都需要把自己的数据输出到不同的子块儿之中,这就是宽依赖。

其实更进一步说,宽依赖的实质,就是发生了shffule操作,计算过程中,需要将不同数据块儿的数据先综合一下,进行相关的计算之后,然后再输出到对应的数据块儿中。

以上是本人对宽窄依赖的理解,不对之处还请指出。