资讯详情

资讯详情

DolphinScheduler+Minio本地开发环境搭建:轻量替代HDFS的完整实践

干这行当久了你会发现开发环境最折腾人的往往不是业务代码而是周围那一圈基础组件。DolphinScheduler 本身是个好用的工作流调度平台但你要是老老实实按生产模式搞一套 HDFS 来存资源文件光环境搭建就够喝一壶。所以我现在本地开发都是 DolphinScheduler 3.1.9 Minio 这套轻量组合一个对象存储搞定资源文件IDEA 里直接源码跑服务调试起来非常顺手。这篇文章把我从零搭建到跑通整个流程的细节包括中间踩过的那些坑全部记录下来给准备在本地搭 DolphinScheduler 开发环境的朋友一个参考。1. 先搞清楚这套架构里各部分是什么关系1.1 DolphinScheduler 3.1.9 在开发环境里的作用DolphinScheduler简称 DS是 Apache 基金会下面的工作流调度系统说白了就是用来编排定时任务的比如每天凌晨跑 SQL 抽数、定期执行 Spark 脚本、根据依赖关系串行并行跑各种作业。3.1.9 属于 3.1.x 分支比较后期的补丁版本相比早期 3.1.0 修复了大量 bugMaster/Worker 通信、任务提交、资源管理这几个核心模块的稳定性都好了不少。我在选型时特意挑了这个版本而不是直接上 3.2.x原因很简单3.1.x 社区资料最全、踩坑案例最多真遇到问题能搜到靠谱答案这对于本地开发调试来说太重要了。在 IDEA 里跑 DS 源码本质上是把整个调度平台的核心服务全部本地化运行ApiServer 提供 REST API 和 UI 后端MasterServer 负责任务的调度分发WorkerServer 真正执行任务AlertServer 负责告警通知。四个服务全部启动后打开前端页面就能完整体验一套生产级调度平台的所有功能。开发时还能直接断点调试 Master 或 Worker 的逻辑这是用二进制包部署完全做不到的。1.2 为什么存储层选择 Minio 而不是 HDFSDS 的资源管理模块负责统一存储工作流里用到的脚本、Jar 包、数据文件等官方默认支持 HDFS、S3、OSS 等存储后端。HDFS 虽然是生产环境的标准选择但本地开发真要搭一套 NameNode DataNode又会遇到内存不足、启动慢、端口冲突这一堆破事。Minio 是兼容 S3 协议的对象存储单个二进制文件就能跑起来几百 MB 内存就能运行得很流畅作为本地开发替代 HDFS 再合适不过。Minio 兼容 S3 协议意味着 DS 的存储适配器无需任何额外开发只要把resource.storage.type配成S3再把 endpoint 指向本地 Minio 即可。DS 底层通过 S3 SDK 与 Minio 交互文件上传、下载、删除、生成临时访问链接这些操作全部走标准 S3 接口相当于白捡了一套成熟的存储方案。对于没有接触过对象存储的同学可以简单理解成 Minio 就是一个轻量版的阿里云 OSS 或 AWS S3但完全部署在你自己的机器上。1.3 整体流程预期从上传脚本到任务运行我把整个搭建过程的最终效果先描述一下方便你判断自己要走到哪一步。整个环境跑通以后你在 DS 的 Web UI 上登录管理员账号创建一个租户然后上传一个 SQL 文件到资源中心这个文件会被自动写入 Minio 的对应 bucket存储路径形如dolphinscheduler/{租户编码}/{文件名}。之后在新建工作流时可以直接引用这个资源文件作为 Shell 或 SQL 任务的脚本Worker 执行任务时会自动从 Minio 拉取文件。如果一切正常你在 Minio 的 web 控制台里能直接看到这份文件整个闭环就算打通了。一个容易忽略的点是本地开发时资源文件放在 Minio但 DS 元数据工作流定义、任务实例、调度记录存放在关系型数据库里。两者互不干扰但必须同时可用。这也是为什么这套环境需要同时装 MySQL可选 H2和 Minio 的原因。2. 环境准备版本选型与本地基础组件2.1 版本组合清单与注意事项老话说得好开发环境一半的问题出在版本不匹配上。DolphinScheduler 3.1.9 的源码对 JDK 版本比较敏感官方推荐 JDK 8实测在 JDK 8 下编译运行最稳妥。Maven 用 3.6 以上IDEA 版本倒没什么硬性要求2022.x 之后都行但必须装好 Lombok 插件这个不装工程直接编译不过。MySQL 建议 5.7 或 8.0ZooKeeper 用 3.7 或 3.8 单机版即可Minio 直接用最新稳定版就行。我整理了一份我当时使用的版本清单组件版本用途备注JDK1.8编译与运行基础不要用 17部分依赖会有兼容问题Maven3.8.x源码编译与依赖管理配好阿里云镜像编译快很多ZooKeeper3.8.0服务注册与任务分发协调开发环境单机即可MySQL5.7 / 8.0DS 元数据存储也可用 PostgreSQL 或 H2Minio最新稳定版资源文件对象存储兼容 S3 协议IDEA2022.x开发调试 IDE必须装 Lombok 插件还有一个细节容易被新手忽略DS 3.1.9 编译时对 Maven 内存有要求默认设置可能不够建议在~/.m2/settings.xml里把 MAVEN_OPTS 调大一点具体后面会提到。2.2 用 Docker 快速启动一个 MinioMinio 的安装方式很多我最推荐开发环境用 Docker一条命令就能搞定完全不用关心二进制包的启动参数。如果你本机没有 Docker直接去官网下载 Minio Server 的二进制文件设置好环境变量后启动效果一样。这里我用 Docker 为例docker run -d \ --name minio-dev \ -p 9000:9000 \ -p 9001:9001 \ -e MINIO_ROOT_USERminioadmin \ -e MINIO_ROOT_PASSWORDminioadmin123 \ -v /data/minio:/data \ minio/minio server /data --console-address :9001端口方面9000 是 S3 API 端口DS 的 S3 客户端要连的就是它9001 是 Minio 的 Web 控制台端口方便你查看文件是否上传成功。启动后用浏览器访问http://localhost:9001输入上面设置的账号密码就能登录管理界面。第一次登录后记得先创建一个名为dolphinscheduler的 bucketDS 不会自动创建 bucket这一步漏掉的话后面上传资源一定会报 NoSuchBucket 错误。如果你不想用 Docker二进制方式也极简单设置两个环境变量然后启动export MINIO_ROOT_USERminioadmin export MINIO_ROOT_PASSWORDminioadmin123 ./minio server /data --console-address :9001无论哪种方式请务必记住 Access Key 和 Secret Key后面 common.properties 配置要用的。2.3 初始化 MySQL 和 ZooKeeperMySQL 是用来存 DS 元数据的本地开发我直接用了已有的 MySQL 8.0 实例。创建数据库时注意字符集必须用 utf8mb4排序规则用 utf8mb4_general_ci否则后续建表可能报错。SQL 语句很简单CREATE DATABASE dolphinscheduler DEFAULT CHARACTER SET utf8mb4 DEFAULT COLLATE utf8mb4_general_ci;DS 的表结构不需要手动逐个执行 SQL 脚本我后面会在 IDEA 章节详细说明怎么用官方工具自动建表这里先把空库准备好就行。ZooKeeper 在 3.1.x 中是必须的Master 和 Worker 的注册、任务队列的分发都依赖它。本地开发直接下载官方压缩包解压配置都不用改默认端口 2181 即可。启动命令bin/zkServer.sh start启动后确认端口监听正常telnet 127.0.0.1 2181我遇到过不少次漏启动 ZK 导致 Master 启动失败的情况所以这里单独强调一下。ZK 没起来的时候Master 服务会反复报连接超时你得从日志里半天才能看出是 ZK 的问题非常浪费时间。3. IDEA 中把 DolphinScheduler 3.1.9 源码跑起来3.1 拉取源码与工程预编译源码可以直接从 Apache 官方仓库拉取指定 tag也可以用国内镜像加速。我直接用 Git 拉取 v3.1.9 这个 taggit clone -b 3.1.9 https://github.com/apache/dolphinscheduler.git工程是标准的多模块 Maven 项目直接用 IDEA 打开根目录的 pom.xml 即可。但先别急着点运行源码首次编译需要下载大量依赖如果网络一般建议先配置 Maven 阿里云镜像然后执行一次整体编译mvn -T 4 clean install -DskipTests -Dspotless.check.skiptrue -Dmaven.javadoc.skiptrue这里的-T 4表示并行 4 线程编译能快不少。spotless.check.skip跳过代码格式检查开发环境下没必要在格式上浪费编译时间。我的经验是首次编译至少需要 15 到 30 分钟取决于网络和机器性能所以建议先去干点别的等它慢慢跑。编译成功后IDEA 里就能看到dolphinscheduler-master、dolphinscheduler-worker、dolphinscheduler-api、dolphinscheduler-alert、dolphinscheduler-tools这几个关键模块。如果 Maven 面板里依赖全部加载完成没有红叉说明工程基本可用。3.2 数据库连接配置与初始化这一步非常关键。DS 3.1.9 的各个服务模块在源码工程里各自有独立的application.yaml配置文件修改一个模块不够需要把 master、worker、api、alert、tools 这几个模块的配置都改一致。配置文件在dolphinscheduler-{模块}/src/main/resources/application.yaml。打开dolphinscheduler-api/src/main/resources/application.yaml找到 Spring 数据源配置部分把默认的 H2 配置改成 MySQLspring: datasource: driver-class-name: com.mysql.cj.jdbc.Driver url: jdbc:mysql://127.0.0.1:3306/dolphinscheduler?useUnicodetruecharacterEncodingUTF-8serverTimezoneAsia/Shanghai username: root password: yourpassword其他模块的 application.yaml 只要涉及数据源配置也做相同修改。这里要特别提醒如果你只改了 api 模块Master 和 Worker 起来后连接元数据库必然失败因为它们也要读写元数据。我当时就是犯了这个低级错误排查了半天才意识到配置文件没同步。数据库初始化有两种方式。第一种也是我推荐的方式利用dolphinscheduler-tools模块。在 IDEA 的 Maven 面板中找到dolphinscheduler-tools先编译该模块然后找到org.apache.dolphinscheduler.tools.datasource.InitDolphinScheduler类直接运行 main 方法。前提是它的 application.yaml 数据源已经改成 MySQL否则它默认连的是 H2。运行后观察控制台日志看到建表成功、初始化数据完成的提示即可。第二种方式是手动执行 SQL 脚本但不推荐。DS 表结构有几十张而且表之间创建顺序有依赖关系手动导入分分钟报外键错误。除非你是老手不然别省这一步的功夫。3.3 启动 Master、Worker、API、Alert 四个服务数据库准备好以后就可以在 IDEA 里依次启动四个核心服务了。每个模块都有对应的启动类模块启动类dolphinscheduler-apiApiApplicationServerdolphinscheduler-masterMasterServerdolphinscheduler-workerWorkerServerdolphinscheduler-alertAlertServer在 IDEA 的 Run Configuration 里新增四个 Application 配置工作目录建议统一设置为各模块的根目录。先启动 ApiServer再启动 MasterServer、WorkerServer、AlertServer顺序没有强制要求但 ApiServer 先起来方便观察整体状态。这里有个 IDE 的高频坑DS 3.1.9 源码中部分类使用了 LombokIDEA 如果没有开启注解处理编译会报找不到 getter/setter 方法。如果启动时出现大量找不到符号的错误检查一下Settings - Build - Compiler - Annotation Processors勾选Enable annotation processing。另外有同学反馈新版本 IDEA 还需要安装 Lombok 插件顺手确认一下。启动完成后如果一切正常ApiServer 会在 12345 端口监听Master 在 5678Worker 在 1234。这些端口如果不幸被占用可以在对应模块的application.yaml里调整server.port和registry.zookeeper相关配置不过本地开发一般不会冲突。3.4 启动之后先别急验证服务注册四个服务全部启动并不意味着万事大吉务必确认它们是否成功注册到 ZooKeeper。打开 ZK 的命令行客户端bin/zkCli.sh ls /dolphinscheduler正常情况会看到nodes、lock等节点再执行ls /dolphinscheduler/nodes/master ls /dolphinscheduler/nodes/worker两个命令都能看到对应的服务地址说明注册成功。我见过不少案例ApiServer 起来了页面上能看到登录框但 Master 没注册成功结果创建工作流时一直报“无可用 Master”。用上面这个方法半分钟就能确定问题在哪一层。浏览器访问http://localhost:12345/dolphinscheduler即可打开 Web UI。如果是首次登录默认账号是admin密码是dolphinscheduler123。登录成功后第一件事不是急着建任务而是检查左下角的“服务管理”页面看看 Master、Worker 是否在线。这一步确认了环境就稳了。4. 对接 Miniocommon.properties 配置全解析4.1 资源存储类型与 S3 协议的关系资源存储类型在 DS 中通过common.properties配置这个文件在源码工程中位于各模块共享的配置目录。DS 支持 HDFS、S3、OSS、GCS 等多种存储后端选择存储类型用的是resource.storage.type这个配置项。因为 Minio 兼容 S3 协议所以这里直接填S3DS 底层会把所有文件操作封装为标准的 S3 API 调用不需要额外开发插件。S3 协议在对象存储领域基本是事实标准Minio、AWS S3、华为云 OBS、七牛云都兼容它。DS 之所以能无缝对接 Minio靠的就是这个协议兼容性。这就像你的手机支持 USB-C 接口那你就能用一个充电头给各种品牌的设备充电只要它们都用 USB-C 接口。理解这一点后面遇到各种连接问题你就能更精准地判断原因。4.2 关键配置项逐一说明找到dolphinscheduler-common模块下的common.properties可能位于dolphinscheduler-common/src/main/resources/common.properties重点配置以下几项# 资源存储类型Minio 就用 S3 resource.storage.typeS3 # 存储根路径建议写成 bucket 下的一个子目录名前缀 resource.upload.pathdolphinscheduler # Minio S3 API 地址注意端口是 9000不是 9001 resource.s3.endpointhttp://127.0.0.1:9000 # Minio 控制台创建的 Access Key 和 Secret Key resource.s3.access.key.idminioadmin resource.s3.access.key.secretminioadmin123 # 区域Minio 默认填 us-east-1 即可 resource.s3.regionus-east-1 # 存储桶名称务必提前在 Minio 中创建 resource.s3.bucket.namedolphinscheduler # 关键使用路径风格访问Minio 必须开启 resource.s3.path.style.accesstrue这里每个参数都值得细说。resource.upload.path是 bucket 内的根路径前缀DS 会把所有上传资源放在这个前缀下面建议直接写dolphinscheduler和 bucket 同名也不会混淆。resource.s3.endpoint不要写 localhost建议用127.0.0.1某些场景下 localhost 会被解析成 IPv6 导致连接失败。resource.s3.path.style.access是最容易被忽略的一项Minio 这类非 AWS 存储服务默认要求路径风格访问也就是 URL 里直接带 bucket 名称的路径如果保持默认 false文件操作会报各种奇怪的 301 重定向或签名错误。如果你的版本在配置文件中找不到resource.s3.path.style.access这一项说明版本较旧或配置模板不完整可以手动加上。DS 3.1.5 之后的版本应该都有这个字段。4.3 多模块配置同步与重启顺序common.properties并不是只有 api 模块才用Master、Worker、Alert 都会读取它。正式启用 Minio 存储后请确保所有模块下的这份配置保持一致否则会出现 API 上传资源成功但 Worker 执行任务时拉不到文件的情况。具体来说C/S 架构中 API 处理用户上传Worker 执行任务时要根据资源 ID 到存储介质取文件如果两者的存储配置不一致比如 API 指向 Minio AWorker 指向 Minio B结果自然是文件找不到。本地开发虽然没有多套 Minio但配置不同步同样会出问题。修改完配置后务必将四个服务全部重启。不要抱有“改完配置热加载就行”的侥幸心理单独的配置监控机制不会自动加载 common.properties。我的习惯是修改配置后先重启 ApiServer再重启 WorkerServer最后重启 Master并把启动日志中资源存储相关的一行打印确认一下。5. 访问验证从上传资源到 Minio 落盘5.1 登录 UI 并创建租户用户环境全部启动后重头戏来了实际验证整个链路是否通畅。用admin/dolphinscheduler123登录 UI你会在左侧菜单看到“安全中心”这一栏。创建租户和用户是必须先做的前置操作原因在于 DS 的资源文件是按租户目录隔离的每个资源上传后最终都会落在对应租户编码的目录下面。在“安全中心 - 租户管理”中点击“创建租户”租户编码建议用纯英文小写比如dev。然后进入“用户管理”新建一个普通用户关联刚才创建的租户。创建完以后退出登录用这个新用户重新登录再进行资源上传测试。不建普通用户直接用 admin 上传也可以但 admin 没有关联租户资源路径会走特殊的租户处理逻辑更容易踩坑我建議直接用新用户走标准流程。5.2 上传资源并确认 Minio 中的目录结构用新用户登录后进入“资源中心 - 文件管理”点击“上传文件”选一个本地 SQL 或 shell 脚本上传。如果配置正确上传过程应该是秒完的。此时打开 Minio 的 Web 控制台http://localhost:9001进入dolphinschedulerbucket你会看到里面出现了一个目录结构大致如下dolphinscheduler/ └── dev/ └── test.sqldev就是你创建的租户编码test.sql是上传的文件。这个路径结构和 DS 内部的资源管理逻辑是对应的租户隔离机制在这里就体现出来了。不同的租户上传同名文件完全互不干扰。如果在 Minio 控制台里看到这个文件说明资源上传这条链路全部打通。接下来验证下载回到 DS 资源中心点击文件对应的“下载”按钮能正常下载即为成功。此时再去尝试“编辑”查看文件内容DS 会通过 API 从 Minio 读取文件内容这也是一道很好的验证步骤。5.3 任务中引用资源的路径写法资源上传成功只是第一步最终目标是让工作流任务能用到这些文件。在 3.1.9 中新建一个 Shell 任务时可以在“脚本”区域直接引用资源文件。引用格式推荐使用在线资源选择功能UI 上会弹出资源列表让你勾选勾选后会插入类似下面的占位符resource/xxx_resource_id/test.sqlDS 在任务提交执行时会自动解析这个引用并让 Worker 从 Minio 下载对应的资源文件到本地临时目录然后作为脚本执行。整个过程对用户来说是透明的。验证方式也很简单在 Shell 任务中写一行ls或cat查看资源文件内容跑一次工作流实例看任务日志中能否正常打印。能打出来说明从上传、存储到任务消费的完整闭环已经通了。我在这一步遇到的典型问题是上传资源没问题但任务运行时提示文件不存在。排查后发现是 Worker 模块的 common.properties 中存储配置没改Worker 还在尝试从本地文件系统找资源。所以再次提醒改完配置四个服务必须同步重启。6. 开发环境常见问题排查实录6.1 Minio 连接失败与 403 权限问题Minio 连接失败是最常见的问题表现形式五花八门主要在 ApiServer 或 Worker 日志中看到连接超时、UnknownHostException、403 Forbidden。我把排查思路整理成一条线遇到问题按顺序排查基本能解决九成以上场景。先说连接超时。确认 endpoint 的 IP 和端口是否正确API 端口是 9000不是 9001。如果你本机防火墙开启需要放行 9000 端口。在服务器上部署时检查 Minio 是否绑定了监听地址Docker 启动时是否做好了端口映射。简单排查命令是curl http://127.0.0.1:9000/minio/health/live能返回正常状态说明 Minio 服务健康问题多半在配置。然后是 403 权限。Access Key 和 Secret Key 错误是最常见原因去 Minio 控制台重新确认。还有一个经典原因Minio 服务端和本机的系统时间差得太多S3 签名机制依赖时间戳一般误差超过 15 分钟就会验签失败。这个问题在公司电脑上尤其常见系统时间被 NTP 同步拉偏或手动改过时间没注意都会导致 403。排查方法很简单对比一下本机时间和 Minio 服务端时间。6.2 资源上传成功但任务取不到文件这种问题非常隐蔽因为从 UI 上看资源中心一切正常文件确实传上去了但任务执行时就是找不到文件。大概率是各模块的 common.properties 配置不一致。我之前调试过一个项目ApiServer 的配置指向的是本机 Minio而 Worker 模块的配置还停留在默认值或者指向别的地址。任务执行时 Worker 自然拉不到文件。排查方法是逐个查看四个服务模块的 common.properties把resource.storage.type、resource.s3.endpoint、resource.s3.bucket.name这几项统一。另外还要检查 Worker 的工作目录是否有写权限DS 下载资源文件后要写到本地临时目录如果该目录权限不对同样会表现成资源找不到。还有一种情况任务日志中报的资源 key 和你上传后在 Minio 中看到的 bucket 路径对不上。这时候去任务实例详情里查看参数化后的实际执行命令能直观看到 DS 是怎么解析资源引用的。如果引用资源的 ID 写错了解析出的路径自然不对。6.3 UI 登录、租户、日志相关杂症登录界面打不开先确认 ApiServer 是否启动成功访问http://localhost:12345/dolphinscheduler是否返回登录页。很多同学把前端工程单独跑在 8080 端口访问的是前端页面而不是 api 服务连不上数据库也会导致登录失败。如果页面能打开但登录报错大概率是元数据库没初始化完整或者 admin 密码不对前者需要用 tools 模块重新初始化。日志相关的坑则主要出现在 Worker 执行任务后UI 上点“查看日志”一片空白。这种情况十有八九是 Logger 相关配置不对或者 Worker 的日志存储目录不存在。开发环境中任务日志默认存储在本地打开 Worker 模块的 logback 配置确认日志根路径存在且有写权限。如果日志直接打不出来先看 Worker 自身的 stdout 有没有报错很快能定位。6.4 常见问题速查表最后整理一张速查表方便你遇到问题直接对照现象可能原因解决方向上传资源报连接超时Minio 未启动/端口错误curl 检查 9000 端口确认 endpoint 配置上传资源报 NoSuchBucketbucket 未创建提前创建dolphinschedulerbucket上传资源报 403 AccessDeniedAK/SK 错误、时间不同步重新生成密钥同步系统时间任务执行时找不到资源文件各模块 common.properties 不一致统一所有模块的存储配置并重启Master 启动后迅速退出ZooKeeper 未启动先启动 ZK确认 2181 端口UI 登录后看不到 Master/Worker服务注册失败ZK 中查看 /dolphinscheduler/nodesWorker 任务日志无法查看日志路径不存在/无权限检查 Worker 日志目录和 logback 配置页面上传资源很慢Minio 和 API 跨网络本地开发使用 127.0.0.1 避免 DNS 延迟前端页面打不开前端工程端口不对确认访问 12345 端口的 api 服务这张表覆盖了我个人在搭建过程中遇到的大多数问题但实际场景里总会出现稀奇古怪的情况。我的建议是遇到问题时先看日志Master、Worker、ApiServer 三个服务的日志都会实时输出核心错误信息绝大多数问题在日志里都有直接线索顺着关键字去查远比在 UI 上猜靠谱。最后再分享一个小技巧。本地开发时建议把各个服务的日志级别调整到 DEBUG特别是在排查 S3 连接问题时。修改logback-spring.xml或者 application.yaml 中的日志级别配置把com.amazonaws和org.apache.dolphinscheduler相关包的日志打开能看到 S3 请求的具体错误详情比抱着一句“AccessDenied”瞎猜高效得多。等环境稳定了再改回 INFO否则日志量太大反而干扰调试。这套环境搭好之后我在本地调试 DS 的资源上传、工作流定义、任务执行这些功能时效率高了不少。比起动不动就上一套 HDFS 或者连远程测试环境Minio 源码运行的方式足够轻量又保留了完整的调试能力。如果你正好在搞 DolphinScheduler 相关的二次开发或者任务调试不妨按这篇文章的步骤试一遍有问题随时对照速查表排查应该能少走不少弯路。
觉得有用,分享给同行:

为您的企业打造数字门面

稳重轻奢商务风格,端正雅致视觉,长效耐看不易过时。

立即咨询 →