繁体   English   中英

PySpark应用程序失败,出现java.lang.OutOfMemoryError:Java堆空间

[英]PySpark application fail with java.lang.OutOfMemoryError: Java heap space

我通过pycharm和pyspark shell运行spark。 我已经堆积了这个错误:

: java.lang.OutOfMemoryError: Java heap space
    at org.apache.spark.api.python.PythonRDD$.readRDDFromFile(PythonRDD.scala:416)
    at org.apache.spark.api.python.PythonRDD.readRDDFromFile(PythonRDD.scala)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at py4j.reflection.MethodInvoker.invoke(MethodInvoker.java:231)
    at py4j.reflection.ReflectionEngine.invoke(ReflectionEngine.java:381)
    at py4j.Gateway.invoke(Gateway.java:259)
    at py4j.commands.AbstractCommand.invokeMethod(AbstractCommand.java:133)
    at py4j.commands.CallCommand.execute(CallCommand.java:79)
    at py4j.GatewayConnection.run(GatewayConnection.java:209)
    at java.lang.Thread.run(Thread.java:748)

我的代码是:

from pyspark import SparkContext, SparkConf
from pyspark.sql import HiveContext
import time

if __name__ == '__main__':

    print("Started at " + time.strftime("%H:%M:%S"))

    conf = (SparkConf()
            .setAppName("TestRdd") \
            .set('spark.driver.cores', '1') \
            .set('spark.executor.cores', '1') \
            .set('spark.driver.memory', '16G') \
            .set('spark.executor.memory', '9G'))
    sc = SparkContext(conf=conf)

    rdd = sc.parallelize(range(1000000000),100)

    print(rdd.take(10))

    print("Finished at " + time.strftime("%H:%M:%S"))

这些是最大内存设置,我可以在群集上设置。 我试图将所有内存分配给1个核心来创建rdd。 但在我看来,应用程序在分发数据集之前失败了。 它无法创建我假设的步骤。 此外,我试图设置各种数量的分区100-10000。 我已经计算了它需要多少内存,所以10亿英寸的内存大约4.5-4.7Gb在内存中,比我少,但没有运气。

如何优化并强制运行我的代码?

TL; DR不要使用parallelize外部测试和简单实验。 因为你使用Python 2.7, range不是懒惰的,所以你将实现多种类型的全范围值:

  • 调用后的Python list
  • 序列化版本,稍后将写入磁盘。
  • 在JVM上加载的序列化副本。

使用xrange会有所帮助,但你不应该首先使用parallelize (或2018年的Python 2)。

如果要创建一系列值,只需使用SparkContext.range

range(start, end=None, step=1, numSlices=None)

从头到尾创建包含元素的新RDD(独占),逐步增加每个元素。 可以像python的内置range()函数一样调用。 如果使用单个参数调用,则该参数将被解释为end,并且start将设置为0。

所以在你的情况下:

rdd = sc.range(1000000000, numSlices=100)

使用DataFrame

from pyspark.sql import SparkSession

spark = SparkSession.builder.getOrCreate()

df = spark.range(1000000000, numPartitions=100)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM