spark重要的几个算子

spark中有几个算子比较重要,开发中不是很常用,但很多算子的底层都是依靠这几个算子实现的,比如CombineByKey,像reduceByKey底层是combineByKey实现的。
首先介绍combineByKey
这个算子 主要需要三个参数,第一个是对每个分区中每个key的第一个值 进行初始化,也就是每个分区内,有多少个key就会执行多少次这个初始化
object CombineByKeyTest01 {
def main(args: Array[String]): Unit = {
val conf=new SparkConf
conf.setMaster("local").setAppName("test")
val sc=new SparkContext(conf)

val rdd1=sc.parallelize(List(("a","2"),("a","3"),("a","4"),("b","3"),("b","4")),2)

rdd1.foreachPartition(f =>{
while(f.hasNext){
print(f.next())
}
})
val rdd2=rdd1.combineByKey(x=>{println("fff=="+x);(x.toInt*2).toString()},(x1:String,x2:String)=>(x1.toInt+x2.toInt).toString(),(s1:String,s2:String)=>(s1.toInt+s2.toInt).toString())

rdd2.foreachPartition(f=>{
while(f.hasNext){
print(f.next())
}
})


sc.stop()
}
第一个分区为(a,2)(a,3),第二个分区为(a,4)(b,3)(b,4)
对于第一个分区 ,首先执行第一步,即(a,4),然后聚合,得出(a,7)
对于第二个分区,首先执行第一步,(a,8),(b,6),(b,4)然后聚合得出(a,8),(b,10)
最后,对所有分区进行聚合,调用第三个参数对于的函数,得出(a,15),(b,10)
接下来介绍Aggregate
这个算子主要是三个参数,第一个参数是初始值,第二个参数进行分区内聚合,第三个参数是对每个分区最后的结果进行聚合
object AggregateTest01 {
def main(args: Array[String]): Unit = {
val conf=new SparkConf
conf.setMaster("local").setAppName("test")
val sc=new SparkContext(conf)

val rdd1=sc.parallelize(List("1","2","3","4","5","6","7"),2)

rdd1.foreachPartition(f =>{
while(f.hasNext){
print(f.next())
}
})
//aggregate操作
val result=rdd1.aggregate("3")(seqOphyj,combOphyj)

println(result)

sc.stop()
}
//每个分区中 每个元素 乘以2 然后相加 进行分区内聚合操作
def seqOphyj(s1:String,s2:String):String={
val ss1=(2*s1.toInt+2*s2.toInt).toString()
ss1
}
//每个分区的结果 与初始值 进行相加操作
def combOphyj(s1:String,s2:String):String={
val ss1=(s1.toInt+s2.toInt).toString()
ss1
}
}
第一个分区为1,2,3 第二个分区为4,5,6,7
对于第一个分区,首先进行第二个函数 即3*2+1*2=8 8*2+2*2=20 20*2+3*2=46
对于第二个分区,首先进行第二个函数, 3*2+4*2=14 14*2+5*2=38 38*2+6*2=88 88*2+7*2=190
然后进行调用第三个函数 3+46+190=239
接下来是AggregateByKey
这个算子基本和Aggregate类似,是对相同key的value进行聚合,但还是有区别的,区别在下面说。
object AggregateByKeyTest01 {
def main(args: Array[String]): Unit = {
val conf=new SparkConf
conf.setMaster("local").setAppName("test")
val sc=new SparkContext(conf)
val rdd1=sc.parallelize(List(("1","2"),("1","3"),("1","4"),("2","3"),("2","4")),2)
rdd1.foreachPartition(f =>{
while(f.hasNext){
print(f.next())
}
})
val rdd2=rdd1.aggregateByKey("2")(seqOphyj, combOphyj)
rdd2.foreachPartition(f =>{
while(f.hasNext){
print(f.next())
}
})
sc.stop()
}
//每个分区中 每个元素 乘以2 然后相加 进行分区内聚合操作
def seqOphyj(s1:String,s2:String):String={
val ss1=(2*s1.toInt+2*s2.toInt).toString()
println("seq="+s1+"&&"+s2+"====="+ss1)
ss1
}
//每个分区的结果 与初始值 进行相加操作
def combOphyj(s1:String,s2:String):String={
val ss1=(s1.toInt+s2.toInt).toString()
println("com="+s1+"&&"+s2+"====="+ss1)
ss1
}
}
第一个分区为(1,2)(1,3),第二个分区为(1,4)(2,3)(2,4)
首先计算第一个分区。对于key1,value为(2*2+2*2)*2+3*2=22
再计算第二个分区,对于key1,value为2*2+4*2=12,对于key2,value为(2*2+3*2)*2+4*2=28
计算第三个方法,为(1,34)(2,28),它与Aggregate的不同点在于第三个函数执行的时候。默认值不参与运算,而aggregate是参与的。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值