场景
spark-sql跑一个较大的任务(几亿条数据),数据落盘时报错:
com.esotericsoftware.kryo.KryoException: Buffer underflow.
探索
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.