《Spark 常见问题排查》

《Spark 常见问题排查》

本文汇总 Spark(含 Structured Streaming / Spark Streaming)使用过程中的常见报错与排查思路。

1 Task not serializable

在 driver 上初始化了一个变量 x,但在 executor 中使用它,Spark 需要将这个变量序列化后传给 executor;如果对象不可序列化,就会报此错误。

参考:https://databricks.gitbooks.io/databricks-spark-knowledge-base/content/troubleshooting/javaionotserializableexception.html

排查与解决:

  1. 将不可序列化的对象定义在闭包内。
  2. 将所调用的方法改为函数,在高阶函数中使用。
  3. 给无法序列化的类加上 java.io.Serializable 接口。
  4. 通过 jars 注册序列化类。

2 日志写入无权限(Permission denied)

报错示例:

java.io.FileNotFoundException: /home/work/services/spark-env/logs/xxx.log (Permission denied)

原因:文件权限导致程序无法写入日志。

解决:

chmod o+w /home/work/services/spark-env/logs/ chmod o+w /home/work/services/spark-env/logs/xxx.log

3 Offsets out of range with no configured reset policy

报错示例:

org.apache.kafka.clients.consumer.OffsetOutOfRangeException: Offsets out of range with no configured reset policy for partitions: {...}

原因:group.id 上次提交的 offset 已超出 Kafka 保留范围(数据被删除),新程序沿用旧 group 消费导致 offset 越界。

解决:换一个新的 group.id。

相关 issue:https://issues.apache.org/jira/browse/SPARK-19680

4 requirement failed: Failed to get records

报错示例:

java.lang.IllegalArgumentException: requirement failed: Failed to get records for xxx after polling for 30000 at org.apache.spark.streaming.kafka010.CachedKafkaConsumer.get(CachedKafkaConsumer.scala:72)

原因:同上,程序从上次结束的 offset 继续消费,但该位置的数据已被删除。

解决:更换 group.id 后重启程序。

5 com.alibaba.fastjson NullPointerException

原因:JSONObject 中没有某个 key,直接调用 getInteger 等 getter 会抛出空指针。

解决:调用 getter 之前先 containsKey 判断。

if (jsonObj.containsKey("key")) { val v = jsonObj.getInteger("key") }

6 程序处理时间过长

从 Web UI 选择【Streaming】→【Completed Batches】→【Batch Time】,选择一个完成的 batch,即可看到 Output Op Duration。

DStream 上常见 5 种 Output Operation:

  • print()
  • saveAsTextFiles(prefix, [suffix])
  • saveAsObjectFiles(prefix, [suffix])
  • saveAsHadoopFiles(prefix, [suffix])
  • foreachRDD(func)

Output Op Duration 与 Job Duration 的时间差,就是 Output Operation 在 driver 端代码的运行时间,可用于定位耗时集中在 driver 还是 executor。

7 调整日志级别

将 log4j.properties.template 复制为 log4j.properties 并修改根级别,减少干扰日志:

cp ${SPARK_HOME}/conf/log4j.properties.template ${SPARK_HOME}/conf/log4j.properties vi ${SPARK_HOME}/conf/log4j.properties
#log4j.rootCategory=INFO, console log4j.rootCategory=WARN, console

8 历史告警 EventCounter is deprecated

WARNING: org.apache.hadoop.metrics.jvm.EventCounter is deprecated. Please use org.apache.hadoop.log.metrics.EventCounter in all the log4j.properties files.

将 log4j.properties 中的 org.apache.hadoop.metrics.jvm.EventCounter 替换为 org.apache.hadoop.log.metrics.EventCounter 即可消除告警。

阅读 — · 全站 —
🎸 我的歌单 0 首