
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
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)
影响范围
在文件同步场景中,“一次性扫描”不够用,用户往往需要:
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;
}
}
(同上)
影响范围
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)
影响范围
问题类型: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。
资源不足时,传统错误往往只有“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 月文档提交不只是“修错别字”,而是有明显的“体系化重构”趋势:
影响范围
| 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 |
来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/70049562/viewspace-3117502/ ,如需转载,请注明出处,否则将追究法律责任。