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的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)