spark RDD踩坑全集--不定时更新

一、算子合集

1.常用算子
2.算子的使用限制

某些算子,例如reduceByKey必须是一个[k,v]结构才能使用

解决方法:

封装成tuple格式等

二、RDD与DataFrame之间的转换

三、RDD泛型转换问题

1.RDD[ Iterable[ T ] ] =>RDD[ T ]
场景: 
	对RDD[T] 进行groupBy分组处理后需要还原成RDD[T](实际上应该是Rdd[key,Iterable[T])这里只考虑核心问题
代码:
val rdd:RDD[Iterable[T]]

val transRdd:Rdd[T] = rdd.flatMap(item=>{
	data:Iterable[T].toArray
})
结论:其实很简单,flatMap能够展开内部的数组,合并起来,如果使用map会变成Rdd[Array[T]]
2.RDD[Row]与RDD[ T ]之间的转换
场景:
1.rdd[row]=>rdd[T] 利用spark.sql取得dataFrame以后转换成Rdd,此时的Rdd为Rdd[Row]
2.rdd[T]=>rdd[row] 将RDD[T]利用spark.createTempView注册成视图
1.代码 
val rdd:rdd[row]
val transRdd:Rdd[T] = rdd.map(item=>{
	new T(item.getString(0),item.getInt(1).....,item.getString(item.length-1))
})
2.代码
val rdd:rdd[T]
val transRdd:Rdd[Row] = rdd.map(item=>{
	  Row(item.elem1,item.elem2,......,item.elemN)
})
结论: 直接在map内部构造实例即可

四、将RDD转换成各种集合 (RDD算子中变量修改失效问题)

场景:需要将RDD的数据输出到给其他模块/函数
1.将RDD[T]转换成List[T]
错误演示:
def fun(rdd:Rdd[T]):List[T]={
	val listBuffer = ListBuffer[T]
	
	rdd.foreach(item=>{
		listBuffer.append(item)
	})
 listBuffer.toList
}

错误原因:spark算子内的变量实际上是外部变量的副本,对其修改不能改变外部的变量。其中原理很简单,rdd是分布在多个机器上的,其算子也是如此,普通变量不能简单的在各个机器中同时修改。
正确操作 1:使用累加器

def fun(sparkContext:SparkContext,rdd:Rdd[T]):List[T]={
    //实例化累加器
	val acc = new sparkContext.collectionAccumulator[T]("name")
	
	rdd.foreach(item=>{
		acc.add(item)
		})
	//取出累加器内的值,隐式转换成了List
	acc.value
}
结论:Accumulator是spark中的累加器,顾名思义该变量只能增加,只有driver能获取到Accumulator的值(使用value方法),Task只能对其做增加操作
正确操作 2:使用collect算子

def fun(rdd:Rdd[T]):List[T]={
	rdd.collect().toList()
}
结论:使用collect算子可以将RDD[T]转换成array[T],再将数组转换成List[T],但是collect算子会将数据全部收集到driver端,不适合大量数据的操作。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值