RDD提供了两种类型的操作:transformation
和action
- 所有的
transformation
都是采用的懒策略,如果只是将transformation
提交是不会执行计算的,计算只有在action
被提交的时候才被触发。 - action操作:action是得到一个值,或者一个结果(直接将RDD cache到内存中)
常见的转换操作有
Transformation 算子 | 含义 |
---|---|
map(func) | 对原 RDD 中每个元素运用 func 函数,并生成新的 RDD |
filter(func) | 对原 RDD 中每个元素使用func 函数进行过滤,并生成新的 RDD |
flatMap(func) | 与 map 类似,但是每一个输入的 item 被映射成 0 个或多个输出的 items( func 返回类型需要为 Seq ) |
mapPartitions(func) | 与 map 类似,但函数单独在 RDD 的每个分区上运行, func函数的类型为 Iterator<T> => Iterator<U> ,其中 T 是 RDD 的类型,即 RDD[T] |
mapPartitionsWithIndex(func) | 与 mapPartitions 类似,但 func 类型为 (Int, Iterator<T>) => Iterator<U> ,其中第一个参数为分区索引 |
sample(withReplacement, fraction, seed) | 数据采样,有三个可选参数:设置是否放回(withReplacement)、采样的百分比(fraction)、随机数生成器的种子(seed); |
union(otherDataset) | 合并两个 RDD |
intersection(otherDataset) | 求两个 RDD 的交集 |
distinct([numPartitions])) | 去重 |
groupByKey([numPartitions]) | 按照 key 值进行分区,即在一个 (K, V) 对的 dataset 上调用时,返回一个 (K, Iterable<V>) Note: 如果分组是为了在每一个 key 上执行聚合操作(例如,sum 或 average),此时使用 reduceByKey 或 aggregateByKey 性能会更好Note: 默认情况下,并行度取决于父 RDD 的分区数。可以传入 numTasks 参数进行修改。 |
reduceByKey(func, [numPartitions]) | 按照 key 值进行分组,并对分组后的数据执行归约操作。 |
aggregateByKey(zeroValue)(seqOp, combOp, [numPartitions]) | 当调用(K,V)对的数据集时,返回(K,U)对的数据集,其中使用给定的组合函数和 zeroValue 聚合每个键的值。与 groupByKey 类似,reduce 任务的数量可通过第二个参数进行配置。 |
sortByKey([ascending], [numPartitions]) | 按照 key 进行排序,其中的 key 需要实现 Ordered 特质,即可比较 |
join(otherDataset, [numPartitions]) | 在一个 (K, V) 和 (K, W) 类型的 dataset 上调用时,返回一个 (K, (V, W)) pairs 的 dataset,等价于内连接操作。如果想要执行外连接,可以使用 leftOuterJoin , rightOuterJoin 和 fullOuterJoin 等算子。 |
cogroup(otherDataset, [numPartitions]) | 在一个 (K, V) 对的 dataset 上调用时,返回一个 (K, (Iterable<V>, Iterable<W>)) tuples 的 dataset。 |
cartesian(otherDataset) | 在一个 T 和 U 类型的 dataset 上调用时,返回一个 (T, U) 类型的 dataset(即笛卡尔积)。 |
coalesce(numPartitions) | 将 RDD 中的分区数减少为 numPartitions。 |
repartition(numPartitions) | 随机重新调整 RDD 中的数据以创建更多或更少的分区,并在它们之间进行平衡。 |
action算子 | 含义 |
---|---|
reduce(func) | (func)使用函数func执行归约操作 |
collect() | 以一个 array 数组的形式返回 dataset 的所有元素,适用于小结果集。 |
count() | 返回 dataset 中元素的个数。 |
first() | 返回 dataset 中的第一个元素,等价于 take(1)。 |
take(n) | 将数据集中的前 n 个元素作为一个 array 数组返回。 |
takeSample(withReplacement, num, [seed]) | 对一个 dataset 进行随机抽样** |
takeOrdered**(n, [ordering]) | 按自然顺序(natural order)或自定义比较器(custom comparator)排序后返回前 n 个元素。只适用于小结果集,因为所有数据都会被加载到驱动程序的内存中进行排序。 |
saveAsTextFile(path) | 将 dataset 中的元素以文本文件的形式写入本地文件系统、HDFS 或其它 Hadoop 支持的文件系统中。Spark 将对每个元素调用 toString 方法,将元素转换为文本文件中的一行记录。 |
saveAsSequenceFile(path) | 将 dataset 中的元素以 Hadoop SequenceFile 的形式写入到本地文件系统、HDFS 或其它 Hadoop 支持的文件系统中。该操作要求 RDD 中的元素需要实现 Hadoop 的 Writable 接口。对于 Scala 语言而言,它可以将 Spark 中的基本数据类型自动隐式转换为对应 Writable 类型。(目前仅支持 Java and Scala) |
saveAsObjectFile(path) | 使用 Java 序列化后存储,可以使用 SparkContext.objectFile() 进行加载。(目前仅支持 Java and Scala)** |
countByKey**() | 计算每个键出现的次数。 |
foreach(func) | 遍历 RDD 中每个元素,并对其执行fun函数 |
Transformations
map(func)
算子
var listRDD = sc.makeRDD(1 to 10)
listRDD.map((_*2)).foreach(println)
// 输出结果: 2,4,6,8,10,12,14,16,18,20 (这里为了节省篇幅去掉了换行,后文亦同)
filter(func)
算子
var listRDD = sc.makeRDD(1 to 10)
listRDD .filter(_%2==0).foreach(println)
// 输出结果: 2,4,6,8,10(这里为了节省篇幅去掉了换行,后文亦同)
flatMap(func)
flatMap(func)与
map类似,但每一个输入的 item 会被映射成 0 个或多个输出的 items( *func* 返回类型需要为
Seq`)
val list = List(List(1, 2), List(3), List(), List(4, 5))
sc.parallelize(list).flatMap(_.toList).map(_ * 10).foreach(println)
// 输出结果: 10,20,30,40,50(这里为了节省篇幅去掉了换行,后文亦同)
flatmap
流的扁平化,最终输出的数据类型为一维数组Array[String]
。
被分割出来的每个数据都作为同一个数组中的相同类型的元素,最终全部被分割出来的数据都存储于同一个一维数组中。
结论:多行数据被分割后都存储到同一个一维数组Array[String]中。
flatMap
这个算子在日志分析中使用概率非常高,这里进行一下演示:拆分输入的每行数据为单个单词,并赋值为 1,代表出现一次,之后按照单词分组并统计其出现总次数,代码如下:
var list = List("hello scala","hello python")
sc.parallelize(list).flatMap(line=>line.split(" ")).map((_,1)).reduceByKey(_+_).foreach(println)
// 输出结果:(scala,1)(python,1)(hello,2)(这里为了节省篇幅去掉了换行,后文亦同)
mapPartitions(func)
mapPartitions
算子,与 map 类似,但函数单独在 RDD 的每个分区上运行(map函数作用在每一条数据上), func函数的类型为Iterator<T> => Iterator<U>
(其中 T 是 RDD 的类型),即输入和输出都必须是可迭代类型。
val listRdd: RDD[Int] = sc.makeRDD(1 to 10)
//mappartition对一个rdd中所有的分区进行遍历
//优于map算子,减少发到执行器的交互次数
//可能内存溢出
val partitions: RDD[Int] = listRdd.