
4 月份月报来啦!社区梳理了 2026 年 4 月份 Apache SeaTunnel 合入 origin/dev 的 31 个带 PR 号代码提交,从功能特性、性能优化、Bug 修复、架构改进展开,对如 Doris Stream Load 增强等关键变更做源码级拆解,并附上当月 PR 贡献者名单,快来看看你在名单上吗?😊
统计口径:只统计 origin/dev 分支在上述时间范围内的提交;不含其他分支(例如 release 分支)独立提交。
时间范围:2026-04-01 ~ 2026-04-30(含)
本月关键词:SeaTunnel;Zeta;Connector V2;Doris;JDBC;CDC;Metadata;Checkpoint;Continuous Discovery;E2E
1. 当月功能特性梳理
1.1 Doris Sink:Stream Load 重定向增强(#10715)
Doris 的 Stream Load 经常出现 FE 返回 307 重定向到 BE 的行为。该 PR 的核心是让连接器在遇到重定向/重定向跟随失败时,输出更可诊断的错误信息,并在 HTTP 客户端侧做重定向跟踪。
关键实现片段:
-
重定向异常信息构造(包含 request、Location、direct_to_be、2pc、stage 等诊断字段):
public static String buildFollowUpFailure(String requestUrl,String location,boolean directToBe,boolean enable2PC,String requestStage,String causeMessage) {return String.format("stream load redirect follow-up failed after HTTP/1.1 307 Temporary Redirect, "+ "request=%s, Location=%s, direct_to_be=%s, 2pc=%s, stage=%s, cause=%s. "+ "Please check BE reachability, FE load, and consider benodes + direct_to_be=true when FE redirect is unstable.",requestUrl,location == null ? "<missing>" : location,directToBe,enable2PC,requestStage,causeMessage == null ? "<missing>" : causeMessage); }(来自提交 #10715:
.../DorisRedirectExceptionBuilder.java) -
执行请求时跟踪最后一次 redirectLocation,并在 IOException 时包装成更可读的异常:
public static CloseableHttpResponse executeWithRedirectTracking(CloseableHttpClient httpClient,HttpUriRequest request,String requestUrl,boolean directToBe,boolean enable2PC,String requestStage) throws IOException {HttpClientContext context = HttpClientContext.create();try {return httpClient.execute(request, context);} catch (IOException e) {String redirectLocation = resolveLastRedirectLocation(context);if (redirectLocation != null) {throw new DorisConnectorException(DorisConnectorErrorCode.STREAM_LOAD_FAILED,DorisRedirectExceptionBuilder.buildFollowUpFailure(requestUrl, redirectLocation, directToBe, enable2PC, requestStage, e.getMessage()),e);}throw e;} }(来自提交 #10715:
.../HttpUtil.java)
影响范围
- Doris Sink 的错误定位体验显著提升:以前“stream load 失败”可能只看到笼统 IOException;现在能直接看到 Location、是否 direct_to_be、阶段信息。
- 对生产价值:减少“偶发重定向/网络抖动”导致的排障时间。
1.2 File Source:FTP/SFTP/Local/HDFS 连续发现(#10473)
在文件同步场景中,“一次性扫描”不够用,用户往往需要:
- 目录持续有新文件时持续消费;
- 配合
sync_mode=update做增量/去重/更新策略。
该 PR 引入 FileDiscoveryMode.CONTINUOUS,并实现一个“定时扫描 + 增量入队 + 有界状态”的 SplitEnumerator。
关键实现片段:
-
新的枚举模式:
public enum FileDiscoveryMode implements Serializable {ONCE,CONTINUOUS }(来自提交 #10473:
.../FileDiscoveryMode.java) -
Continuous Enumerator 的核心机制:定时扫描、将新 split 入队、把 state 控制在 in-flight 范围(避免无限增长):
public void open() {scheduler = Executors.newSingleThreadScheduledExecutor(...);scheduler.scheduleWithFixedDelay(this::safeScanOnce,0L,Math.max(1L, scanInterval.toMillis()),TimeUnit.MILLISECONDS); }public FileSourceState snapshotState(long checkpointId) {synchronized (lock) {// Store in-flight splits only to avoid unbounded state growth.return new FileSourceState(new HashSet<>(inFlightSplits), jobStartTimeMillis);} }(来自提交 #10473:
.../ContinuousMultipleTableFileSourceSplitEnumerator.java) -
扫描时对“版本变化/重复入队”做抑制,避免 scanInterval 很短导致重复 split 风暴:
private boolean enqueueSplitIfAbsent(FileSourceSplit split, SplitVersion splitVersion) {String splitId = split.splitId();synchronized (lock) {if (splitVersion != null && splitVersion.equals(knownSplitVersions.get(splitId))) {return false;}if (pendingSplitIds.contains(splitId)) {return false;}for (FileSourceSplit inFlight : inFlightSplits) {if (Objects.equals(inFlight.splitId(), splitId)) {return false;}}pendingSplits.addLast(split);pendingSplitIds.add(splitId);if (splitVersion != null) {knownSplitVersions.put(splitId, splitVersion);}return true;} }(同上)
影响范围
- 连接器能力从“批处理导入”向“目录持续同步”扩展,且通过有界状态设计避免 enumerator 状态无限膨胀。
- 配合 DistCp/update 类场景更稳:避免重复 split 入队导致重复写入压力。
1.3 JDBC Sink:新增 batch_interval_ms 定时 flush(#10609)
JDBC Sink 以往主要依赖 batch_size 达到阈值时刷写;这会造成一个典型问题:
- batch_size 设得大以提升吞吐时,小流量场景 迟迟不 flush,数据延迟不可控。
该 PR 在 JDBC Sink 中引入 batch_interval_ms,实现“时间到就刷”的策略,并配套 E2E 用例验证“在任务结束前已写入”。
核心 E2E 断言(证明“定时 flush 在 job 完成前生效”):
given().ignoreExceptions().await().atMost(30, TimeUnit.SECONDS).pollInterval(2, TimeUnit.SECONDS).untilAsserted(() -> {Assertions.assertFalse(jobFinished.get(), "Job should still be running ...");int rowCount = getSinkRowCount("sink_batch_interval_timer");Assertions.assertTrue(rowCount > 0,"Timer flush should have written rows to the database BEFORE job completion "+ "(batch_size=100000 is never reached)");});
(来自提交 #10609:JdbcSinkBatchIntervalIT.java)
影响范围
- 对“低吞吐但要求低延迟写入”的场景(例如准实时维表落库、审计日志落库)非常关键:把延迟上限从“等 batch_size”变为“等 batch_interval_ms”。
1.4 CDC:暴露 binlog/GTID/SourceTimestamp 元数据(#10667)
在 CDC 同步中,很多用户需要拿到“事件来自哪里、位点是多少、源端时间戳”等信息,用于:
- 延迟/堆积诊断(sourceTimestamp vs sinkTimestamp)
- 数据血缘与审计
- 与外部系统对齐 offset/GTID
该 PR 在 MetadataUtil 中增加对 BINLOG_FILE/BINLOG_POS/BINLOG_ROW/GTID/SOURCE_TIMESTAMP 的设置入口,并通过 CommonOptions 标记可透传元数据集合。
示例:
public static void setBinlogFile(SeaTunnelRow row, String file) {row.getOptions().put(BINLOG_FILE.getName(), file);
}
public static void setGtid(SeaTunnelRow row, String gtid) {row.getOptions().put(GTID.getName(), gtid);
}
public static void setSourceTimestamp(SeaTunnelRow row, Long sourceTimestamp) {row.getOptions().put(SOURCE_TIMESTAMP.getName(), sourceTimestamp);
}
(来自提交 #10667:seatunnel-api/.../MetadataUtil.java)
影响范围
- CDC 链路的可观测能力增强:用户可以在 Transform / Sink 侧读取这些 metadata 做日志、分流、告警等。
2. 当月 Bug 修复梳理
2.1 Zeta Checkpoint:notifyCompleted 失败处理收敛(#10705)
问题类型:Checkpoint completed 通知链路(notifyCheckpointCompleted / notifyCheckpointEnd)存在异常时,如果处理分散,容易形成“部分状态推进、部分失败”的不一致。
该 PR 的核心是把 notifyCompleted 相关异常统一收敛到 coordinator 的错误处理路径:
try {InvocationFuture<?>[] invocationFutures = notifyCheckpointCompleted(completedCheckpoint);CompletableFuture.allOf(invocationFutures).join();InvocationFuture<?>[] invocationFuturesForEnd = notifyCheckpointEnd(completedCheckpoint);CompletableFuture.allOf(invocationFuturesForEnd).join();
} catch (Throwable e) {handleCoordinatorError("notify checkpoint completed failed",e,CheckpointCloseReason.CHECKPOINT_NOTIFY_COMPLETE_FAILED);return false;
}
(来自提交 #10705:CheckpointCoordinator.java)
影响范围
- Zeta 引擎 Exactly-once/Checkpoint 稳定性增强:失败更快、更一致地进入“可恢复/可终止”的状态机分支。
2.2 Zeta:防止“终态僵尸 job”在 master 切换后被恢复(#10692)
这类问题的典型危害是:
- job 实际已终止,但 HA 切换后被错误恢复 -> 重复写入/资源泄漏/状态污染。
该修复落在 CoordinatorService 与测试中(见提交清单)。
2.3 Zeta:避免 NPE(overviewMap 延迟初始化)(#10610)
属于典型的“监控/overview 结构在特定初始化顺序下为空”问题,修复点在 CheckpointMonitorService。
2.4 其他 Fix
-
10729:取消任务卡住、临时清理失败的防护(涉及引擎 + 文件 sink committer)
-
10674:Kingbase JDBC 容器测试偶发失败修复(E2E/CI 稳定性)
-
10745:Hazelcast 序列化相关测试稳定性增强
-
10754:CI 构建状态同步逻辑修复
3. 工程与架构改进
3.1 资源申请失败可观测增强(#10304)
资源不足时,传统错误往往只有“no enough resource”,无法指导运维定位是:
- 需要多少 slot
- 实际拿到多少
- 哪个 resourceProfile 首个失败
该 PR 在 ResourceRequestHandler 中构造更具体的 failureMessage(required/obtained/index/profile),并把异常更好地外显给上层(JobMaster 等)。
示例(截取关键构造逻辑):
String failureMessage =String.format("Apply resource not success for job: %d, required: %d slots, obtained: %d slots, "+ "first unassigned resource at index %d: %s",jobId,resourceProfile.size(),resultSlotProfiles.size(),failedIndex,resourceProfile.get(failedIndex));
LOGGER.warning(failureMessage);
completeRequestWithException(toExternalException(failureMessage, requestSlotWithRetryError));
(来自提交 #10304:ResourceRequestHandler.java)
影响范围
- 对“资源不足/worker 不可用/标签调度失败”的排障效率提升明显:错误信息从“抽象”变成“可执行”。
3.2 Zeta:本地 IDE 启动体验改善(#10742)
修改点在 seatunnel-engine-server/pom.xml,属于开发者体验优化:降低本地调试/启动摩擦。
3.3 Zeta:REST 提交任务异常日志增强(#10696)
提升异常输出质量,避免 REST 层吞掉关键堆栈或上下文。
3.4 文档体系化
4 月文档提交不只是“修错别字”,而是有明显的“体系化重构”趋势:
-
10785:onboarding + architecture docs 重组(英文/中文同步)
-
10728:批量修复 404 链接(大范围)
-
10577/#10707/#10719:补齐 API/CoordinatorService 的 Javadoc,降低阅读门槛
-
10704/#10769/#10737/#10741/#10683/#10713:连接器/引擎说明补充与纠错
影响范围
- 对“新用户快速上手”和“贡献者理解架构”是直接收益:文档从散点变为结构化入口。
4. 本月 PR 贡献者榜
| Rank | GitHub 用户名 | PR 数 | 主要贡献类型(计数) | 主要贡献范围(计数) | PR 列表 |
|---|---|---|---|---|---|
| 1 | yzeng1618 | 5 | feature×2, docs×2, fix×1 | connectors×2, engine×2, docs×1 | #10473 #10715 #10719 #10745 #10785 |
| 2 | davidzollo | 4 | fix×1, docs×1, improve×1, other×1 | ci×2, docs×1, other×1 | #10689 #10728 #10751 #10754 |
| 3 | zhangshenghang | 4 | docs×2, improve×1, chore×1 | docs×2, engine×1, other×1 | #10304 #10737 #10741 #10764 |
| 4 | nzw921rx | 3 | feature×2, improve×1 | e2e×1, engine×1, connectors×1 | #10609 #10742 #10743 |
| 5 | chl-wxp | 2 | improve×2 | docs×2 | #10704 #10769 |
| 6 | dybyte | 2 | fix×2 | engine×1, connectors×1 | #10610 #10674 |
| 7 | heye1005 | 2 | test×1, improve×1 | connectors×2 | #10701 #10778 |
| 8 | ricky2129 | 2 | feature×1, fix×1 | connectors×1, engine×1 | #10667 #10692 |
| 9 | zooo-code | 2 | docs×2 | api×2 | #10577 #10707 |
| 10 | corgy-w | 1 | fix×1 | connectors×1 | #10729 |
| 11 | hyboll | 1 | fix×1 | engine×1 | #10705 |
| 12 | jouzi5 | 1 | docs×1 | docs×1 | #10713 |
| 13 | liunaijie | 1 | improve×1 | connectors×1 | #10759 |
| 14 | xiaochen-zhou | 1 | improve×1 | engine×1 | #10696 |
5. 版本演进趋势与技术发展方向
- Connector 方向:更贴近生产复杂性
Doris 重定向链路增强、文件源连续发现、JDBC 定时 flush、RocketMQ OptionRule 补全,都是“线上更容易踩坑的边界条件”被产品化。 - Zeta 方向:稳定性与可观测优先
Checkpoint 通知失败收敛、HA 场景的僵尸 job 恢复防护、REST 异常日志增强、资源申请失败信息增强,体现了“让问题更可见、更可恢复”的路线。 - CDC 方向:把元数据作为一等公民
binlog/GTID/source timestamp 的透出,意味着后续更容易做端到端延迟治理、审计与血缘能力。 - Docs 方向:从“零散说明”走向“体系化架构入口”
10785 的大规模文档重组 + 多个 Javadoc PR,明显在为更大规模贡献者/用户群做准备。
附录:2026 年 4 月全部提交清单
- 2026-04-21 / #10729 / 2c81f7f / [Fix][Zeta] prevent cancel stuck and downgrade tmp cleanup failure
- 2026-04-21 / #10715 / 6af9ed0 / [Feature][Connectors-v2] Add Doris sink redirect enhancement
- 2026-04-21 / #10759 / 5111281 / [Improve][Connectors-v2][ORC] parse config on file level rather than field level
- 2026-04-20 / #10304 / 1d37f8c / [Improve][Engine] Enhance logging and exception handling for resource allocation failures
- 2026-04-19 / #10778 / 6d2a104 / Test/rocketmq restore e2e
- 2026-04-19 / #10743 / b9cdfeb / [Feature][E2E] Add MySQL CDC multi-database multi-table E2E test
- 2026-04-19 / #10705 / b70e84f / [Fix][Zeta] Converge notifyCompleted failure handling in CheckpointCoordinator
- 2026-04-19 / #10742 / b9b30b5 / [Improve][Zeta] Improve engine-server local IDE startup experience
- 2026-04-19 / #10785 / bf3eefe / [Docs] Reorganize SeaTunnel onboarding and architecture docs
- 2026-04-18 / #10577 / ac71b05 / [Docs][API] Add Javadoc to MultiTableSinkWriter
- 2026-04-16 / #10769 / ae8b96c / [Improve][Docs] Fix hive document error
- 2026-04-15 / #10764 / 39a25bd / [Chore][Tools] Add project PR submission skill
- 2026-04-14 / #10692 / 2ab8824 / [Fix][Zeta] Prevent terminal-state zombie jobs from being restored after master switch
- 2026-04-13 / #10754 / f3e5051 / [Fix][CI] Sync build status for recent PRs regardless of mergeable state
- 2026-04-12 / #10737 / 4752cee / [Docs][Connector-V2][Jdbc] Clarify save mode limitation in query mode
- 2026-04-12 / #10751 / 18c03db / Disable ASF Dependabot update PRs
- 2026-04-10 / #10741 / 8f03dfd / [Docs][Zeta] Clarify OSS checkpoint bucket URI format
- 2026-04-10 / #10745 / 26b30cf / [Fix][CI] Stabilize pipeline cleanup Hazelcast serialization test
- 2026-04-10 / #10609 / 4a8298d / [Feature][JDBC] Add batch_interval_ms option for JDBC Sink time-based flushing
- 2026-04-10 / #10689 / fc2d209 / [Improve][CI] Optimize update build status workflow
- 2026-04-09 / #10707 / df6ca72 / [Docs][Core] Add Javadoc to SupportResourceShare and MultiTableResourceManager
- 2026-04-09 / #10728 / 45127cd / [Docs] Fix 404 broken links in docs
- 2026-04-08 / #10704 / 93bba1a / [Improve][Docs] Iceberg connector adds parameter documentation related to Kerberos authentication
- 2026-04-08 / #10719 / 815cfc0 / [Docs][Core] Add Javadoc to CoordinatorService scheduling and HA flow
- 2026-04-06 / #10667 / 6dee790 / [Feature][CDC] Expose binlog file/pos/row, GTID, and SourceTimestamp …
- 2026-04-06 / #10713 / 9e7a0f6 / [Docs] Correct the key features in the zh documentation
- 2026-04-03 / #10610 / 1f81a8e / [Fix][Zeta] Prevent NPE by lazy initializing overviewMap
- 2026-04-03 / #10473 / 01cd08a / [Feature][Connector-V2] Add continuous discovery for FTP/SFTP/Local/HDFS file sources
- 2026-04-03 / #10696 / 9ad1832 / [Improve][Zeta] Enhance exception logging for task submission via RESTful API
- 2026-04-03 / #10701 / 7becf69 / [Improve][Connector-V2] Complete OptionRule declarations for RocketMQ source and sink
- 2026-04-02 / #10674 / b7a0fc5 / [Fix][E2E] Fix flaky CI failure in KingbaseDialectContainerTest
