一、RDD.fold和Scala.fold使用之间的差别
1.Scala中fold的使用
val t1=Array(("C++", (1,"1")), ("Java", (2,"2")),("Java", (2,"2")), ("SQL", (3,"3")), ("Python", (4,"4")))
val rst=t1.foldLeft(("",0,""))((sum,obj)=>{
(sum._1+obj._1,sum._2+obj._2._1,sum._3+obj._2._2)
})
使用基本规则:
(1)foldLeft后的值("",0,"")为实际返回值的数据格式类型,及其初始值
(2)返回值格式和集合内数据格式类型不需要相同
(3)函数体内sum表示前一个操作的返回值,obj为当前操作的集合中对象,sum和obj的类型可以不同
(4)函数体内的返回值需要和foldLeft后的返回值数据类型保持一致,用于传递至下一次计算
2.Spark RDD中fold的使用
spark fold源码
def fold(zeroValue : T)(op : scala.Function2[T, T, T]) : T = { /* compiled code */ }
样例代码
@Test
def testForecastTraffic_1(): Unit = {
val t1 = sc.parallelize(List(("C++", (1,"1")), ("Java", (2,"2")),("Java", (2,"2")), ("SQL", (3,"3")), ("Python", (4,"4"))))
val res = t1.fold((",",(0,"")))((sum, info) => {
(sum._1+info._1,(sum._2._1+info._2._1,sum._2._2+info._2._2))
})
println(res)
}
使用基本规则
(1)fold后的类型和Function中的类型要保持一致
二、RDD.groupBy和RDD.groupByKey
(1)对RDD内部元素类型无明确要求,返回值是原始元素完成对象,返回集合类型为Iterable
RDD. groupBy (f:tup=>{K}):RDD[(K,Iterable[(KV)))]
(2)需要RDD里面的元素是(K,V)格式,返回值Key值为K,value值只包含V,不包含K
RDD. groupByKey():RDD[(K,Iterable[V])]
三、RDDa.join(RDDb)、leftOuterJoin、rightOuterJoin、fullOuterJoin
(1)RDDa和RDDb要求都是(K,V)结构
(2)join:返回RDDa和RDDb中,同时含有的key值,如果K值有重复,返回笛卡尔积组合(建议K值唯一),返回值不是Option类
(3)leftOuterJoin以RDDa的Key为主,B的返回值是Option,有匹配的值返回Some(Value),无值返回none
(4)rightOuterJoin以RDDb的Key为主
(5)fullOuterJoin以RDDa,RDDb的Key同时为主,返回值(A,B)都是Option类
四、aggregate使用:分区内先进行汇聚操作,然后分区间的结果进行汇聚操作,需要提供两个函数
def aggregate[U](zeroValue : U)(seqOp : scala.Function2[U, T, U], combOp : scala.Function2[U, U, U])
(1)seqOp:分区内元素操作函数,入参类型为RDD内元素类型T,返回值为最终的结果返回值类型U
(2)combOp:每个分区间的结果进行汇聚的操作函数,入参和返回值均是类型U
(注:seqOp和combOp可以在内部定义成匿名函数,在外部定义,注意序列化)
(3)seqOp和combOp函数定义方法
1、内部定义
val rst = arraysRDDa.aggregate("")((value, elements) => elements + "," + value, (value1, value2) => value2 + "|" + value1)
2、匿名函数实现
val opt=(value: String, element: (Int, Int))=>{
value + "," + element
}
val combine=(a: String, b: String)=>{
a + "|" + b
}
val rst = arraysRDDa.aggregate("")(opt, combine)
3、封装在类(支持序列化)或者对象中(建议使用)
object SparkRDDOptionTest {
//一个分区内元素操作
def seqOP(value: String, element: (Int, Int)): String = {
value + "," + element
}
//分区间元素操作
def combineOP(a: String, b: String): String = {
a + "|" + b
}
aggregateByKey
(1)aggregateByKey和aggregate的差别在于,如果RDD内的元素类型为T=(K,V),aggregate的seq函数输入输出为(U,T)=>U,输入数据类型T为原始元素,能获取Key值K和value值V,而aggregateByKey的seq函数输出输出是(U,V)=>U,只能获取value值V而不能获取key值
五、RDDa.sortBy和RDDa.sortByKey
(1)sortBy和sortByKey都是transform操作,遇到action操作后才会触发操作