【问题标题】:How to distribute data to worker nodes如何将数据分发到工作节点
【发布时间】:2014-12-18 23:36:02
【问题描述】:

我有一个关于 Apache Spark 以及如何将数据从驱动程序分发到执行程序的一般性问题。 我将带有“scala.io.Source”的文件加载到集合中。然后我将集合与“SparkContext.parallelize”并行化。问题从这里开始 - 当我没有指定分区的数量时,工作人员的数量被用作分区值,任务被发送到节点,我收到建议的任务大小为 100kB 的警告,我的任务大小是例如15MB(60MB 文件/4 个节点)。然后计算以节点上的“OutOfMemory”异常结束。当我并行化到更多分区时(例如 600 个分区 - 每个任务获得 100kB)。计算在工作人员上成功执行,但在驱动程序中经过一段时间后会引发“OutOfMemory”异常。在这种情况下,我可以打开 spark UI 并观察驱动程序的内存在计算过程中是如何缓慢消耗的。看起来驱动程序将所有内容都保存在内存中,并且没有将中间结果存储在磁盘上。

我的问题是:

  • RDD分成多少个分区?
  • 如何“以正确的方式”分发数据?
  • 如何防止内存异常?
  • 有没有办法告诉司机/工人交换?它是一个配置选项还是必须在程序代码中“手动”完成?

谢谢

【问题讨论】:

  • 你能发布代码吗?我听起来好像代码级别有问题。

标签: scala apache-spark


【解决方案1】:
  • 如何“以正确的方式”分发数据?

    您将需要一个分布式文件系统(例如 HDFS)来托管您的文件。这样,每个工作人员都可以并行读取文件的一部分。这将提供比序列化和数据更好的性能。

  • 如何防止内存异常?

    不看代码很难说。大多数操作都会溢出到磁盘。如果我不得不猜测,我会说你使用的是groupByKey

  • RDD分成多少个分区?

    我认为经验法则(最佳并行度)是您的工作可用内核数量的 2-4 倍。正如您所做的那样,您可以牺牲内存使用时间。

  • 有没有办法告诉司机/工人交换?它是一个配置选项还是必须在程序代码中“手动”完成?

    随机溢出行为由属性spark.shuffle.spill 控制。默认情况下是真的(=溢出到磁盘)。

【讨论】:

  • 如果每个worker并行读取一个文件,一旦它被缓存,分区是否会保持这种状态?
猜你喜欢
  • 2019-11-11
  • 1970-01-01
  • 2016-06-15
  • 1970-01-01
  • 2017-07-15
  • 2023-02-12
  • 2021-08-22
  • 1970-01-01
  • 2021-01-29
相关资源
最近更新 更多