
https://github.com/apache/
点击蓝字
关注我们
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. 当月功能特性梳理
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);}执行请求时跟踪最后一次 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
影响范围
在文件同步场景中,“一次性扫描”不够用,用户往往需要:
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); }}.../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; }}来自提交 #10473:.../ContinuousMultipleTableFileSourceSplitEnumerator.java
影响范围
batch_interval_ms 定时 flush(#10609)JDBC Sink 以往主要依赖 batch_size 达到阈值时刷写;这会造成一个典型问题:
该 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
影响范围
在 CDC 同步中,很多用户需要拿到“事件来自哪里、位点是多少、源端时间戳”等信息,用于:
该 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
影响范围
2. 当月 Bug 修复梳理
问题类型: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
影响范围
这类问题的典型危害是:
该修复落在 CoordinatorService 与测试中(见提交清单)。
属于典型的“监控/overview 结构在特定初始化顺序下为空”问题,修复点在 CheckpointMonitorService。
3. 工程与架构改进
资源不足时,传统错误往往只有“no enough resource”,无法指导运维定位是:
该 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
影响范围
修改点在 seatunnel-engine-server/pom.xml,属于开发者体验优化:降低本地调试/启动摩擦。
提升异常输出质量,避免 REST 层吞掉关键堆栈或上下文。
4 月文档提交不只是“修错别字”,而是有明显的“体系化重构”趋势:
影响范围
4. 本月PR贡献者榜

5. 版本演进趋势与技术发展方向
Connector 方向:更贴近生产复杂性
Zeta 方向:稳定性与可观测优先
CDC 方向:把元数据作为一等公民
Docs 方向:从“零散说明”走向“体系化架构入口”
Apache SeaTunnel是一个云原生的多模态、高性能海量数据集成工具。北京时间 2023 年 6 月1 日,全球最大的开源软件基金会ApacheSoftware Foundation正式宣布SeaTunnel毕业成为Apache顶级项目。目前,SeaTunnel在GitHub上Star数量已达9k+,社区达到7000+人规模。SeaTunnel支持在云数据库、本地数据源、SaaS、大模型等170多种数据源之间进行数据实时和批量同步,支持CDC、DDL变更、整库同步等功能,更是可以和大模型打通,让大模型链接企业内部的数据。
同步Demo
新手入门

最佳实践

测试报告

源码解析



