每次 Stream Load 都成功,每批只有几十 KB,CPU 和磁盘也没有立刻打满。几小时后导入突然报 -235,业务以为遇到了随机故障。
它不是突然发生的。每个成功小批都在给同一批 Tablet 增加版本,Compaction 还债速度长期低于造债速度,拒写只是最后一道保护。
Doris 最怕的不是写得多,而是把每一小撮数据都当成一笔独立事务。
一分钟一万行和一秒一次并不是同一种负载
固定每分钟写入 60 万行:
| 写法 | 每分钟事务数 | 主要成本 | 典型结果 |
|---|---|---|---|
| 每秒 100 次,每次 100 行 | 6000 | FE 事务、Rowset、版本、发布 | Version 快速累积 |
| 每秒 1 次,每次 1 万行 | 60 | 批次延迟与客户端缓存 | 存储路径明显更健康 |
| Group Commit 合并小写入 | 由服务端窗口决定 | 等待窗口、WAL 或同步可见 | 客户端保持小写,服务端减少事务 |
总行数相同,版本生产速度可以相差两个数量级。扩容磁盘不能消除事务固定成本。
复现实验固定表结构、数据量和持续时间,只改变每批行数、每秒事务数以及是否启用 Group Commit,持续记录热点 Tablet 的 VersionCount 与 Compaction Score。
-235 前面的完整因果链
text
高频小批
→ 每批独立事务
→ 每个受影响 Tablet 产生新 Rowset 与 Version
→ 查询需要合并更多读取路径
→ Compaction 选择并重写 Rowset
→ 新版本产生速度长期高于合并速度
→ VersionCount 触及保护上限
→ 后续导入被 -235 拒绝
数据导入 FAQ 将 -235 定义为对应 Tablet 版本数超过上限,常见原因就是导入频率高于 BE Compaction 速度。它不是 Segment 过多的 -238,两者不能混调。
先找到哪块 Tablet 在欠债
止血前先做只读检查:
sql
SHOW TABLETS FROM target_table;
SHOW TABLET <tablet_id>;
继续执行 SHOW TABLET 返回的 ProcPath,重点比较各副本的 VersionCount。如果只有少数 Tablet 高,先查分桶热点和数据倾斜;如果全表同步上涨,优先查导入频率和 Compaction 能力。
同时在对应 BE 查看:
- Compaction Score 是否持续上升;
- Cumulative/Base Compaction 是否执行或报错;
- 磁盘空间、I/O、CPU 和内存是否成为限制;
- 导入批次、并发数和每批涉及的分区数量。
单看平均 Score 会隐藏一块即将拒写的热点 Tablet。
Group Commit 优秀在服务端合并事务
Group Commit 官方文档 描述的核心不是加速单批,而是让多个并发小写入共享一笔事务。相同 label 和 txnId 是写入被合并的直接证据。
sql
SET group_commit = async_mode;
INSERT INTO event_log VALUES (...);
INSERT INTO event_log VALUES (...);
sync_mode 等到合并事务可见后返回;async_mode 写入 WAL 后可先返回 PREPARE,可见性稍后发生。追求最低客户端延迟时,不能把收到响应误判成 SQL 已经可查。
Group Commit 也有明确边界:Stream Load 2PC、自定义 Label、部分列更新和显式事务可能绕过或回退普通路径;严格依赖提交顺序的 Unique Key 表还需要 Sequence。
止血不是调大上限
处理顺序应该是:
- 降低或暂停问题表的小批写入,让 VersionCount 是否下降成为第一项验证。
- 将客户端攒批,或在支持条件下启用 Group Commit。
- 检查 Compaction 是否被磁盘、内存、线程或错误卡住。
- 若仅单个 Tablet 热,修正 Bucket Key 或分区策略。
- 在灰度表重放同样负载,要求版本增速长期低于消化速度。
直接提高 max_tablet_version_num 只会推迟拒写,并让查询承担更多 Rowset 合并。直接增加 Compaction 线程可能与导入和查询争夺同一组 CPU、磁盘和内存。
源码只看版本保护与合并入口
在 Doris 4.0.8 中,源码阅读围绕三处:Tablet 元数据维护版本、写入发布前检查版本数量、Compaction 调度按 Score 选择 Tablet。再向下追 Rowset 选择策略,确认为什么某些尺寸差异过大的 Rowset 暂时不会被合并。
源码不能替代现场证据。只有把报错 Tablet、VersionCount、Compaction Score、任务日志和导入频率串起来,才能证明是版本债而不是磁盘故障或副本异常。
-235不是故障起点,而是 Doris 在版本债彻底失控前替你踩下的刹车。