RDD是啥
Resilient Distributed Dataset (RDD),弹性分布式数据集,是对不可修改,分区的数据集合的抽象。
RDD is characterized by five main properties:
- A list of partitions
- A function for computing each split
- A list of dependencies on other RDDs
- Optionally, a Partitioner for key-value RDDs (e.g. to say that the RDD is hash-partitioned)
- Optionally, a list of preferred locations to compute each split on (e.g. block locations for an HDFS file)
org.spark.rdd.RDD类方法
RDD是一个抽象类,定义如下
abstract class RDD[T] extends Serializable with Logging
RDD类的public方法大约有80多个(包括不同参数重载的),均在下面列出。
值得注意的是,RDD类中并没有定义xxxByKey形式的方法,这类方法其实是在PairRDDFunctions中定义的,通过隐式转换,键值对形式的RDD(即RDD[(K, V))可以调用PairRDDFunctions中定义的方法。
键值转换操作
filter(f: (T) ⇒ Boolean): RDD[T]
过滤数据,仅留下使得f返回true的元素。
map[U](f: (T) ⇒ U)(implicit arg0: ClassTag[U]): RDD[U]
将一个RDD中的每个数据项,通过map中的函数映射变为一个新的元素。
输入分区与输出分区一对一,即:有多少个输入分区,就有多少个输出分区。
flatMap[U](f: (T) ⇒ TraversableOnce[U])(implicit arg0: ClassTag[U]): RDD[U]
第一步和map一样,最后将所有的输出分区合并成一个。
使用flatMap时候需要注意:
flatMap会将字符串看成是一个字符数组。
mapPartitions[U](f: (Iterator[T]) ⇒ Iterator[U], preservesPartitioning: Boolean = false)(implicit arg0: ClassTag[U]): RDD[U]
该函数和map函数类似,只不过映射函数的参数由RDD中的每一个元素变成了RDD中每一个分区的迭代器。如果在映射的过程中需要频繁创建额外的对象,使用mapPartitions要比map高效的过。
比如,将RDD中的所有数据通过JDBC连接写入数据库,如果使用map函数,可能要为每一个元素都创建一个connection,这样开销很大,如果使用mapPartitions,那么只需要针对每一个分区建立一个connection。
参数preservesPartitioning表示是否保留父RDD的partitioner分区信息。
mapPartitionsWithIndex[U](f: (Int, Iterator[T]) => Iterator[U], preservesPartitioning: Boolean = false)(implicit arg0: ClassTag[U]): RDD[U]
函数作用同mapPartitions,不过提供了两个参数,第一个参数为分区的索引。
keyBy[K](f: (T) ⇒ K): RDD[(K, T)]
通过f函数为每个元素生成一个KEY
sortBy[K](f: (T) ⇒ K, ascending: Boolean = true, numPartitions: Int = this.partitions.length)(implicit ord: Ordering[K], ctag: ClassTag[K]): RDD[T]
通过给定的函数对元素排序
zip[U](other: RDD[U])(implicit arg0: ClassTag[U]): RDD[(T, U)]
与另一个RDD组合成(k,v)对。
zipPartitions[B, V](rdd2: RDD[B], preservesPartitioning: Boolean)(f: (Iterator[T], Iterator[B]) ⇒ Iterator[V])(implicit arg0: ClassTag[B], arg1: ClassTag[V]): RDD[V]