Java Spark和common partitionner:由同一个键分区的两个独立引用是否只在连接时加载它们的公共分区?
法国城市数据(会计、企业、工作…)可以方便地按部门划分(Java Spark和common partitionner:由同一个键分区的两个独立引用是否只在连接时加载它们的公共分区?,java,apache-spark,dataset,rdd,partitioning,Java,Apache Spark,Dataset,Rdd,Partitioning,法国城市数据(会计、企业、工作…)可以方便地按部门划分(29=Finistère,33=Gironde等),在我的数据集中,该字段被命名为CodeDepartment 我有很多关于这些城市的企业、会计、税务等方面的参考资料,它们在这些部门分区内按codeCommune排序: enterprises=enterprises.repartition(col(“codedepartment”).sortWithinPartition(“codeCommune”) 然后,我想加入他们进行分析: 我有
29=Finistère
,33=Gironde
等),在我的数据集中,该字段被命名为CodeDepartment
我有很多关于这些城市的企业、会计、税务等方面的参考资料,它们在这些部门分区内按codeCommune
排序:enterprises=enterprises.repartition(col(“codedepartment”).sortWithinPartition(“codeCommune”)
然后,我想加入他们进行分析:
- 我有
主机配置local[12]
- 我想研究菲尼斯特的城市。这意味着ApacheSpark将加载拼花文件的
,以创建内部RDDcities\cities\u部分\u 29
,或者类似的内容,我假设它会这样做cities\u RDD\u 29
但是当连接步骤开始时,即使连接条件是这样的:
enterprises.col(“codecomune”)=cities.col(“codecomune”)
确保Spark仅从
enterprises\enterprises\u零件\u 29
创建内部企业RDDenterprises\u RDD\u 29
就足够了,并且不会尝试在其他零件中搜索吗
enterprises.col(“CodeDepartment”)=cities.col(“CodeDepartment”)
那么,如何为数据集创建这样的分区器呢
enterprises = enterprises.repartition(col("codeCommune"))
cities = cities.repartition(col("codeCommune"))
enterprises.join(cities, col("codeCommune"))
不,这不是个好主意。这将导致35000个分区。在我看来,分区和连接列是两个不同的东西。不必担心很多分区,35K在计算方面是个小数字。推荐了许多小分区,并说Spark在短至200ms的任务中是高效的。这也是我的经验。对于SortMergeJoin,dfs将由Spark按连接列进行分区。您可以通过直接从dfs的源文件通过连接键将dfs加载到分区中来避免混乱。不,我仍然不同意。第一个问题是,将其保存在paquet文件中不仅仅是一场噩梦:35000个城市=35000个文件夹,每个文件夹中都有一个文件:至少十分钟,阅读几分钟。这会适得其反。当主键(相当)是第一个数据集的唯一标识符时,分区不是主键,在第二个数据集中是两到五条记录的键,在第三个数据集中只有一百条记录的键。在写入最终输出之前,您可以将合并到更小数量的分区。如果输出分区的数量>=节点的数量,那么
coalesce
是便宜的,没有进一步的洗牌。我将不得不通过codeDepartment
对它们进行重新分区,否则它毫无意义。不,对不起。我认为这是一个错误的建议。