分组操作 和 JOIN操作有可能发生数据倾斜
Spark共享变量
计数器 和 广播变量是Spark提供的两个共享变量,提供给不同结点上的RDD函数使用
-
计数器
一个只能增加,用于计数和求和的变量
创建方法是SparkContext.accumulator(v, name),其中v是初始值,name是名称

-
广播变量
一个只读变量,spark把该变量在所有worker结点上都缓存一份,可以实现Map Side Join效果
创建方法是sparkContext.broadcast(变量)
val people_info = sc.parallelize(Array(("1","tom"),("2","rose"))).collectAsMap()
val student_all = sc.parallelize(Array(("1","s1","211"),("1","s2","222"),("1","s3","233"), ("1","s2","244")))
//将需要关联的小表进行广播
val people_bc = sc.broadcast(people_info)
val res = student_all.mapPartitions(iter =>{
//获取小表的数据
val stuMap = people_bc.value
val arrayBuffer = ArrayBuffer[(String,String,String)]()
//做两表的操作
iter.foreach{case (idCard,school,sno) =>{
if(stuMap.contains(idCard)){
arrayBuffer.+= ((idCard, stuMap.getOrElse(idCard,""),school))
}
}}
arrayBuffer.iterator
})
Spark数据倾斜的问题
以统计文件中单词频次为例,单词作为Key,频次作为Value。有单词占用1G空间,有单词占用1K空间,单词出现频次不同,该单词占用内存空间也不等,处理效率也不同。这种现象称为数据倾斜。
分而治之的解决思想
对Key加随机数,两次分组可以解决数据倾斜问题

实现方法:

输出结果

Map Side Join
-
小表 和 大表 Join
小表作为广播变量,分布式集群中每台结点缓存一份。大表根据外键字段从缓存中取出对应数据

实现方法:

-
大表 和 大表JOIN
外键字段通过散列函数,分割成小表,小表之间做JOIN,最后结果合并

695

被折叠的 条评论
为什么被折叠?



