使用Spark History Server查看Spark作业信息

Spark应用程序在运行期间会向外提供Web UI服务用于可视化作业信息,例如Stage和Task的详细信息、内存使用情况等。为了能够在作业执行结束后查看作业执行情况,您需要将Spark作业日志持久化到某一后端存储中,并通过ack-spark-history-server组件去解析该日志并渲染成Web UI对外提供服务。本文将介绍如何在ACK集群中使用Spark History Server查看Spark作业的运行情况。

前提条件

步骤一:部署ack-spark-history-server组件

  1. 登录容器服务管理控制台,在左侧导航栏选择市场 > 应用市场

  2. 应用市场页面,单击应用目录页签,搜索并选中ack-spark-history-server

  3. ack-spark-history-server页面,单击一键部署

  4. 创建面板中,选择集群和命名空间,然后单击下一步

  5. 参数配置页面,设置相应参数,然后单击确定

    以下是关于日志存储、环境变量和Service配置参数的说明。您可以根据需求自定义参数配置。您可以在ack-spark-history-server页面中的配置项查看全量配置项说明。

    说明

    在部署ack-spark-history-server组件时需要指定一个日志存储后端,例如阿里云OSS、PVC或HDFS等。

    • (必选)配置日志存储后端

      在配置日志存储后端时,您可以选择阿里云OSS、PVC或HDFS等选项。以下为各存储后端的配置说明。

      使用OSS作为存储后端

      当使用OSS作为日志存储后端时,需要设置如下参数。

      重要

      Spark作业在写入日志时,需要等待作业执行结束后才可以上传,因此无法实时查看正在运行的作业日志,只能查看已完成作业的日志。

      参数

      描述

      示例值

      spark.history.fs.logDirectory

      日志目录的URL。确保在部署组件之前,日志目录已创建,例如spark/spark-events。关于如何创建目录请参见管理目录

      oss://<Bucket name>/spark/spark-events

      storage.oss.enable

      启用阿里云对象存储服务(OSS、OSS-HDFS)作为日志存储后端。

      true

      storage.oss.endpoint

      阿里云OSS访问端点。

      oss-cn-beijing-internal.aliyuncs.com

      storage.oss.existingSecret

      (推荐)已拥有读取OSS访问凭证的Secret名称。关于如何创建OSS访问凭证的Secret YAML,请参见OSS访问凭证Secret YAML示例

      spark-oss-secret

      storage.oss.createSecret

      如果没有指定已有的Secret,将自动创建一个用于存储OSS访问凭证的Secret。

      不涉及。

      storage.oss.createSecret.accessKeyId

      阿里云AccessKey ID。

      LTAIXXXXXXXXXXXXXXCuMnk

      storage.oss.createSecret.accessKeySecret

      阿里云AccessKey Secret。

      ViuXXXXXXXXXXXXXv15yVKkGj0J

      OSS访问凭证Secret YAML示例

      确保Secret中包含OSS_ACCESS_KEY_IDOSS_ACCESS_KEY_SECRET两个字段。

      1. 使用以下内容创建spark-oss-secret.yaml。

        apiVersion: v1
        kind: Secret
        metadata:
          name: spark-oss-secret
          namespace: spark-operator
        stringData:
          OSS_ACCESS_KEY_ID: ""       # 阿里云AccessKey ID。
          OSS_ACCESS_KEY_SECRET: ""   # 阿里云AccessKey Secret。
      2. 执行以下命令以创建OSS访问凭证Secret。

        kubectl apply -f spark-oss-secret.yaml

      使用PVC作为存储后端

      使用PVC作为日志存储后端时,需要设置如下参数。

      参数

      描述

      示例值

      spark.history.fs.logDirectory

      日志目录的URL。

      file:///mnt/spark/spark-events

      storage.pvc.enable

      启用PVC作为日志存储后端。

      true

      storage.pvc.name

      已经存在的PVC名称。确保在ack-spark-history-server需要的命名空间中提前创建好PV和PVC,并成功绑定。关于如何创建并绑定PVC请参见存储-CSI

      "<PVC name>"

      storage.pvc.mountPath

      PVC在容器中的挂载路径。

      "/mnt"

      使用HDFS作为存储后端

      使用HDFS作为存储后端时,需要设置如下参数。

      参数

      描述

      示例值

      spark.history.fs.logDirectory

      日志目录的URL。

      hdfs://namenode:port/spark/spark-events

    • (可选)配置Service类型和端口

      默认会创建一个Service资源用于暴露History Server的Web UI,可以通过service.typeservice.port参数配置Service的类型和端口号。

      参数

      描述

      默认值

      service.type

      选择Service类型。取值:

      • ClusterIP

      • NodePort

      • LoadBalancer

      ClusterIP

      service.port

      Web UI访问端口号。

      18080

    • (可选)配置环境变量

      您可以在env参数中添加环境变量,对History Server进行配置。

      环境变量

      描述

      默认值

      SPARK_DAEMON_MEMORY

      分配给History Server的内存大小。

      1g

      SPARK_DAEMON_JAVA_OPTS

      History Server JVM配置项。

      ""

      SPARK_DAEMON_CLASSPATH

      History Server类路径。

      ""

      SPARK_PUBLIC_DNS

      History Server的外网地址。如果没有设置历史服务器的外网地址,应用历史将默认使用内部地址,这可能导致链接失效。

      ""

      SPARK_HISTORY_OPTS

      一组spark.history.*配置项。

      ""

      您可以在sparkConf参数中添加配置,来设置History Server。常用配置项如下。

      属性名称

      描述

      默认值

      spark.history.fs.update.interval

      检测日志更新的时间间隔。

      10s

      spark.history.fs.retainedApplications

      缓存UI数据的应用最大数量。

      50

      spark.history.ui.port

      History Server端口号。

      18080

      spark.history.fs.cleaner.enabled

      是否周期性地清理事件日志。

      false

      spark.history.fs.cleaner.interval

      spark.history.fs.cleaner.enabled=true 时,指定清理事件日志的时间间隔。

      1d

      spark.history.fs.cleaner.maxAge

      spark.history.fs.cleaner.enabled=true时,清理日志文件时会删除存活时间超过该阈值的日志。

      7d

      spark.history.fs.cleaner.maxNum

      spark.history.fs.cleaner.enabled=true时,设置保留的日志文件数量的最大值,超过该阈值的日志文件将在清理触发时被删除。

      Int.MaxValue

      spark.history.fs.driverlog.cleaner.enabled

      是否周期性地清理Driver事件日志。

      spark.history.fs.cleaner.enabled

      spark.history.fs.driverlog.cleaner.interval

      spark.history.fs.driverlog.cleaner.enabled=true 时,指定清理Driver事件日志的时间间隔。

      spark.history.fs.cleaner.interval

      spark.history.fs.driverlog.cleaner.maxAge

      spark.history.fs.driverlog.cleaner.enabled=true时,清理Driver事件日志时会删除存活时间超过该阈值的日志。

      spark.history.fs.cleaner.maxAge

      spark.history.fs.numReplayThreads

      处理日志文件时创建的线程数量。

      25%的可用CPU核数。

      spark.history.store.maxDiskUsage

      应用历史缓存所能使用的磁盘大小上限。

      10g

步骤二:访问Spark History Server Web UI

在默认配置中,Service的类型为ClusterIP。访问Spark History Server的Web UI,需要将其服务转发到本地的18080端口。您可以参见以下方式进行配置。如果您需要使用已有的负载均衡实例进行访问,请参见通过使用已有负载均衡的服务暴露应用

重要

通过kubectl port-forward命令建立的端口转发仅适用于测试环境下的快速验证,不适合在生产环境中使用,使用时请注意安全风险。

  1. 执行以下命令,配置本地端口转发。

    RELEASE_NAME=spark-history-server
    RELEASE_NAMESPACE=spark-operator
    
    SERVICE_NAME=${RELEASE_NAME}-service
    SERVICE_PORT=$(kubectl get service ${SERVICE_NAME} --namespace ${RELEASE_NAMESPACE} -o jsonpath="{.spec.ports[0].port}")
    
    echo "Now you can go to http://127.0.0.1:18080 to visit spark history server."
    kubectl plort-forward --namespace ${RELEASE_NAMESPACE} services/${SERVICE_NAME} 18080:${SERVICE_PORT}

    预期输出:

    Now you can go to http://127.0.0.1:18080 to visit spark history server.
    Forwarding from 127.0.0.1:18080 -> 18080
    Forwarding from [::1]:18080 -> 18080
  2. 浏览器中访问http://127.0.0.1:18080,查看Spark History Server Web UI。

    image

步骤三:在Spark作业启用日志记录

部署ack-spark-history-server组件后,还需在Spark作业中启用事件日志记录功能。请配置以下两个参数,以启用并存储Spark作业的事件日志。

参数

描述

示例值

spark.eventLog.enabled

启用事件日志记录。取值:

  • true

  • false

true

spark.eventLog.dir

事件日志存储路径。取值:

  • oss://<Bucket name>/spark/spark-events(OSS路径)

  • hdfs://namenode:port/spark/spark-events(HDFS路径)

  • file:///tmp/spark/spark-events(本地路径)

oss://<Bucket name>/spark/spark-events

示例场景:在Spark作业中配置OSS日志记录

以下是将OSS作为存储后端进行日志记录配置的详细步骤。

  1. 构建Spark容器镜像

    由于社区的Spark容器镜像不包含访问OSS所需的相关JAR包,您需要自行构建Spark容器镜像,将Hadoop OSS SDK的相关JAR包添加到镜像中。以下是一个Dockerfile示例。关于容器镜像服务构建镜像请参见使用企业版实例构建镜像。根据Dockerfile构建镜像并推送至您自己的镜像仓库,注意调整Spark对应的Hadoop版本的依赖JAR包。

    ARG SPARK_IMAGE=registry-cn-hangzhou.ack.aliyuncs.com/dev/spark:3.5.2
    
    FROM ${SPARK_IMAGE}
    
    # Add dependency for Hadoop Aliyun OSS support
    ADD --chmod=644 https://repo1.maven.org/maven2/org/apache/hadoop/hadoop-aliyun/3.3.4/hadoop-aliyun-3.3.4.jar ${SPARK_HOME}/jars
    ADD --chmod=644 https://repo1.maven.org/maven2/com/aliyun/oss/aliyun-sdk-oss/3.17.4/aliyun-sdk-oss-3.17.4.jar ${SPARK_HOME}/jars
    ADD --chmod=644 https://repo1.maven.org/maven2/org/jdom/jdom2/2.0.6.1/jdom2-2.0.6.1.jar ${SPARK_HOME}/jars
  2. 创建Secret

    在Spark作业的命名空间中,您需要创建一个Secret来存储OSS访问凭证。

    1. 创建如下Secret清单文件spark-oss-secret.yaml,用于存储OSS访问凭据。

      apiVersion: v1
      kind: Secret
      metadata:
        name: spark-oss-secret
        namespace: default
      stringData:
        # 阿里云AccessKey ID
        OSS_ACCESS_KEY_ID: ""
        # 阿里云AccessKey Secret
        OSS_ACCESS_KEY_SECRET: ""
    2. 执行以下命令,创建一个Secret资源。

      kubectl apply -f spark-oss-secret.yaml

      预期输出:

      secret/spark-oss-secret created
  3. 提交Spark作业

    以下是一个SparkApplication示例,启用了事件日志记录功能。您需要根据具体情况修改以下参数:

    参数

    描述

    示例值

    image

    已构建Spark容器镜像的镜像地址。

    registry-cn-hangzhou.ack.aliyuncs.com/ack-demo/spark:3.5.2-oss

    fs.oss.endpoint

    阿里云OSS访问端点。

    oss-cn-beijing-internal.aliyuncs.com

    spark.eventLog.dir

    日志存放路径。确保指定的日志存放路径已提前创建,否则作业将在运行时出现错误。

    oss://<Bucket name>/spark/spark-events

    1. 创建如下SparkApplication清单文件,并保存为spark-pi.yaml

      apiVersion: sparkoperator.k8s.io/v1beta2
      kind: SparkApplication
      metadata:
        name: spark-pi-oss
        namespace: default
      spec:
        type: Scala
        mode: cluster
        image: registry-cn-hangzhou.ack.aliyuncs.com/ack-demo/spark:3.5.2-oss
        mainApplicationFile: local:///opt/spark/examples/jars/spark-examples_2.12-3.5.2.jar
        mainClass: org.apache.spark.examples.SparkPi
        sparkVersion: 3.5.2
        hadoopConf:
          fs.AbstractFileSystem.oss.impl: org.apache.hadoop.fs.aliyun.oss.OSS
          fs.oss.impl: org.apache.hadoop.fs.aliyun.oss.AliyunOSSFileSystem
          # OSS访问端点
          fs.oss.endpoint: oss-cn-beijing-internal.aliyuncs.com
          fs.oss.credentials.provider: com.aliyun.oss.common.auth.EnvironmentVariableCredentialsProvider
        sparkConf:
          spark.eventLog.enabled: "true"
          # 日志存放路径
          spark.eventLog.dir: oss://<Bucket name>/spark/spark-events
        driver:
          cores: 1
          coreLimit: 1200m
          memory: 512m
          serviceAccount: spark-operator-spark
          envFrom:
          - secretRef:
              name: spark-oss-secret
        executor:
          instances: 1
          cores: 1
          coreLimit: 1200m
          memory: 512m
          envFrom:
          - secretRef:
              name: spark-oss-secret
        restartPolicy:
          type: Never
    2. 执行以下命令,提交Spark作业。在完成镜像制作和SECRET创建后,您可以在浏览器中访问http://127.0.0.1:18080查看Spark作业情况。

      kubectl apply -f spark-pi.yaml

      预期输出:

      sparkapplication.sparkoperator.k8s.io/spark-pi created