带有自定义分区程序的Spark RDD(不是PairRDD)

时间:2019-06-28 15:16:32

标签: apache-spark rdd partition

我可以使用自定义pdf("filename.pdf") sink("filename.pdf") print("message") sink() dev.off() 创建Spark RDD(不是PairRDD)吗?我似乎在API中找不到任何允许这样做的东西……Partitioner方法仅适用于partitionBy s

2 个答案:

答案 0 :(得分:0)

AFAIK,您不能,但我的理解为何如下:

Apache Spark读取数据时,会将其视为一种黑匣子*。因此,框架无法在最开始的步骤说“哦,这里有X行,所以我必须将其放入分区1”,在那里它不知道它的内部内容。取而代之的是,框架将使用许多不同的参数,例如分区数,分割大小等,以找出应在每个任务中从给定源读取多少数据(参数将取决于源)。因此,其想法是将大型数据集的较小部分分配给任务(分区),而不是分析每行/行/记录/任何内容,并说出它可以落在何处。即使对于像Apache Kafka这样的本地分区数据源,Spark也可以这样工作,即无需为分区解释数据。 IMO是分布式数据处理框架与分布式数据存储之间的主要区别之一,有时您可以定义自己的分区逻辑,但这仅是因为您正在接收某些特定数据而不是数据的“包”。换句话说,Spark的分区更依赖于数据源分区逻辑,以利用源的并行性进行初始读取。

另一点是,明确的partitionBy也是您的意图。通过这样做,您说的是管道将需要在同一分区上拥有此特定键的所有数据,因此您可以执行聚合操作或任何其他分组操作。

此外,如果您查看org.apache.spark.rdd.RDD#partitioner,您会发现它主要涉及涉及随机播放的操作-这是用户想要的。它不用于分发在计算开始时读取的数据。

因此,总结一下,我将区分2个分区。第一个与数据源有关,在这里您需要使用框架公开的配置属性。第二个是业务逻辑分区器,在将平面RDD转换为成对RDD之后,此处的操作被视为分组操作,因为它表示要使同一分区上的所有相似数据都可以在其上做一些事情(聚合,会话生成,...)

*-并非总是如此。例如,当您将JDBC与Spark SQL一起使用时,可以定义用于分区的列,该列将用作带键的范围分区。但这更多归功于存储(结构化数据)的组织。

答案 1 :(得分:0)

恐怕你做不到。这就是API的设计方式。您需要在记录上放置标签,以便可以说您要将其发送到给定的分区。

除非您在信件上有邮政编码,否则邮递员无法决定需要将其发送到哪个位置。

如果您自然没有RDD中的密钥,则可以使用以下API以编程方式创建它们-

zipWithIndex()
zipWithUniqueId()