Spark应用程序在运行期间会向外提供Web UI服务用于可视化作业信息,例如Stage和Task的详细信息、内存使用情况等。为了能够在作业执行结束后查看作业执行情况,您需要将Spark作业日志持久化到某一后端存储中,并通过ack-spark-history-server组件去解析该日志并渲染成Web UI对外提供服务。本文将介绍如何在ACK集群中使用Spark History Server查看Spark作业的运行情况。
前提条件
已部署ack-spark-operator组件,请参见部署ack-spark-operator组件。
已通过kubectl工具连接集群。具体操作,请参见获取集群KubeConfig并通过kubectl工具连接集群。
步骤一:部署ack-spark-history-server组件
登录容器服务管理控制台,在左侧导航栏选择 。
在应用市场页面,单击应用目录页签,搜索并选中ack-spark-history-server。
在ack-spark-history-server页面,单击一键部署。
在创建面板中,选择集群和命名空间,然后单击下一步。
在参数配置页面,设置相应参数,然后单击确定。
以下是关于日志存储、环境变量和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
使用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.type
和service.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
命令建立的端口转发仅适用于测试环境下的快速验证,不适合在生产环境中使用,使用时请注意安全风险。
执行以下命令,配置本地端口转发。
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
浏览器中访问http://127.0.0.1:18080,查看Spark History Server Web UI。
步骤三:在Spark作业启用日志记录
部署ack-spark-history-server组件后,还需在Spark作业中启用事件日志记录功能。请配置以下两个参数,以启用并存储Spark作业的事件日志。
参数 | 描述 | 示例值 |
| 启用事件日志记录。取值:
|
|
| 事件日志存储路径。取值:
|
|
示例场景:在Spark作业中配置OSS日志记录
以下是将OSS作为存储后端进行日志记录配置的详细步骤。
构建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
创建Secret
在Spark作业的命名空间中,您需要创建一个Secret来存储OSS访问凭证。
创建如下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: ""
执行以下命令,创建一个Secret资源。
kubectl apply -f spark-oss-secret.yaml
预期输出:
secret/spark-oss-secret created
提交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
创建如下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
执行以下命令,提交Spark作业。在完成镜像制作和SECRET创建后,您可以在浏览器中访问http://127.0.0.1:18080查看Spark作业情况。
kubectl apply -f spark-pi.yaml
预期输出:
sparkapplication.sparkoperator.k8s.io/spark-pi created