Spark作业优化设计,保证对预分区数据的窄依赖

Optimal design of Spark job, and ensuring narrow dependencies on pre-partitioned data

假设我有世界上所有国家的 activity 数据(相对而言,每条记录都有一个国家列),我想用每个国家也可用的一些参考数据来丰富它,然后使用这个作为某些 ML 算法的输入。此外,我知道每个连接集(按国家/地区键控和连接)都适合单个执行程序的内存,在国家/地区级别处理此数据并将结果合并以汇总整体输出的最有效方法是什么。

我目前的想法是:

  1. 按国家/地区对两个数据集进行分区和键控,在国家/地区级别加入两个数据集,然后使用纯 Scala 代码(在 map 函数内)处理数据,然后将部分输出转换为数据集以进行最终合并.
  2. 按国家/地区对两个数据集进行分区和键控,在国家/地区级别加入两个数据集,始终坚持数据集并让 Spark 2 优化计算 - 例如受益于高效的数据序列化表示,全阶段代码生成 e.t.c.

其次,对于选项 2),我如何确保在按国家/地区进行初始键控和加入之后,所有后续聚合操作(如 groupBy() e.t.c。具有窄依赖性(因为所有数据都在同一个 'country' 分区中)。我是否只需要在聚合函数中使用的键中包含国家/地区列 - 例如groupBy(国家,key1,key2 ...)?

我会做三件基本的事情:

  • 按国家键分区
  • 使用 mapPartitions 在每个分区基础上转换 Iterables 数据
  • 使用 reduceByKeyaggregateBykey 进行聚合

所有这些应该让您尽可能高效地减少网络随机播放和磁盘I/O,同时您在最后执行写入操作之前完成所有实际工作。