Apache spark 如何通过增加spark'解决pyspark`org.apache.arrow.vector.util.DalLocationException`错误;什么是记忆?

Apache spark 如何通过增加spark'解决pyspark`org.apache.arrow.vector.util.DalLocationException`错误;什么是记忆?,apache-spark,pyspark,user-defined-functions,apache-arrow,Apache Spark,Pyspark,User Defined Functions,Apache Arrow,我正在pyspark中运行一个作业,在这里我曾经使用过一个。这会导致以下(此处简称)错误: 我相当肯定这是因为pandas UDF接收的其中一个组非常大,如果我减少数据集并删除足够多的行,我可以毫无问题地运行我的UDF。然而,我想用我的原始数据集运行,即使我在一台内存为192.0 GiB的机器上运行这个spark作业,我仍然会得到相同的错误。(192.0 GiB应该足以将整个数据集保存在内存中。) 如何为spark提供足够的内存以运行需要大量内存的UDF? 例如,是否有一些spark配置我错过了

我正在
pyspark
中运行一个作业,在这里我曾经使用过一个。这会导致以下(此处简称)错误:

我相当肯定这是因为pandas UDF接收的其中一个组非常大,如果我减少数据集并删除足够多的行,我可以毫无问题地运行我的UDF。然而,我想用我的原始数据集运行,即使我在一台内存为192.0 GiB的机器上运行这个spark作业,我仍然会得到相同的错误。(192.0 GiB应该足以将整个数据集保存在内存中。)

如何为spark提供足够的内存以运行需要大量内存的UDF?

例如,是否有一些spark配置我错过了,它为ApacheArrow提供了更多内存

更长的错误消息

根据我的理解,在应用函数之前,组的所有数据都会加载到内存中。这可能会导致内存不足异常,尤其是在组大小不一致的情况下。maxRecordsPerBatch的配置不适用于组,由您来确保分组的数据适合可用内存

您可以尝试添加数据,以确保组没有扭曲。请参阅下面的文章,其中讨论了连接的盐渍。同样的概念也可以在这里应用

  • 您是否已尝试将
    --executor memory
    spark submit选项设置为
    180g
    ,以便spark使用所有可用内存
  • 实际上,Spark看起来并不是一个典型的数据倾斜问题。当您的一个数据结构达到Apache Arrow内部限制时,这看起来是一种非常奇怪的情况—缓冲区的大小不能超过Integer.MAX_VALUE字节:。我不确定Arrow是如何工作的,但对我来说,您的一个数据点似乎包含超过4GB的数据

  • Spark的PandasUDF功能使用Arrow framework将Spark数据帧转换为PandasUDF数据帧,此时Arrow内部缓冲区限制仅为2GB,因此您的PandasUDF分组条件不应产生超过2GB的未压缩数据

    df.groupby('id').apply(function)
    
    我是说

    只有在按分区分组的情况下,才能运行pandas UDF方法 大小小于2 GB未压缩

    这是票供你参考


    上述问题似乎在>=0.15版本的pyarrow中得到了解决,只有Spark 3.x使用pyarrow 0.15版本

    箭头0.16已将最大缓冲区分配大小从MaxInteger更改为MaxLong(64位)

    截至2020年7月,上游Spark仍基于箭头0.15

    Netty后备缓冲区仍然不支持此功能。。所以,很可能你仍然会把这个问题作为一个不同的例外

    因此,由于上述限制,到目前为止,这仍然是不可能的

    这可能会在火花侧得到修复 其想法是将GroupedData分批提供给熊猫UDF以解决此问题


    更新:Databricks平台上的PySpark没有此问题。需要DBR7.4+

    这也是我的理解。我的问题是:我能增加Spark的可用内存来容纳我庞大的团队吗?这里的一个假设是,我可用的200GB RAM并非全部由spark使用。这取决于集群的配置。您能否分享集群的详细信息,如执行器数量、执行器内存、内核等?您是否解决过此问题?我也经历了这一点……我相信@artem vovsia是正确的,因为我达到了Apache Arrows的内部限制。所以我“解决”了这个问题(了解它的原因),但这并不是一个简单的解决办法。我必须经历的艰难解决方案就是通过Arrow发送更少的数据。例如,我用字符串将所有列编码为整数和其他破解。
    ---------------------------------------------------------------------------
    Py4JJavaError                             Traceback (most recent call last)
     in 
    ----> 1 device_attack_result.count()
          2 
          3 
          4 
    
    /usr/lib/spark/python/pyspark/sql/dataframe.py in count(self)
        520         2
        521         """
    --> 522         return int(self._jdf.count())
        523 
        524     @ignore_unicode_prefix
    
    /usr/lib/spark/python/lib/py4j-0.10.7-src.zip/py4j/java_gateway.py in __call__(self, *args)
       1255         answer = self.gateway_client.send_command(command)
       1256         return_value = get_return_value(
    -> 1257             answer, self.gateway_client, self.target_id, self.name)
       1258 
       1259         for temp_arg in temp_args:
    
    /usr/lib/spark/python/pyspark/sql/utils.py in deco(*a, **kw)
         61     def deco(*a, **kw):
         62         try:
    ---> 63             return f(*a, **kw)
         64         except py4j.protocol.Py4JJavaError as e:
         65             s = e.java_exception.toString()
    
    /usr/lib/spark/python/lib/py4j-0.10.7-src.zip/py4j/protocol.py in get_return_value(answer, gateway_client, target_id, name)
        326                 raise Py4JJavaError(
        327                     "An error occurred while calling {0}{1}{2}.\n".
    --> 328                     format(target_id, ".", name), value)
        329             else:
        330                 raise Py4JError(
    
    Py4JJavaError: An error occurred while calling o818.count.
    : org.apache.spark.SparkException: Job aborted due to stage failure: Task 102 in stage 27.0 failed 4 times, most recent failure: Lost task 102.3 in stage 27.0 (TID 3235, ip-172-31-111-163.ec2.internal, executor 1): org.apache.arrow.vector.util.OversizedAllocationException: Unable to expand the buffer
    ...
    
    df.groupby('id').apply(function)