Apache SeaTunnel 4 月有何新动作?连接器增强与 Zeta 稳定性提升等亮点速览

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 等诊断字段):

    java 复制代码
    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 时包装成更可读的异常:

    java 复制代码
    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。

关键实现片段:

  • 新的枚举模式:

    java 复制代码
    public enum FileDiscoveryMode implements Serializable {
        ONCE,
        CONTINUOUS
    }

    (来自提交 #10473:.../FileDiscoveryMode.java

  • Continuous Enumerator 的核心机制:定时扫描、将新 split 入队、把 state 控制在 in-flight 范围(避免无限增长):

    java 复制代码
    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 风暴:

    java 复制代码
    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 完成前生效"):

java 复制代码
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 标记可透传元数据集合。

示例:

java 复制代码
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 的错误处理路径:

java 复制代码
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 等)。

示例(截取关键构造逻辑):

java 复制代码
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 月全部提交清单

  1. 2026-04-21 / #10729 / 2c81f7f / [Fix][Zeta] prevent cancel stuck and downgrade tmp cleanup failure
  2. 2026-04-21 / #10715 / 6af9ed0 / [Feature][Connectors-v2] Add Doris sink redirect enhancement
  3. 2026-04-21 / #10759 / 5111281 / [Improve][Connectors-v2][ORC] parse config on file level rather than field level
  4. 2026-04-20 / #10304 / 1d37f8c / [Improve][Engine] Enhance logging and exception handling for resource allocation failures
  5. 2026-04-19 / #10778 / 6d2a104 / Test/rocketmq restore e2e
  6. 2026-04-19 / #10743 / b9cdfeb / [Feature][E2E] Add MySQL CDC multi-database multi-table E2E test
  7. 2026-04-19 / #10705 / b70e84f / [Fix][Zeta] Converge notifyCompleted failure handling in CheckpointCoordinator
  8. 2026-04-19 / #10742 / b9b30b5 / [Improve][Zeta] Improve engine-server local IDE startup experience
  9. 2026-04-19 / #10785 / bf3eefe / [Docs] Reorganize SeaTunnel onboarding and architecture docs
  10. 2026-04-18 / #10577 / ac71b05 / [Docs][API] Add Javadoc to MultiTableSinkWriter
  11. 2026-04-16 / #10769 / ae8b96c / [Improve][Docs] Fix hive document error
  12. 2026-04-15 / #10764 / 39a25bd / [Chore][Tools] Add project PR submission skill
  13. 2026-04-14 / #10692 / 2ab8824 / [Fix][Zeta] Prevent terminal-state zombie jobs from being restored after master switch
  14. 2026-04-13 / #10754 / f3e5051 / [Fix][CI] Sync build status for recent PRs regardless of mergeable state
  15. 2026-04-12 / #10737 / 4752cee / [Docs][Connector-V2][Jdbc] Clarify save mode limitation in query mode
  16. 2026-04-12 / #10751 / 18c03db / Disable ASF Dependabot update PRs
  17. 2026-04-10 / #10741 / 8f03dfd / [Docs][Zeta] Clarify OSS checkpoint bucket URI format
  18. 2026-04-10 / #10745 / 26b30cf / [Fix][CI] Stabilize pipeline cleanup Hazelcast serialization test
  19. 2026-04-10 / #10609 / 4a8298d / [Feature][JDBC] Add batch_interval_ms option for JDBC Sink time-based flushing
  20. 2026-04-10 / #10689 / fc2d209 / [Improve][CI] Optimize update build status workflow
  21. 2026-04-09 / #10707 / df6ca72 / [Docs][Core] Add Javadoc to SupportResourceShare and MultiTableResourceManager
  22. 2026-04-09 / #10728 / 45127cd / [Docs] Fix 404 broken links in docs
  23. 2026-04-08 / #10704 / 93bba1a / [Improve][Docs] Iceberg connector adds parameter documentation related to Kerberos authentication
  24. 2026-04-08 / #10719 / 815cfc0 / [Docs][Core] Add Javadoc to CoordinatorService scheduling and HA flow
  25. 2026-04-06 / #10667 / 6dee790 / [Feature][CDC] Expose binlog file/pos/row, GTID, and SourceTimestamp ...
  26. 2026-04-06 / #10713 / 9e7a0f6 / [Docs] Correct the key features in the zh documentation
  27. 2026-04-03 / #10610 / 1f81a8e / [Fix][Zeta] Prevent NPE by lazy initializing overviewMap
  28. 2026-04-03 / #10473 / 01cd08a / [Feature][Connector-V2] Add continuous discovery for FTP/SFTP/Local/HDFS file sources
  29. 2026-04-03 / #10696 / 9ad1832 / [Improve][Zeta] Enhance exception logging for task submission via RESTful API
  30. 2026-04-03 / #10701 / 7becf69 / [Improve][Connector-V2] Complete OptionRule declarations for RocketMQ source and sink
  31. 2026-04-02 / #10674 / b7a0fc5 / [Fix][E2E] Fix flaky CI failure in KingbaseDialectContainerTest
相关推荐
智能相对论1 小时前
应用“深水区”正在被攻克,轮足机器人迎来拐点时刻
大数据·人工智能·机器人
Volunteer Technology1 小时前
HDFS源码(二)
大数据·hadoop·hdfs
xixixi777771 小时前
《从心理诱导突破Claude到AI仿冒直播首张拘留单:AI安全、监管与商用的三重转折点》
大数据·网络·人工智能·安全·ai·大模型·风险
立控信息LKONE1 小时前
门禁机、控制器等库室安防设施、实现库室智能联动,一体报警
大数据·人工智能·安全
小真zzz1 小时前
中立第三方:搜极星的突围之路
大数据·人工智能
yzx9910131 小时前
软件脚本定制开发:从需求到交付的技术实战指南
大数据·人工智能·数据挖掘
Yolo566Q1 小时前
环境土壤物理模型HYDRUS1D/2D/3D实践技术应用系统性学习
大数据·开发语言·gpt·学习·arcgis·r语言
T06205142 小时前
【数据集】上市公司企业业务招待费数据 (2012-2024年)
大数据
承渊政道2 小时前
Oracle迁移避坑:一个(+)写错,LEFT JOIN可能变INNER JOIN
运维·服务器·数据库·数据仓库·学习·安全·oracle