import org.apache.spark.rdd.RDD
import org.apache.spark.{HashPartitioner, SparkConf, SparkContext}
class RDDSuanzi {
private[this] def rddBasics: Unit = {
val sparkConf: SparkConf = new SparkConf().setAppName("rdd basics implement")
val sparkContext: SparkContext = SparkContext.getOrCreate(sparkConf)
val rdd: RDD[Int] = sparkContext.parallelize(Array(1, 2, 3, 4, 5, 6))
val rDD: RDD[Int] = sparkContext.makeRDD(Array(4, 5, 6, 7, 8))
val pairRDD: RDD[(String, String)] = sparkContext.makeRDD(Array(("a", "1"), ("b", "2"), ("c", "3"), ("b", "5")))
val collect: Array[Int] = rdd.collect()
/** 以Array集合的形式返回RDD的元素,也可rdd.toArray方法 */
val cacheRDD: RDD[Int] = rdd.cache()
/**把rdd数据缓存到内存中*/
val checkpoint: Unit = rdd.checkpoint() /**把数据缓存到检查点中,调用checkpoint方法之前最后先cache/persist持久化一下,必须反复计算*/
val take: Array[Int] = rdd.take(num = 10)
/** 返回Array集合中[0,num-1]下标的元素 */
val countByValue: collection.Map[Int, Long] = rdd.countByValue()
/** 各元素在RDD中出现的次数 */
rdd.dependencies /**获取RDD的依赖关系*/
val top: Array[Int] = rdd.top(num = 10)
/** 以降序的排序规则返回num个元素 */
val takeOrdered: Array[Int] = rdd.takeOrdered(num = 10)
/** 以升序的排序规则返回num个元素 */
val lookup: Seq[String] = pairRDD.lookup("a")
/** 针对(K,V)类型,给定K,返回对应的V */
rdd.map(row => row.toChar)
/** 一一对应的映射rdd的每个元素 */
rdd.flatMap(row => (1 to row))
/** 将rdd的每个元素进行一对多转换,map函数式对RDD中的每个元素的操作,flatMap也是,但是它多了一步扁平化处理,
* 扁平化就是原来的Tuple或map集合的多元化元素压扁成一元形式 */
/**根据映射函数,对RDD中的元素进行二元计算,返回计算结果。reduce先在各分区中操作,随后进行整合*/
rdd.reduce((a,b) => a+b)
/** 增加分区时设置为true,
* 减少分区时,若为false则不进行shuffle。
* 当减少较少分区时,若为false则在同一个stage中合并分区;
* 当减少较多分区时,若为false则在同一个stage中合并分区,并行度不够影响性能,在此设置为true较好 */
rdd.coalesce(numPartitions = 2, true)
rdd.repartition(numPartitions = 2)
/** 源码中调用coalesce(numPartitions = 2,true) */
rdd.randomSplit(weights = Array(0.8, 0.2), seed = 11L)
/** 根据weights权重将一个RDD切分多个RDD */
val glom: RDD[Array[Int]] = rdd.glom()
/** 将RDD中么个分区中类型为T的元素转换为数组Array[T],这样每个分区只有一个数组元素 */
rdd.union(rDD)
/** 两个RDD中的数据进行合并,但不去重 */
rdd.intersection(rDD)
/** 求两个RDD的数据交集,没有重复数据。一般会有shuffle过程 */
rdd.subtract(rDD)
/** 求差集,结果包含rdd不包含rDD,一般会有shuffle过程 */
rdd.zip(rDD)
/** 将两个RDD组合成K-V形式的RDD,默认两个RDD的partition数量和元素数量相同,否则有异常 */
// rdd.zipPartitions(rDD)
/** 将两个RDD组合成K-V形式的RDD 需要保证两个RDD的partition相同,对两个RDD的元素数据无要求 */
val zipWithIndex: RDD[(Int, Long)] = rdd.zipWithIndex()
/** 将RDD的元素和此元素的ID组合成K-V,需要计算每个分区的开始索引号 */
val zipWithUniqueId: RDD[(Int, Long)] = rDD.zipWithUniqueId()
/** 将RDD的元素和一个唯一ID组合成K-V值 */
val value: RDD[(String, String)] = pairRDD.partitionBy(new HashPartitioner(2))
/** 功能与repartition类似,生成ShuffledRDD */
pairRDD.mapValues(x => x + 1)
/** 对[K,V]的V值进行map操作 */
val collectAsMap: collection.Map[String, String] = pairRDD.collectAsMap()
/** 返回HashMap */
pairRDD.flatMapValues(x => Seq(x, "a"))
/** 对[K,V]的V值进行flatmap操作 */
/*四种K-V类型转换操作:combineByKey、foldByKey、reduceByKey、groupByKey*/
val reduceByKey: RDD[(String, String)] = pairRDD.reduceByKey({ case (x, y) => x + y })
/** 合并具有相同键的值 */
val groupByKey: RDD[(String, Iterable[String])] = pairRDD.groupByKey()
/** 对具有相同键的值进行分组 */
val sortByKey: RDD[(String, String)] = pairRDD.sortByKey()
/** ascending = true 模式为升序排序 */
pairRDD.combineByKey(
(x: String) => (List(x), 1), //createCombiner 组建组合函数
(peo: (List[String], Int), x: String) => (x :: peo._1, peo._2 + 1), //mergeValue 合并值函数
(sex1: (List[String], Int), sex2: (List[String], Int)) => (sex1._1 ::: sex2._1, sex1._2 + sex2._2) //mergeCombiners 合并组合器函数
).foreach(println)
/** 聚合各分区的元素,而每个元素都是二元组,和aggregate类似 */
}
}