目录
- 功能简介
- 为什么选择 EMR Serverless + DolphinScheduler
- 前置条件
- 全新部署 DolphinScheduler 3.4.2(含 EMR Serverless 插件)
- 从旧版本升级到 3.4.2 以获得 EMR Serverless 能力
- 使用 EMR Serverless Task 提交任务
- IAM 权限配置参考
- 避坑指南(FAQ & Troubleshooting)
1. 功能简介
Apache DolphinScheduler 从 3.4.2 版本起,原生集成了 Amazon EMR Serverless Task 插件(artifact: dolphinscheduler-task-emr-serverless)。该插件允许用户直接在 DolphinScheduler 的 DAG 工作流中,以可视化方式向 EMR Serverless 提交 Spark / Hive 作业,并实现:
- 同步等待:提交后自动每 10 秒轮询 Job Run 状态,直到 SUCCESS / FAILED / CANCELLED 才返回结果给调度引擎,确保 DAG 依赖关系正确传递。
- 日志回显:任务完成后可在 DolphinScheduler UI 中直接查看执行日志,无需跳转到 AWS Console。
- 自动取消:如果在 DolphinScheduler 中 Kill 任务,插件会自动调用 CancelJobRun API 取消正在运行的作业。
- Failover 支持:Worker 节点故障时,新 Worker 可通过 jobRunId 恢复对运行中作业的跟踪。
- 混合调度:同一工作流中可同时编排 EMR on EC2 任务和 EMR Serverless 任务,按需分配不同资源形态。
工作原理:插件在后台使用 aws-java-sdk,将用户填写的 JSON 参数转换为 StartJobRunRequest 对象并通过 StartJobRun API 提交到 AWS,然后通过 GetJobRun API 轮询作业状态直至完成。
注意:EMR (EC2) 和 EMR Serverless 是 两个独立的插件模块(
dolphinscheduler-task-emrvsdolphinscheduler-task-emr-serverless),安装一个不代表另一个也能用。
2. 为什么选择 EMR Serverless + DolphinScheduler
| 对比维度 | EMR on EC2 | EMR Serverless |
|---|---|---|
| 集群管理 | 需要运维长驻集群或手动创建/销毁 | 完全免运维,按需启停 |
| 成本模型 | 按实例小时计费(含空闲时间) | 仅按 vCPU-hour + GB-hour 计费,任务间无空闲浪费 |
| 弹性扩缩 | 依赖 Managed Scaling / Auto Scaling | 自动按需分配资源,秒级扩容 |
| 本地存储 | 需要预配置 EBS | 无需关注,自动提供 |
| 适合场景 | 需要 SSH/长驻交互式/复杂依赖的场景 | ETL 批处理、定时 SQL、Spark 脚本 |
与 DolphinScheduler 结合的价值:
- 利用 DolphinScheduler 的 DAG 编排能力,将分散的 ETL 脚本组织为有序的数据管线
- EMR Serverless 消除集群运维负担,DolphinScheduler 负责调度与监控
- 原生插件封装了异步轮询、状态跟踪、日志获取等复杂逻辑,用户只需填写 JSON 参数
3. 前置条件
| 项目 | 要求 |
|---|---|
| DolphinScheduler 版本 | ≥ 3.4.2 |
| Java | JDK 8 或 JDK 11 |
| 元数据库 | MySQL 8.x 或 PostgreSQL 12+ |
| EC2 实例 | 挂载有 EMR Serverless 相关权限的 IAM Role |
| EMR Serverless | 已创建至少一个 Application(Spark 或 Hive 类型),状态为 STARTED 或 CREATED |
| S3 | 准备好日志桶和脚本文件存储位置 |
| IAM | Job Execution Role(EMR Serverless 任务实际执行时使用的角色) |
4. 全新部署 DolphinScheduler 3.4.2(含 EMR Serverless 插件)
4.1 下载安装包
VERSION=3.4.2
wget https://dlcdn.apache.org/dolphinscheduler/${VERSION}/apache-dolphinscheduler-${VERSION}-bin.tar.gz
tar -xzf apache-dolphinscheduler-${VERSION}-bin.tar.gz
cd apache-dolphinscheduler-${VERSION}-bin
4.2 安装 EMR Serverless Task 插件
官方二进制包 plugins/ 目录默认为空,必须手动安装所需插件:
# 方式一:一次性安装全部插件(需要能访问 Maven Central)
bash bin/install-plugins.sh
# 方式二(推荐):只安装需要的插件,更快更省空间
export JAVA_HOME=/path/to/jdk
# 安装 EMR Serverless 插件
./mvnw dependency:get \
-DgroupId=org.apache.dolphinscheduler \
-DartifactId=dolphinscheduler-task-emr-serverless \
-Dversion=3.4.2 \
-Dclassifier=shade \
-Ddest=plugins/task-plugins/
# 如果同时需要 EMR on EC2 插件
./mvnw dependency:get \
-DgroupId=org.apache.dolphinscheduler \
-DartifactId=dolphinscheduler-task-emr \
-Dversion=3.4.2 \
-Dclassifier=shade \
-Ddest=plugins/task-plugins/
⚠️
dolphinscheduler-task-emr-serverless的 shade 包体积较大(打包了完整的 AWS EMR Serverless SDK)。
4.3 补充 MySQL JDBC 驱动(如使用 MySQL)
官方包因 GPL 许可不内置 MySQL 驱动:
curl -o mysql-connector-j-8.4.0.jar \
https://repo1.maven.org/maven2/com/mysql/mysql-connector-j/8.4.0/mysql-connector-j-8.4.0.jar
# 复制到每个模块的 libs/ 目录
for dir in api-server master-server worker-server alert-server tools; do
cp mysql-connector-j-8.4.0.jar $dir/libs/
done
4.4 配置数据源(MySQL 示例)
修改以下模块的 conf/application.yaml(api-server、master-server、alert-server、tools 四处都要改,worker-server 不连数据库无需修改):
spring:
profiles:
active: mysql # 默认是 postgresql,改为 mysql
# 在 mysql profile 块中配置:
datasource:
url: jdbc:mysql://your-rds-endpoint:3306/dolphinscheduler?useUnicode=true&characterEncoding=UTF-8
username: dolphin_user
password: your-password
driver-class-name: com.mysql.cj.jdbc.Driver
4.5 配置 AWS 凭证
编辑 conf/aws.yaml(默认内容是占位的 MinIO 测试凭证,必须替换)。
注意:
aws.emr段的配置被 EMR on EC2 和 EMR Serverless 两个 Task 插件共享。
# 推荐:EC2 实例挂载 IAM Role 时使用 InstanceProfile
aws:
emr:
credentials.provider.type: InstanceProfileCredentialsProvider
region: us-east-1 # 改为您的实际 Region
如果是非 EC2 环境或需要跨账号,可以使用静态 Key(不推荐生产环境):
aws:
emr:
credentials.provider.type: AWSStaticCredentialsProvider
access.key.id: AKIA...
access.key.secret: your-secret-key
region: us-east-1
4.6 配置 Tenant
编辑 worker-server/conf/application.yaml:
tenant-config:
auto-create-tenant-enabled: true
default-tenant-enabled: true # 默认是 false,建议改为 true
4.7 初始化数据库并启动
# 初始化 schema
bash tools/bin/upgrade-schema.sh
# 启动全部服务
bash bin/start-all.sh
# 或逐个启动:
bash api-server/bin/start.sh
bash master-server/bin/start.sh
bash worker-server/bin/start.sh
bash alert-server/bin/start.sh
4.8 验证插件加载
查看 master-server 和 worker-server 日志:
grep "Success register task plugin" master-server/logs/master-server.log
# 应看到:
# Success register task plugin: EMR_SERVERLESS
# Success register task plugin: EMR (如果也安装了)
5. 从旧版本升级到 3.4.2 以获得 EMR Serverless 能力
5.1 升级路径
3.1.x / 3.2.x / 3.3.x → 3.4.2
DolphinScheduler 支持跨版本升级,升级工具会逐版本执行 DDL。
5.2 升级步骤
Step 1: 备份
# 备份数据库
mysqldump -h your-rds-endpoint -u root -p dolphinscheduler > dolphinscheduler_backup.sql
# 备份当前安装目录
cp -r /opt/dolphinscheduler /opt/dolphinscheduler-backup
Step 2: 停止旧版本所有服务
bash bin/stop-all.sh
Step 3: 解压新版本
tar -xzf apache-dolphinscheduler-3.4.2-bin.tar.gz -C /opt/
Step 4: 迁移配置
将旧版本中已修改的配置(application.yaml、aws.yaml、自定义环境变量)迁移到新目录中的对应位置。
Step 5: 执行 Schema 升级
# 补充 MySQL JDBC 驱动到 tools/libs/
cp mysql-connector-j-8.4.0.jar tools/libs/
# 执行升级
bash tools/bin/upgrade-schema.sh
如果遇到
Duplicate key name错误,参见下方避坑指南 #6。
Step 6: 安装 EMR Serverless 插件
按照 4.2 节 的方式安装插件。
Step 7: 配置 AWS 凭证
按照 4.5 节 配置 aws.yaml。
Step 8: 启动新版本
bash bin/start-all.sh
Step 9: 验证
- 检查日志确认插件加载成功
- 在 UI 中创建一个 EMR Serverless 类型的任务节点(应能在任务类型列表中看到)
- 提交测试任务验证端到端连通性
6. 使用 EMR Serverless Task 提交任务
6.1 创建任务
在 DolphinScheduler UI 中:
- 进入 项目管理 → 项目名称 → 工作流定义,点击"创建工作流"进入 DAG 编辑页面
- 从左侧工具栏拖拽 AmazonEMRServerless 任务节点到画布
6.2 任务参数说明
| 参数 | 说明 | 示例 |
|---|---|---|
| Application Id | EMR Serverless Application 的 ID,可在 EMR Serverless 控制台获取 | 00fkht2eodujab09 |
| Execution Role Arn | Job 运行时使用的 IAM Role ARN,该角色需要有访问 S3、Glue 等服务的权限 | arn:aws:iam::123456789012:role/EMRServerlessRole |
| Job Name | 作业名称(可选),用于在 EMR Serverless 控制台中标识作业 | DailyETL-SparkSQL |
| StartJobRunRequest JSON | 对应 StartJobRunRequest 中 JobDriver 和 ConfigurationOverrides 部分的 JSON 配置(见下方示例) | — |
⚠️ 重要:
StartJobRunRequest JSON中不需要包含ApplicationId和ExecutionRoleArn字段,它们会自动从上方的表单参数注入。
6.3 示例一:提交 Spark 作业
StartJobRunRequest JSON:
{
"JobDriver": {
"SparkSubmit": {
"EntryPoint": "s3://my-bucket/scripts/my-spark-job.py",
"EntryPointArguments": [
"s3://my-bucket/input/",
"s3://my-bucket/output/"
],
"SparkSubmitParameters": "--conf spark.executor.cores=4 --conf spark.executor.memory=8g --conf spark.executor.instances=10 --conf spark.hadoop.hive.metastore.client.factory.class=com.amazonaws.glue.catalog.metastore.AWSGlueDataCatalogHiveClientFactory"
}
},
"ConfigurationOverrides": {
"MonitoringConfiguration": {
"S3MonitoringConfiguration": {
"LogUri": "s3://my-bucket/emr-serverless-logs/"
}
}
}
}
说明:
EntryPoint:S3 上的 Spark 入口文件(jar 或 Python 脚本)EntryPointArguments:传递给入口程序的参数列表SparkSubmitParameters:等价于 spark-submit 的--conf、--jars、--class等参数MonitoringConfiguration:指定日志输出的 S3 路径
6.4 示例二:提交 Hive 作业
StartJobRunRequest JSON:
{
"JobDriver": {
"HiveSQL": {
"Query": "s3://my-bucket/scripts/my-hive-query.sql",
"Parameters": "--hiveconf hive.exec.dynamic.partition=true --hiveconf hive.exec.dynamic.partition.mode=nonstrict"
}
},
"ConfigurationOverrides": {
"MonitoringConfiguration": {
"S3MonitoringConfiguration": {
"LogUri": "s3://my-bucket/emr-serverless-logs/"
}
},
"ApplicationConfiguration": [
{
"Classification": "hive-site",
"Properties": {
"hive.metastore.client.factory.class": "com.amazonaws.glue.catalog.metastore.AWSGlueDataCatalogHiveClientFactory"
}
}
]
}
}
说明:
Query:S3 上的 Hive SQL 文件路径Parameters:Hive 运行时参数ApplicationConfiguration:相当于 Hive 的 site 配置,此处配置 Glue Data Catalog 作为 Hive Metastore
6.5 作业状态流转
提交后 DolphinScheduler 每 10 秒轮询作业状态:
SUBMITTED → PENDING → SCHEDULED → RUNNING → SUCCESS
→ FAILED
→ CANCELLED
- 作业达到 SUCCESS 状态 → 任务标记为成功
- 作业达到 FAILED 或 CANCELLED 状态 → 任务标记为失败
- 在 DolphinScheduler 中 Kill 任务 → 自动调用
CancelJobRunAPI 取消运行中的作业
6.6 注意事项
- Application 状态:Application Id 对应的 EMR Serverless Application 必须处于
STARTED或CREATED状态 - Execution Role 权限:需要具备
emr-serverless:StartJobRun、emr-serverless:GetJobRun、emr-serverless:CancelJobRun,以及作业所需的 S3、Glue 等数据访问权限 - JSON 不含 ID 字段:
StartJobRunRequest JSON中不要重复写ApplicationId或ExecutionRoleArn,它们从表单自动注入 - Failover:EMR Serverless Task 支持 Worker 故障恢复,新 Worker 可通过 jobRunId 继续跟踪运行中的作业
7. IAM 权限配置参考
7.1 EC2 实例 IAM Role(DolphinScheduler Worker 所在机器)
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"emr-serverless:StartJobRun",
"emr-serverless:GetJobRun",
"emr-serverless:CancelJobRun",
"emr-serverless:ListJobRuns",
"emr-serverless:GetApplication",
"emr-serverless:ListApplications"
],
"Resource": "*"
},
{
"Effect": "Allow",
"Action": "iam:PassRole",
"Resource": "arn:aws:iam::*:role/EMRServerlessJobRole",
"Condition": {
"StringLike": {
"iam:PassedToService": "emr-serverless.amazonaws.com"
}
}
}
]
}
7.2 EMR Serverless Job Execution Role
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"s3:GetObject",
"s3:PutObject",
"s3:ListBucket",
"s3:DeleteObject"
],
"Resource": [
"arn:aws:s3:::your-bucket",
"arn:aws:s3:::your-bucket/*"
]
},
{
"Effect": "Allow",
"Action": [
"glue:GetDatabase",
"glue:GetDatabases",
"glue:GetTable",
"glue:GetTables",
"glue:GetPartition",
"glue:GetPartitions",
"glue:CreateTable",
"glue:UpdateTable",
"glue:BatchCreatePartition"
],
"Resource": "*"
},
{
"Effect": "Allow",
"Action": [
"logs:PutLogEvents",
"logs:CreateLogGroup",
"logs:CreateLogStream",
"logs:DescribeLogGroups",
"logs:DescribeLogStreams"
],
"Resource": "*"
}
]
}
Trust Policy:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Service": "emr-serverless.amazonaws.com"
},
"Action": "sts:AssumeRole"
}
]
}
8. 避坑指南(FAQ & Troubleshooting)
以下问题基于实际部署经验总结,按出现频率排列。
问题 1:Cannot find TaskChannel for : EMR_SERVERLESS
现象:任务提交后 master 日志报 TaskExecutionContextCreateException: Cannot find TaskChannel for : EMR_SERVERLESS
原因:EMR Serverless 插件未安装。官方二进制包 plugins/ 目录默认为空。
解决:
./mvnw dependency:get \
-DgroupId=org.apache.dolphinscheduler \
-DartifactId=dolphinscheduler-task-emr-serverless \
-Dversion=3.4.2 -Dclassifier=shade \
-Ddest=plugins/task-plugins/
# 安装后必须重启全部四个服务
bash bin/stop-all.sh && bash bin/start-all.sh
⚠️ 常见误区:安装了
dolphinscheduler-task-emr(EC2 版)后以为 EMR Serverless 也能用——两者是独立的 artifact。
问题 2:装了插件但 api-server 查看日志仍报错
现象:任务执行成功,但在 UI 点击"查看日志"时报 Cannot find TaskChannel for : EMR_SERVERLESS
原因:api-server 也会加载 task 插件(用于日志查询、参数校验等功能),但只重启了 master/worker,忘记重启 api-server。
解决:
bash api-server/bin/stop.sh && bash api-server/bin/start.sh
教训:改动 plugins/ 目录后,master-server、worker-server、api-server、alert-server 全部要重启。插件通过 JVM classpath 加载,不支持热加载。
问题 3:Connection refused: localhost:9000 或 UnrecognizedClientException
现象:EMR Serverless 任务报连接 localhost:9000 被拒绝,或 AWS 返回 403 凭证无效。
原因:conf/aws.yaml 是官方包自带的占位 MinIO 测试配置,里面写的是 minioadmin / localhost:9000 / cn-north-1 等假值。
解决:
# conf/aws.yaml
aws:
emr:
credentials.provider.type: InstanceProfileCredentialsProvider
region: us-east-1 # 改为实际 Region
验证 EC2 实例的 IAM Role 有权限:
aws sts get-caller-identity
aws emr-serverless list-applications --region us-east-1
问题 4:The tenantCode is default, please enable TenantConfig#isDefaultTenantEnabled
现象:任务被 dispatch 到 worker 后立即失败,无日志。
原因:DolphinScheduler 3.4.x 默认 default-tenant-enabled: false(安全隔离),任务租户为 default 时拒绝执行。
解决:
# worker-server/conf/application.yaml
tenant-config:
default-tenant-enabled: true
重启 worker-server 后重试任务。
问题 5:MySQL JDBC 驱动缺失
现象:启动时或执行 upgrade-schema.sh 时报 No suitable driver found for jdbc:mysql://...
原因:GPL 许可问题,官方包不内置 MySQL 驱动。
解决:
curl -o mysql-connector-j-8.4.0.jar \
https://repo1.maven.org/maven2/com/mysql/mysql-connector-j/8.4.0/mysql-connector-j-8.4.0.jar
for dir in api-server master-server worker-server alert-server tools; do
cp mysql-connector-j-8.4.0.jar $dir/libs/
done
问题 6:升级时报 Duplicate key name 'uniq_workflow_definition_code'
现象:从旧版本升级,运行 upgrade-schema.sh 中途报 MySQL 语法错误。
原因:数据库表结构曾被之前某次未完成的手动升级改过,但 t_ds_version 表版本号停留在旧值,导致工具重复执行已生效的 DDL。
解决:
- 用
SHOW INDEX FROM <table>/DESCRIBE <table>核实报错的 DDL 是否已实际生效 - 确认是幂等冲突后,注释掉
tools/sql/sql/upgrade/{对应版本}_schema/mysql/dolphinscheduler_ddl.sql中已生效的 ALTER 语句 - 重新运行
upgrade-schema.sh - 最终确认
SELECT * FROM t_ds_version为目标版本号
⚠️ 不要直接删库重来,历史数据难以恢复。
问题 7:反向代理后 UI 404 或 WebSocket 断连
现象:通过 Nginx 反代后页面加载异常。
原因:DolphinScheduler 有固定的 context-path /dolphinscheduler/,且部分功能依赖 WebSocket。
解决(Nginx 配置参考):
server {
listen 80;
location /dolphinscheduler/ {
proxy_pass http://localhost:12345/dolphinscheduler/;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
# WebSocket 支持
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
location = / {
return 302 /dolphinscheduler/ui/;
}
}

639

被折叠的 条评论
为什么被折叠?



