场景
spark-sql跑一个较大的任务,数据落盘时报错:
com.esotericsoftware.kryo.KryoException: Buffer underflow.
Caused by: org.apache.spark.SparkException: Kryo serialization failed: Buffer overflow. Available: 0, required: 53139320. To avoid this, increase spark.kryoserializer.buffer.max value.
at org.apache.spark.serializer.KryoSerializerInstance.serialize(KryoSerializer.scala:350)
at org.apache.spark.executor.Executor$TaskRunner.run(Executor.scala:429)
... 3 more45
探索
override def readObject[T: ClassTag](): T = {
try {
kryo.readClassAndObject(input).asInstanceOf[T]
} catch {
// DeserializationStream uses the EOF exception to indicate stopping condition.
case e: KryoException
if e.getMessage.toLowerCase(Locale.ROOT).contains("buffer underflow") =>
throw new EOFException
}
}
是在将输入流转换成一个样例类时引发的报错,看注释应该是缺失终止符导致的异常。
当我把这个任务切分成两部分跑之后,就不会出现这个报错,猜测可能是因为数据量过大的缘故。spark的worker上的每个excutor的每个core,都有一个kryo的buffer 缓冲区,这个缓冲区默认初始大小是64KB,根据任务需要会提高buffer大小,默认最大可以提高到64m。
根据提示尝试提高最大buffer大小的参数:
--conf spark.kryoserializer.buffer.max=512m
再观察几天看问题会不会复现。
需要注意的是,官方提示spark.kryoserializer.buffer.max参数设定的值必须小于2048M.