Join ApacheSpark:使用不同的分区器连接两个RDD
我有两个带有不同分区器的RDDJoin ApacheSpark:使用不同的分区器连接两个RDD,join,apache-spark,partitioning,shuffle,rdd,Join,Apache Spark,Partitioning,Shuffle,Rdd,我有两个带有不同分区器的RDD case-class-Person(姓名:String,年龄:Int,学校:String) 案例班学校(名称:String,地址:String) rdd1是Person的RDD,我根据该人的年龄对其进行了分区,然后将钥匙转换为学校 val-rdd1:RDD[Person]=rdd1.keyBy(Person=>(Person.age,Person)) .partitionBy(新HashPartitioner(10)) .mapPartitions(个人=> p
case-class-Person(姓名:String,年龄:Int,学校:String)
案例班学校(名称:String,地址:String)
rdd1
是Person
的RDD,我根据该人的年龄
对其进行了分区,然后将钥匙转换为学校
val-rdd1:RDD[Person]=rdd1.keyBy(Person=>(Person.age,Person))
.partitionBy(新HashPartitioner(10))
.mapPartitions(个人=>
persons.map{案例(年龄,人)=>
(个人、学校、个人)
})
rdd2
是学校的RDD,按学校的名称进行分组
val rdd2:RDD[School]=rdd2.groupBy(u.name)
现在,rdd1
是根据人的年龄进行分区的,所以所有年龄相同的人都进入相同的分区。并且,rdd2
根据学校名称进行分区(默认情况下)
我想要rdd1.leftOuterJoin(rdd2)
,这样rdd1
就不会被洗牌,因为rdd1与rdd2相比非常大。另外,我将结果输出到Cassandra,它在age
上进行分区,因此当前对rdd1
的分区将加快以后的编写过程
有没有一种方法可以将两个RDD连接起来,而无需:
1.洗牌rdd1
和
2.广播“rdd2”,因为rdd2
大于可用内存
注意:连接的rdd应该根据年龄进行分区。假设您有两个rdd,rdd1和rdd2,并且希望应用连接操作。如果RDD已分区(已设置分区)。然后调用rdd3=rdd1.join(rdd2)将通过rdd1对rdd3进行分区。rdd3将始终从rdd1(第一个父级,调用联接的父级)获取哈希分区。可能使用签名leftOuterJoin[W](其他:RDD[(K,W)],partitioner:partitioner)
,并且使用与rdd1相同的分区器可能会有所帮助。两者都是不同键上的HashPartitioner
。如何在HashPartitioner
中指定自定义键?它只接受一定数量的分区作为输入。注意:大小为rdd1~100GB,大小为rdd2~10GB。我有15个这样的rdd2,它们必须与rdd1
连接。并且,每个较小的rdd(这里是rdd2)在rdd1中使用不同的键连接。为了避免rdd1的乱序,我已经基于一个固定的键对它进行了分区,这样它就不会被乱序。是的,你是对的。我想不出一个简单的方法来使用HashPartitioner,您考虑过创建自己的Partitioner吗?这并不像看上去那么难。嗨@DanielPaula,是的,我考虑过使用自定义分区器。但问题是,我在api中看到,它必须在RDD的键上定义。我想根据一些其他数据对我的RDD进行自定义分区,这些数据不是关键。