处理大数据集

时间:2016-01-22 07:39:23

标签: apache-spark yarn

当我使用1 GB数据集运行解析代码时,它完成时没有任何错误。但是,当我一次尝试25 GB的数据时,我会遇到错误。我试图了解如何避免失败。很高兴听到任何建议或想法。

不同的错误,

org.apache.spark.shuffle.MetadataFetchFailedException: Missing an output location for shuffle 0

org.apache.spark.shuffle.FetchFailedException: Failed to connect to ip-xxxxxxxx

org.apache.spark.shuffle.FetchFailedException: Error in opening FileSegmentManagedBuffer{file=/mnt/yarn/nm/usercache/xxxx/appcache/application_1450751731124_8446/blockmgr-8a7b17b8-f4c3-45e7-aea8-8b0a7481be55/08/shuffle_0_224_0.data, offset=12329181, length=2104094}

群集详细信息:

  

纱线:8个节点
  总核心数:64
  记忆:500 GB
  Spark版本:1.5

Spark提交声明:

spark-submit --master yarn-cluster \
                        --conf spark.dynamicAllocation.enabled=true \
                        --conf spark.shuffle.service.enabled=true \
                        --executor-memory 4g \
                        --driver-memory 16g \
                        --num-executors 50 \
                        --deploy-mode cluster \
                        --executor-cores 1 \
                        --class my.parser \
                        myparser.jar \
                        -input xxx \
                        -output xxxx \

堆栈跟踪之一:

at org.apache.spark.MapOutputTracker$$anonfun$org$apache$spark$MapOutputTracker$$convertMapStatuses$2.apply(MapOutputTracker.scala:460)
at org.apache.spark.MapOutputTracker$$anonfun$org$apache$spark$MapOutputTracker$$convertMapStatuses$2.apply(MapOutputTracker.scala:456)
at scala.collection.TraversableLike$WithFilter$$anonfun$foreach$1.apply(TraversableLike.scala:772)
at scala.collection.IndexedSeqOptimized$class.foreach(IndexedSeqOptimized.scala:33)
at scala.collection.mutable.ArrayOps$ofRef.foreach(ArrayOps.scala:108)
at scala.collection.TraversableLike$WithFilter.foreach(TraversableLike.scala:771)
at org.apache.spark.MapOutputTracker$.org$apache$spark$MapOutputTracker$$convertMapStatuses(MapOutputTracker.scala:456)
at org.apache.spark.MapOutputTracker.getMapSizesByExecutorId(MapOutputTracker.scala:183)
at org.apache.spark.shuffle.hash.HashShuffleReader.read(HashShuffleReader.scala:47)
at org.apache.spark.rdd.ShuffledRDD.compute(ShuffledRDD.scala:90)
at org.apache.spark.rdd.RDD.computeOrReadCheckpoint(RDD.scala:297)
at org.apache.spark.rdd.RDD.iterator(RDD.scala:264)
at org.apache.spark.rdd.MapPartitionsRDD.compute(MapPartitionsRDD.scala:38)
at org.apache.spark.rdd.RDD.computeOrReadCheckpoint(RDD.scala:297)
at org.apache.spark.rdd.RDD.iterator(RDD.scala:264)
at org.apache.spark.scheduler.ResultTask.runTask(ResultTask.scala:66)
at org.apache.spark.scheduler.Task.run(Task.scala:88)
at org.apache.spark.executor.Executor$TaskRunner.run(Executor.scala:214)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at java.lang.Thread.run(Thread.java:745)

6 个答案:

答案 0 :(得分:74)

此错误几乎可以保证是由执行程序的内存问题引起的。我可以想出几种方法来解决这些类型的问题。

1)您可以尝试使用更多分区(在repartition上执行dataframe)。当一个或多个分区包含的数据多于内存中的数据时,通常会出现内存问题。

2)我注意到您没有明确设置spark.yarn.executor.memoryOverhead,因此默认为max(386, 0.10* executorMemory),在您的情况下为400 MB。这对我来说听起来很低。我会尝试将其增加到1GB(请注意,如果将memoryOverhead增加到1GB,则需要将--executor-memory降低到3GB)

3)查看故障节点上的日志文件。您想查找文本" Killing container"。如果您看到文本"超出物理内存限制",根据我的经验,增加memoryOverhead将解决问题。

答案 1 :(得分:7)

除了上面描述的内存和网络配置问题之外,值得注意的是,对于大型表(例如此处有几个TB),org.apache.spark.shuffle.FetchFailedException可能由于超时检索shuffle分区而发生。要解决此问题,您可以设置以下内容:

SET spark.reducer.maxReqsInFlight=1;  -- Only pull one file at a time to use full network bandwidth.
SET spark.shuffle.io.retryWait=60s;  -- Increase the time to wait while retrieving shuffle partitions before retrying. Longer times are necessary for larger files.
SET spark.shuffle.io.maxRetries=10;

答案 2 :(得分:4)

通过将Spark超时spark.network.timeout增加到更大的值(如800),我也获得了一些不错的结果。默认的120秒将导致很多执行程序在负载较重时超时。

答案 3 :(得分:3)

好的,它是一个旧线程,Stackoverflow上有很多答案,但我错过了几天这个错误,我认为分享这个故事可能有所帮助。

实际上有几种方法可以实现。正如Glennie提到的那个很好的答案,这很可能是一个内存问题,所以请确保你有足够的内存用于一切。有容器内存,AM内存,映射内存,减少内存等配置需要注意。阅读this可以帮助您找到合适的配置。您应该自己选择数字,但这里有一些我设置的属性。

<强>纱-site.xml中

<property>
    <name>yarn.nodemanager.resource.memory-mb</name>
    <value>32768</value>
</property>

<property>
    <name>yarn.app.mapreduce.am.resource.mb</name>
    <value>4096</value>
</property>

<property>
    <name>yarn.scheduler.minimum-allocation-mb</name>
    <value>4096</value>
</property>

<强> mapred-site.xml中

<property>
    <name>mapreduce.map.memory.mb</name>
    <value>4096</value>
</property>

<property>
    <name>mapreduce.reduce.memory.mb</name>
    <value>4096</value>
</property>

这些可以解决您可能遇到的其他一些错误,例如PySpark shell在启动时崩溃。但在我的情况下,虽然一些错误消失了(例如MetadataFetchFailed错误),但问题仍然存在。确切的错误是:

  

org.apache.spark.shuffle.FetchFailedException:无法连接   DB-ETA-C / X.X.X.X:34085

在使用从Spark超时到YARN shuffle服务的每个可能的YARN和Spark属性之后,我最终意识到在错误日志中失败的容器正在寻找x.x.x.x本地(内部)运行netstat -tulpn | grep <PORT NUM>时,IP 返回yyyy:34085,其中yyyy是外部 IP地址。它根本不是内存问题,它只是一个网络配置问题。

Spark服务仅绑定到外部接口 ,因为主机名与/etc/hosts中的外部IP相关联。更新/etc/hosts文件后,问题得到解决。

底线: 该错误显然表明某个容器无法到达另一个容器。这通常是由于内存问题导致容器出现故障,但它也可能是一个网络问题,因此如果节点上有多个接口,请特别注意这些问题。

答案 4 :(得分:1)

这两个例外情况应分开讨论。

对于MetadataFetchFailedException,通常发生在一个执行器突然被杀死或终止时,但是该执行器具有一些shuffle输出,然后当另一位执行器尝试获取此shuffle输出的元数据时,就会发生异常。

1)在大多数情况下,这是由于容器因超出内存限制而被Yarn杀死。因此,您需要在日志中再次确认。

2)最常见的解决方法是增加memoryOverhead,默认值为0.1 *执行程序内存。在大多数情况下,这太小了。我建议将其设置为0.2 *执行程序内存。如果您有大量执行程序或运行其他子流程,则需要更大的价值。

对于FetchFailedException,通常发生在托管某些shuffle输出的执行程序太忙或暂时死机时。这可能是由于磁盘IO或网络IO速度慢所致。当您有超过1000位执行者时,这很常见。

1)您需要检查的第一件事是该执行程序是否真的死了。您可以在无效执行列表中确认这一点。然后检查该死执行器上的日志。

2)当您有1000个执行程序时,最坏的情况是一个执行程序可能与其他执行程序最多具有1000个TCP连接,这会获取1000个不同的文件。这可能会很慢。

3)我们可以做的是增加重试时间和连接等待队列。您可以尝试以下配置

--conf spark.blacklist.enabled=true # blacklist bad machine
--conf spark.reducer.maxReqsInFlight=10 # limit concurrent requests from reducer 
--conf spark.shuffle.io.retryWait=10s # increase retry wait
--conf spark.shuffle.io.maxRetries=10 # increase retry times
--conf spark.shuffle.io.backLog=4096 # increase tcp connection wait queue length

答案 5 :(得分:0)

如果所有改组任务均失败,则可能的原因可能是对Netty的依赖冲突。 从spark-core中排除网络依赖对我有用。

       <dependency>
            <groupId>org.apache.spark</groupId>
            <artifactId>spark-core_2.10</artifactId>
            <version>${spark.version}</version>
            <exclusions>
                <exclusion>
                    <groupId>io.netty</groupId>
                    <artifactId>netty-all</artifactId>
                </exclusion>
                <exclusion>
                    <groupId>io.netty</groupId>
                    <artifactId>netty</artifactId>
                </exclusion>
            </exclusions>
        </dependency>