关于scala:Tupled RDD数据的并行化级别

 2022-01-07 

parallelization level of Tupled RDD data

假设我有一个如下类型的 RDD:

1
RDD[(Long, List(Integer))]

我可以假设整个列表都位于同一个工人吗?我想知道某些操作在 RDD 级别是否可以接受还是应该在驱动程序中计算。例如:

1
val data: RDD[(Long, List(Integer))] = someFunction() //creates list for each timeslot

请注意,List 可能是 aggregate 或任何其他操作的结果,不一定是作为一个整体创建的。

1
2
3
4
5
6
val diffFromMax = data.map(item => (item._1, findDiffFromMax(item._2)))

def findDiffFromMax(data: List[Integer]): List[Integer] = {
  val maxItem = data.max
  data.map(item => (maxItem - item))
}

问题是 List 是分布式计算 maxItem 可能会导致大量网络流量。这可以使用以下类型的 RDD 处理:

1
RDD[(Long, Integer /*Max Item*/,List(Integer))]

最大项目是在驱动程序处计算的。

所以问题(实际上是 2 个问题)是:

  • 在 RDD 数据的哪个点我可以假设数据位于一名工人? (参考文档或个人评估的答案会很棒)如果有的话?在 Tuple: ((Long, Integer), Double) 中的 Tuple 的情况下会发生什么?
  • 使用元组设计算法的常见做法是什么?我是否应该始终将数据视为可能出现在不同的工人身上?我应该总是在第一个元组字段将它分解为最小粒度 - 对于在时间段(长)中有用户(字符串)的数据(双)的情况 - 数据应该是(长,(强,双))还是((Long, String), Double) 或者 (String, (Long, Double))?或者这可能不是最优的,矩阵更好?

  • 简短的回答是肯定的,您的列表将位于一个工人中。

    您的元组是 RDD 中的单个记录。单个记录始终位于单个分区(将位于单个工作人员上)。
    当您执行 findDiffFromMax 时,您是在目标 worker 上运行它(因此该函数被序列化为所有要运行的 worker)。

    您应该注意的是,当您生成 (k,v) 元组时,通常这意味着一个键值对,因此您可以在 RDD 上执行基于键的操作。顺序 ((Long, (Strong, Double)) 与 ((Long, String), Double) 或任何其他方式) 并不重要,因为它都是单个记录。唯一重要的是哪个是关键操作的关键,所以问题将是你的计算逻辑