Spark中Transformations、Actions

 

解释narrow transformation和wide transformation的区别
掌握map flatmap filter coalesce
列举两种wide transformation
列举Spark pipeline中的4种常见action
Transformations
narrow transformation只在worker node 本地执行操作,不需要重排(shuffle),因而不需要将进行网络数据传输。如下面的map、faltMap、filter和coalesce。
map()
map()会将一个函数应用到RDD中的每一个element或partition,是一种one to one transformation。

def lower(line):
return line.lower()
lower_text_RDD = text_RDD.map(lower)
下图中橘黄色代表worker node,黑色代表partition,每个partition中包含若干element。Spark 以partition为工作单位而非element,这也是Spark和MapReduce的区别之一。每个RDD都会实现compute函数以达到这个目的。compute函数会对迭代器进行复合,不需要保存每次计算的结果。另外,每个worker node将map应用到它们收到的RDD partition上。


flatMap()
flatMap()会先执行map然后flatten(扁平化)输出。map变换对每一条输入进行指定的操作,然后为每一条输入返回一个对象,flatten将所有对象合并为一个对象。
flatMap()会生成一个新的RDD,并且原RDD的RDD partition与新的RDD partition一一对应。
split_words函数以行作为输入,element是行,单词作为输出,element是单词。由于每行含有的单词数不尽相同,右边的黑盒有的厚有的薄。

对每个Partition执行完split_words后,获得words的一维列表,所有单词都只在一个列表中。
def split_words(line):
return line.split()

words_RDD = text_RDD.flatMap(split_words)
words_RDD.collect()

filter()和coalesce()
starts_with_a()是过滤器中的一种,该函数返回布尔真值。如果结果为true,filter会将这个word保留。filter的结果就是过滤后的word组成的列表。
def starts_with_a(word):
return word.lower().startwith("a")
words_RDD.filter(starts_with_a).collect()


filter()过滤后生成的RDD Partition 往往长短不一,这时需要将部分partition合并以提高性能,即coalesce()。coalesce将较小partition的数量。

wide transformation 需要将shuffle数据,所以需要网络传输。如groupByKey()和reduceByKey()。
groupByKey()
groupByKey把element按key进行分组,如下图,将key相同的键值对合并,value变为原value组成的列表。

reduceByKey()
reduceByKey() = groupByKey() + sum(),其中sum()是一种reduce。将groupByKey()结果中的列表相加就是reduceByKey()。

Actions
actions是执行流水线,将最终结果返回到Driver Program,将结果保存到外存等一系列事件的触发器,也是Spark pipeline的最后一步。
collect()
collect会将所有worker node上的结果收集到Driver Program上,然后会传送到我们的python shell上。
take(n)
take(n)会将结果的前n个element拷贝出来。
reduce(func)
使用func将element聚合
saveAsTextFile(filename)
将结果以文本形式存储到本地或HDFS
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

Transformations

Transformation描述
map(func) 通过应用一个函数的所有元素,返回一个新的分布式数据集
filter(func) 通过选择函数返回true的那些元素来形成,返回一个新的数据集
flatMap(func) 与map类似,但每个输入项都可以映射到0个或多个输出项(因此函数应该返回一个序列而不是单个项)
mapPartitions(func) 与map类似,但运行在RDD的每个分区(块),所以函数必须是迭代器Iterator => Iterator,当运行在一个类型T的RDD
mapPartitionsWithIndex(func) 与mapPartitions类似,但也为函数提供一个表示分区索引的整数值,所以函数必须是(Int, Iterator) => Iterator类型当运行在一个类型T的RDD
sample(withReplacement, fraction, seed) 使用给定随机数字生成器的种子,对数据的一小部分进行采样,无论有无替换
union(otherDataset) 返回一个新的数据集,其中包含源数据集和参数中的元素的联合
intersection(otherDataset) 返回一个新的RDD,它包含源数据集和参数中的元素的交集
distinct([numTasks])) 返回一个包含源数据集的不同元素的新数据集
groupByKey([numTasks]) 当调用一个(K, V)对的数据集时,返回一个(K, 可迭代的)对的数据集。注意:如果要对每个键执行聚合(如汇总或平均值),使用简化的方法或聚合键将会获得更好的性能。注意:在默认情况下,输出的并行度取决于父RDD分区的数量,你可以通过一个可选的numTasks参数来设置不同数量的任务。
reduceByKey(func, [numTasks]) 当调用(K, V)的数据集对,返回一个数据集(K, V)对每个键的值在哪里聚合使用给定减少函数func,必须(V, V) => V形似groupByKey,减少任务的数量通过一个可选的第二个参数是可配置的。
aggregateByKey(zeroValue)(seqOp, combOp, [numTasks]) 当调用一个(K, V)对的数据集时,返回一个(K, U)对的数据集,其中每个键的值使用给定的组合函数和一个中立的“零”值进行聚合。允许一个与输入值类型不同的聚合值类型,同时避免不必要的分配。与groupByKey一样,reduce任务的数量是通过可选的第二个参数进行配置的。
sortByKey([ascending], [numTasks]) 当调用一个(K, V)对K实现排序的数据集时,返回一个由按升序或降序排列的(K, V)对的数据集,如布尔提升参数中所指定的那样。
join(otherDataset, [numTasks]) 当调用类型的数据集(K,V)和(K,W)时,返回一个数据集(K,(V,W))对每一个键的所有对元素。外部连接通过左外连接、右外连接与全外连接。
cogroup(otherDataset, [numTasks]) 当调用类型的数据集(K,V)和(K,W)时,返回一个 (K, (Iterable, Iterable)) 元素的数据集。这个操作也称为group分组。
cartesian(otherDataset) 当调用类型T和U的数据集时,返回一个(T,U)对(所有对元素)的数据集。
pipe(command, [envVars]) 通过shell命令对RDD的每个分区进行管道,例如Perl或bash脚本。RDD元素被写入到进程的stdin中,输出到其stdout的输出被作为字符串的RDD返回。
coalesce(numPartitions) 将RDD中的分区数量减少到num分区。在过滤大数据集之后,可以更有效地运行操作。
repartition(numPartitions) 对RDD中的数据进行随机重组,以创建多个或更少的分区,并在它们之间进行平衡。这通常会使网络上的所有数据都被打乱。
repartitionAndSortWithinPartitions(partitioner) 根据给定的分区重新分区RDD,在每个结果分区中,根据它们的键对记录进行排序。这比调用重新分区更有效,然后在每个分区中进行排序,因为它可以将排序推入到洗牌机器中。

Actions

Action描述
reduce(func) 使用函数func聚合数据集的元素(它需要两个参数并返回一个参数)。这个函数应该是可交换的和结合的,这样它就可以在并行计算中得到正确的计算。
collect() 将数据集的所有元素作为驱动程序的数组返回。这通常是在过滤器或其他操作之后才会有用的,这些操作返回一个足够小的数据子集。
count() 返回数据集中的元素数量。
first() 返回数据集的第一个元素(类似于take(1))。
take(n) 返回一个带有数据集的第n个元素的数组。
takeSample(withReplacement, num, [seed]) 返回一个包含数据集的num元素随机样本的数组,不管有没有替换,都可以选择预先指定一个随机数生成器种子。
takeOrdered(n, [ordering]) 返回RDD的前n个元素,使用它们的自然顺序或自定义比较器。
saveAsTextFile(path) 在本地文件系统、HDFS或任何其他hadoop支持的文件系统中,将数据集的元素作为文本文件(或一组文本文件)写入一个给定目录中。Spark将调用每个元素的toString,将其转换为文件中的一行文本。
saveAsSequenceFile(path) (Java and Scala) 在本地文件系统、HDFS或任何其他Hadoop支持的文件系统中,将数据集的元素作为Hadoop序列文件写入给定路径。这可用于实现Hadoop可写接口的键-值对的RDDs。在Scala中,它还可以在可隐式可转换的类型中使用(Spark包含诸如Int、Double、String等基本类型的转换)。
saveAsObjectFile(path) (Java and Scala) 使用Java序列化以简单的格式编写数据集的元素,然后可以使用sparkcontext.objectfile()装载数据。
countByKey() 只有在类型的rdd(K,V)上才可用。返回一个hashmap(K,Int)对每个键的计数。
foreach(func) 在数据集的每个元素上运行一个函数func。这通常是为了一些副作用,比如更新一个累加器或者与外部存储系统进行交互。注意:除了foreach()之外的累计变量之外,修改变量可能导致未定义的行为。请参阅理解闭包,了解更多细节。
posted @ 2018-12-07 13:39  JackSun924  阅读(346)  评论(0编辑  收藏  举报