一、Sort排序详解
val rdd3=rdd2.map(r⇒(r._1._1._1,r._2._1._1,euclidean(r._1._1._2,r._2._1._2)))
val rdd4=rdd3.map(r⇒(r._3,r))
val rdd6=rdd4.sortByKey(false)
var rdd7= rdd3.sortBy(r⇒(r._3),false)
false代表降序
http://blog.csdn.net/jiangpeng59/article/details/52938465
sortBy
(1)用case class
(2)隐式转换
(3)元组排序
二、zip
zip的时候,分区数量必须一致,元素数量也要一致
http://lxw1234.com/archives/2015/07/350.htm
三、笛卡尔积:
1、用两层循环得到矩阵,用list带出循环,将list转换成rdd
public class ReIdAttributesTempRDD implements Serializable {
private int x;
private int y;
private String id1;
private String id2;
private ReIdAttributesTemp reIdAttributesTemp1;
private ReIdAttributesTemp reIdAttributesTemp2;
public ReIdAttributesTempRDD(int x, int y, String id1, String id2, ReIdAttributesTemp reIdAttributesTemp1,
ReIdAttributesTemp reIdAttributesTemp2) {
super();
this.x = x;
this.y = y;
this.id1 = id1;
this.id2 = id2;
this.reIdAttributesTemp1 = reIdAttributesTemp1;
this.reIdAttributesTemp2 = reIdAttributesTemp2;
}
}
2、cartesian
val rdd1 = rdd.map(r ⇒ (r.getTrackletID, r.getFeatureVector)).zipWithIndex()
val caRDD = rdd1.cartesian(rdd1)
得到的就是矩阵,但是这样的话,是没有经过过滤的
四、过滤,用zipWithIndex()添加坐标,利用坐标过滤,得到上三角矩阵
val rdd1 = rdd.map(r ⇒ (r.getTrackletID, r.getFeatureVector)).zipWithIndex()
val caRDD = rdd1.cartesian(rdd1)
val rdd2=caRDD.filter(r⇒r._1 != r._2).filter(r⇒r._1._2<r._2._2)
五、分区
partitions的大小,默认是最好的,否则的话,会有shuffle read的过程,很耗时间,同时,数据量小的时候,必须调节partitions的大小,否则会空跑,Spark 中也有一个优化版的 repartition(),叫作 coalesce()。只有当数据集多次在诸如连接(join)这种基于键的操作中使用时,分区才会有帮助。
https://www.iteblog.com/archives/1368.html
https://www.iteblog.com/archives/1522.html
RDD.partitionBy()可以用来重新分区,用于partition的优化
https://www.safaribooksonline.com/library/view/learning-spark/9781449359034/ch04.html
六、glom
c.glom().collect()
结果是 Array[Array[T]]
1、当分区数量m小于元素个数n时,结果是n/m
2、m>n时,结果依然是m个,只是有的是"",其余的间隔分配
3、在使用时,不能用rddGlom.map和foreach
var rddArr=rddGlom.collect()
// val list: List[Broadcast[Array[ReIdAttributesTemp]]] = List()
for(i <- 0 until rddArr.length){
var arr=rddArr(i)
val broadcastVar = sc.broadcast(arr)
EuDis(rdd,broadcastVar)
// list.+:(broadcastVar)
broadcastVar.unpersist()
// for(j <-0 until arr.length ){
// print(arr(j).getTrackletID+",")
// }
}
http://lxw1234.com/archives/2015/07/343.htm
七、算子
http://lxw1234.com/archives/2015/07/363.htm
八、关闭
在finally中关闭
rdd.unpersist()
sc.stop()
九、foreach和foreachPartition
https://my.oschina.net/dongtianxi/blog/745908
http://blog.csdn.net/u014393917/article/details/50607437
https://my.oschina.net/dongtianxi/blog/745908
十、rdd不收集,在执行foreach和foreachPartition时,不会在driver端打印信息,信息在worker端
十一、union
RDD[(String, Iterable[(String, Double)])]中的Iterable不能union
十二、treeAggregate、treeReduce
http://www.jianshu.com/p/27222830d21a
aggregate 和 treeAggregate 的对比
http://www.cnblogs.com/drawwindows/p/5762392.html
十三、mapPartitions、mapPartitionsWithIndex
mapPartitionsWithIndex函数作用同mapPartitions,不过提供了两个参数,第一个参数为分区的索引。
http://lxw1234.com/archives/2015/07/348.htm
十四、coalesce、repartition
都是用来重新分区
http://lxw1234.com/archives/2015/07/341.htm
十五、persist
缓存操作,比cache更复杂,可以设置缓存的级别
rdd.persist(StorageLevel.MEMORY_AND_DISK)
十六、reduceByKey和groupByKey区别与用法
groupby 是reduce操作
http://blog.csdn.net/zongzhiyuan/article/details/49965021
十七、Cache 和 Checkpoint
https://www.kancloud.cn/kancloud/spark-internals/45239
十八、Spark分区器HashPartitioner和RangePartitioner代码详解
https://www.iteblog.com/archives/1522.html
https://ihainan.gitbooks.io/spark-source-code/content/section1/partitioner.html
十九、flod算子
https://blog.csdn.net/dax1n/article/details/72972583
二十、Spark函数之count、countByKey和countByValue
https://blog.csdn.net/weixin_42181200/article/details/80696369
二十一、collectAsMap:对于一个RDD来说,collectAsMap函数返回所有元素集合,不过该集合是去掉的重复的key的集合,如果元素重该复集合中保留的元素是位置最后的一组
样例:
val pairRDD = sc.parallelize[(Int, Int)](Seq((1, 2), (3, 4), (3, 6)), 2)
scala> val a = pairRDD.collectAsMap()
a: scala.collection.Map[Int,Int] = Map(1 -> 2, 3 -> 6)
2. lookup:对于key-value类型的RDD,该函数可以取出相同的key的value值,组成一个集合seq
样例:
val pairRDD = sc.parallelize[(Int, Int)](Seq((1, 2), (3, 4), (3, 6)), 2)
scala> pairRDD.lookup(3)
res0: Seq[Int] = WrappedArray(4, 6)
二十二、join,sortByKey(范围分区) 和 groupByKey(hash分区),都会利用分区信息,可以加快处理流程,比如join前,把不变的大表用partitionBy()进行分区,这样join的时候,就只会对另一个rdd进行shuffle。注意,partitionBy() 是一个转化操作,因此它的返回值总是一个新的 RDD,但它不会改变原来的 RDD。RDD 一旦创建就无法修改。partitionBy()之后进行persist() ,这样后续使用就不会一次次的进行分区,能够从数据分区中获益的操作有 cogroup()、groupWith()、join()、leftOuterJoin()、rightOuterJoin()、groupByKey()、reduceByKey()、combineByKey() 以及 lookup()
了所有会为生成的结果 RDD 设好分区方式的操作:cogroup()、groupWith()、
join()、lef tOuterJoin()、rightOuterJoin()、groupByKey()、reduceByKey()、combineByKey()、partitionBy()、sort()、mapValues()(如果父 RDD 有分区方式的话)、
flatMapValues()(如果父 RDD 有分区方式的话),以及 filter()(如果父 RDD 有分区方式的话)。其他所有的操作生成的结果都不会存在特定的分区方式。
对于二元操作,输出数据的分区方式取决于父 RDD 的分区方式。默认情况下,结
果会采用哈希分区,分区的数量和操作的并行度一样。不过,如果其中的一个父 RDD 已
经设置过分区方式,那么结果就会采用那种分区方式;如果两个父 RDD 都设置过分区方
式,结果 RDD 会采用第一个父 RDD 的分区方式
二十三、combineByKey
https://blog.csdn.net/t1dmzks/article/details/70249743