最近在搞实时数据链路,手头有个需求:用 Flink 消费 Kafka 里的业务日志,做一轮清洗和规则过滤之后,再落到下游存储。任务不能一直挂在命令行里跑,得有调度、有告警、有可视化地管理起来。我最终选的是 DolphinScheduler 来做调度,Flink 作为计算引擎,Kafka 作为消息管道,整套环境跑在 Linux 服务器上。
DolphinScheduler 调度 Flink 任务这个组合,是我在多个实时项目里反复验证过的方案。和直接用 crontab 或者 nohup 相比,DolphinScheduler 的流程编排、失败重跑、告警通知、多租户隔离这些能力,能让流式任务真正进入"可运维"的状态。这篇博文不打算讲太多虚的,我从环境准备、Flink 任务开发、DolphinScheduler 任务配置,到常见的坑和排查思路,一步步把整条链路拆开来讲,适合正在搭实时数仓、日志处理管道,或者想把 Flink 任务纳入统一调度平台的读者参考。
1. 项目概述与整体方案选型
1.1 为什么需要调度平台来管理 Flink 任务
很多人刚接触 Flink 的时候,习惯直接在服务器上跑一条命令:
bash复制./bin/flink run -d -c com.example.KafkaFlinkJob /path/to/job.jar
任务确实能跑起来,但一旦进入生产环境,问题就来了:这个任务挂了谁能在 5 分钟内发现?Kafka 消费位点停在哪个 offset?出故障后重新提交的日志在哪里?如果每天要定点启动一批任务,依赖关系怎么编排?
crontab 能解决定时触发,但解决不了流程编排、失败重试、任务依赖和告警。Azkaban 能做 DAG 调度,但安装部署和日常维护成本偏高,权限模型也不够细致。DolphinScheduler 在开源调度里面算是对使用者最友好的一个,提供 Web 界面可视化操作,支持 Shell、SQL、Flink、Spark 多种任务类型,还能做到任务之间上下游依赖的自动触发。
我个人的观点是:调度 Flink 任务,关键不在于"能启动",而在于"可观测、可重试、可治理"。DolphinScheduler 恰好把这些能力打包好了。
1.2 技术选型:Flink、Kafka、DolphinScheduler 的分工
这三个组件放在一起是非常经典的实时计算三件套,各自的定位完全不同:
| 组件 | 定位 | 核心能力 |
|---|---|---|
| Kafka | 消息队列/数据管道 | 高吞吐写入、消息持久化、多消费组隔离、削峰填谷 |
| Flink | 流式计算引擎 | 状态管理、事件时间处理、精确一次语义、丰富的窗口计算 |
| DolphinScheduler | 工作流调度 | 任务编排、定时触发、依赖管理、失败重试、告警通知 |
数据流向大概是这样的:
code复制业务日志 -> Kafka Topic -> Flink 消费清洗 -> 下游存储(MySQL/ClickHouse/ES)
^
|
DolphinScheduler 负责启动和监控 Flink 任务
选择 Flink 而不选 Spark Streaming,除了实时性更强之外,关键还是 Flink 的 checkpoint 机制在做流式聚合、状态计算的时候更成熟。Kafka 在这里承担的是缓冲和解耦的职责,即使 Flink 任务短暂下线,消息也不会丢,任务恢复后可以继续从上次 checkpoint 对应的 offset 消费。DolphinScheduler 则负责在最外层做"调度大脑",按小时、按天触发业务关联的多个 Flink jar 包任务。
1.3 版本组合建议
在动手之前,一定要先确认版本兼容性。我在项目里用过的组合比较多,目前最稳的一套是:
- JDK 1.8(Flink 1.14+ 也支持 JDK 11,但很多公司生产环境还是 1.8)
- Kafka 2.8 或 3.x
- Flink 1.16 或 1.17
- DolphinScheduler 3.1.x
- Zookeeper 3.8(如果 Kafka 没用 KRaft 模式)
这里特别提醒一句:DolphinScheduler 的 Flink 任务节点,本质上是在底层拼接 flink run 命令。所以 DolphinScheduler 的版本只要能正常执行 shell 命令和识别你配置的 FLINK_HOME 就行,它和 Flink 的版本耦合度不高。真正需要在意的是 Flink 本身和 Kafka connector 的版本对应关系,这块我在后面第 3 节细讲。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. Linux 环境准备与基础部署
2.1 Linux 系统初始化
不管是 Flink、Kafka 还是 DolphinScheduler,都需要跑在 Linux 上。部署前我习惯先做一轮系统初始化,避免后面踩环境坑。
第一步:创建独立用户
生产环境不建议用 root 跑任务,我通常会单独建一个用户:
bash复制useradd -m -s /bin/bash datadev
passwd datadev
所有 JDK、Flink、Kafka、DolphinScheduler 的安装目录都统一放在 /opt 或 /data 下面,并把目录属主改成 datadev,这样权限清晰,也好管理。很多同学用 root 装完直接启动,后面在 DolphinScheduler 里用租户提交任务时经常遇到权限问题,就是因为目录属主不对。
第二步:安装 JDK 并配置环境变量
编辑 /etc/profile,追加:
bash复制export JAVA_HOME=/opt/jdk1.8.0_202
export PATH=$JAVA_HOME/bin:$PATH
执行 source /etc/profile 后验证:
bash复制java -version
第三步:关闭防火墙并配置 hosts
本地测试环境可以关闭防火墙:
bash复制systemctl stop firewalld
systemctl disable firewalld
如果是云服务器,需要在安全组里放行对应端口。然后编辑 /etc/hosts,把各节点的主机名和 IP 对应起来。分布式环境里主机名解析如果不对,Kafka 的 advertised.listeners 会经常出问题,这个很关键。
第四步:时间同步
流式任务对服务器时间很敏感,Kafka 的消息时间戳、Flink 的事件时间处理都依赖时钟。配置 NTP 或 chrony 同步时间,这一步别省。
2.2 Flink 部署要点
Flink 支持 standalone、YARN、Kubernetes 等多种部署模式。DolphinScheduler 提交 Flink 任务的时候,可以指定运行模式。我先说最简单的 standalone。
下载 Flink 二进制包并解压:
bash复制tar -zxvf flink-1.16.2-bin-scala_2.12.tgz -C /opt
cd /opt/flink-1.16.2
修改 conf/flink-conf.yaml,关键参数:
yaml复制jobmanager.memory.process.size: 2048m
taskmanager.memory.process.size: 4096m
taskmanager.numberOfTaskSlots: 4
rest.port: 8081
这些参数影响到 Flink 能同时跑多少个任务、单个任务的并行度上限。我习惯先按服务器内存的四分之一到三分之一分配给 TaskManager,然后根据需要的并行
