终于找到了问题得关键,发个博文分享一下,
在使用spark得时候,由于使用collect_list函数对庞大得数据进行了行转列处理,spark运行产生了:
Cannot grow BufferHolder by size 134146152 because the size after growing exceeds size limitation 2147483632;
at org.apache.spark.sql.catalyst.expressions.codegen.BufferHolder.grow(BufferHolder)
....
或者是:
Caused by: java.lang.NegativeArraySizeException
org.apache.spark.unsafe.types.UTF8String.concatWs(UTF8String.java:943)
这样得问题,经查询问题原因。
原因
BufferHolder 的最大大小为2147483632字节 (大约 2 GB) 。
如果列值超过此大小,Spark 将返回异常。
使用类似于的聚合时,可能会发生这种情况 collect_list 。
此代码示例在超出最大大小的列值中生成重复值 BufferHolder 。 因此, IllegalArgumentException: Cannot grow BufferHolder 当在笔记本中运行时,它将返回错误。
且造成得另外一种情况是超出这个限制,将会spill the data into disks.(这也是1.1.1版本遇到得问题)
解决方案
必须确保列值不超过2147483632个字节。 这可能需要你调整如何处理笔记本中的数据。
一种方法是将如此庞大行转列字段内容分成若干个缓冲大小不超过限制得文件进行处理。
二 对spark.kryoserializer.buffer.max参数设置,单位兆,一般默认都是几百兆,可以根据资源情况调节,例如设置 --configspark.kryoserializer.buffer.max=2048m
二对限制和资源配置处理,将限制配置进行更高得值调节,即 spark.config spark.worker.memory=max(max根据实际情况自己配置)
可引用 https://docs.microsoft.com/zh-cn/azure/databricks/kb/sql/cannot-grow-bufferholder-exceeds-size