火花数据集的正确monadic flatMap操作?

时间:2018-04-24 13:49:02

标签: scala apache-spark

我正在寻找具有以下签名的功能:

bind[A, B](f: A => Dataset[B], ds: Dataset[A]): Dataset[A]

火花库里有这样的东西吗? (flatMap遗憾的是需要从ATraversableOnce[B]的映射,这意味着我必须具体化我的数据集,除非我遗漏了某些内容)。 如果没有,那么如何实现这样的功能呢?

2 个答案:

答案 0 :(得分:4)

RDD不是monad。 RDD对象仅对驱动程序有意义,并且对工作程序执行map/flatmap个函数。因此,您无法在地图/平面地图操作中发出RDD

DatasetRDD的外观所以我想这也是不可能的。

答案 1 :(得分:1)

假设您有N个节点,每个节点上有M个内存。 此外,假设f(a)与所有a <- ds的大小大致相同。 您说您希望f(a)成为分布式Dataset。您坚持f返回Dataset的唯一原因是返回的值不适合单个节点的内存,因此

|f(a)| >= M .

同时你假设bind(f, ds)适合记忆,因此

N * M >= ds.size * |f(a)| >= ds.size * M

如果我们取消M,则会说:

N >= ds.size

也就是说,ds中的元素数量必须相对较小(小于计算节点的数量)。这反过来意味着您可以简单地在主节点上收集它,将其映射到数据集,然后获取联合。沿着这些方向的东西(未经测试):

def bind[A, B](f: A => Dataset[B], ds: Dataset[A]): Dataset[A] = {
  ds.collect.map(f).reduce(_ union _)
}

尝试将其变成一般的monad并没有多大意义,因为如果你将Dataset读成&#34;庞大的分布式数据集几乎不适合具有多个节点的大型集群&#34;,那么< / p>

  • ds已经很大了
  • 每个f(a)都很大
  • ds.flatMap(f)对于2的力量是巨大的,不适合记忆

因此,一般bind可以是:

  • 不可能,因为结果不适合记忆。
  • 替换为fold(f: A => TraversableOnce[B]),因为f(a)很小
  • 替换为ds.collect,因为ds很小

你是那个必须做出决定的人,那就是那个小小的&#34;在每个特定情况下。这可能是没有提供通用flatMap(f: A => Dataset[B])的原因:必须在每次调用此类flatMap时做出非平凡的设计决策。