RequestBodyTooLarge 出现在 HDInsight 的 Apache Spark 流式处理应用程序日志中

本文介绍在 Azure HDInsight 群集中使用 Apache Spark 组件时出现的问题的故障排除步骤和可能的解决方案。

问题

Apache Spark 流式处理应用程序日志中会出现以下错误

NativeAzureFileSystem ... RequestBodyTooLarge

java.io.IOException: Operation failed: "The request body is too large and exceeds the maximum permissible limit.", 413, PUT, https://<storage account>.dfs.core.chinacloudapi.cn/<container>/hdp/spark2-events/application_1620341592106_0004_1.inprogress?action=flush&retainUncommittedData=false&position=9238349177&close=false&timeout=90, RequestBodyTooLarge, "The request body is too large and exceeds the maximum permissible limit. RequestId:0259adb6-101f-0041-0660-43f672000000 Time:2021-05-07T16:48:00.2660760Z"
        at org.apache.hadoop.fs.azurebfs.services.AbfsOutputStream.flushWrittenBytesToServiceInternal(AbfsOutputStream.java:362)
        at org.apache.hadoop.fs.azurebfs.services.AbfsOutputStream.flushWrittenBytesToService(AbfsOutputStream.java:337)
        at org.apache.hadoop.fs.azurebfs.services.AbfsOutputStream.flushInternal(AbfsOutputStream.java:272)
        at org.apache.hadoop.fs.azurebfs.services.AbfsOutputStream.hflush(AbfsOutputStream.java:230)
        at org.apache.hadoop.fs.FSDataOutputStream.hflush(FSDataOutputStream.java:134)
        at org.apache.spark.scheduler.EventLoggingListener$$anonfun$logEvent$3.apply(EventLoggingListener.scala:144)
        at org.apache.spark.scheduler.EventLoggingListener$$anonfun$logEvent$3.apply(EventLoggingListener.scala:144)
        at scala.Option.foreach(Option.scala:257)
        at org.apache.spark.scheduler.EventLoggingListener.logEvent(EventLoggingListener.scala:144)

原因

通过 ABFS 驱动程序创建的文件会在 Azure 存储中创建块 Blob。 Spark 事件日志文件可能达到了 WASB 的文件长度限制。 请参阅一个块 blob 最多可以容纳 50,000 个块

在 Spark 2.3 中,每个 Spark 应用会生成一个 Spark 事件日志文件。 在 Spark 流应用运行过程中,其事件日志文件会不断增大。 目前,WASB 上的文件的块大小限制为 50000,默认块大小为 4 MB。 因此在默认配置中,最大文件大小为 195 GB。 但是,Azure 存储已将最大块大小增大至 100 MB,这样就有效地将单个文件的限制提升至 4.75 TB。 有关详细信息,请参阅 Blob 存储可伸缩性和性能目标

解决方法

对于此错误,可以采用四种解决方案:

  • 将块大小增大至最大 100 MB。 在 Ambari UI 中,修改 HDFS 配置属性 fs.azure.write.request.size(或者在 Custom core-site 节中创建该配置)。 将该属性设置为更大的值,例如:33554432。 保存更新的配置并重启受影响的组件。

  • 定期停止并重新提交 Spark 流作业。

  • 使用 HDFS 来存储 Spark 事件日志。 使用 HDFS 存储日志可能会在群集缩放或 Azure 升级期间导致 Spark 事件数据丢失。

    1. 通过 Ambari UI 对 spark.eventlog.dirspark.history.fs.logDirectory 做出更改:

      spark.eventlog.dir = hdfs://mycluster/hdp/spark2-events
      spark.history.fs.logDirectory = "hdfs://mycluster/hdp/spark2-events"
      
    2. 在 HDFS 上创建目录:

      hadoop fs -mkdir -p hdfs://mycluster/hdp/spark2-events
      hadoop fs -chown -R spark:hadoop hdfs://mycluster/hdp
      hadoop fs -chmod -R 777 hdfs://mycluster/hdp/spark2-events
      hadoop fs -chmod -R o+t hdfs://mycluster/hdp/spark2-events
      
    3. 通过 Ambari UI 重启所有受影响的服务。

  • 在 spark-submit 中添加 --conf spark.hadoop.fs.azure.enable.flush=false 以禁用自动刷新

后续步骤

如果你的问题未在本文中列出,或者无法解决问题,请访问以下渠道之一获取更多支持:

  • 如果需要更多帮助,可以从 Azure 门户提交支持请求。 从菜单栏中选择“支持” ,或打开“帮助 + 支持” 中心。