最佳实践 · 大数据运维

待环境验证

Doris、StarRocks 与 ClickHouse 指标一致性对账

围绕共同快照、业务键、时区、NULL、金额精度与维表版本建立跨引擎对账,避免用总额相等掩盖重复、遗漏和口径差异。

Apache DorisClickHouseStarRocks大数据
阅读导引 · 理解后再操作

这篇知识解决什么问题

先统一输入窗口与业务口径,再比较 Doris、StarRocks 和 ClickHouse 的指标。对账围绕业务键、时区、NULL、固定精度和维度版本逐层下钻,不用总数或总额相同代替完整性证明。

同指标必须先有同输入与同语义

事件明细、当前状态和增量汇总具有不同粒度,相近查询时间也不构成共同快照。先冻结可信窗口并对齐位点、删除与去重口径,再比较结果,避免把自然的版本差异误判为引擎错误。

结果差异要能回到业务键

相同总额可能存在正负抵消,相同行数也可能一漏一重。应从日期、租户、稳定桶逐层比较键集合和字段,哈希仅辅助定位,并明确序列化、NULL 标记与算法,不能直接比较各引擎默认 hash。

进入文章正文
关联架构图解5 个组件 · 点击展开

这里借用 Doris 场景图核对其中一侧的查询入口、可见性和执行证据,它是单侧逻辑图,不是跨库同步图。StarRocks、ClickHouse 的源端位点、视图刷新与回填状态必须另行留证,图中没有跨引擎共同事务快照保证。

查看场景架构与实施步骤
参考架构 · 非实时拓扑

Doris 集群巡检与导入查询治理架构

从 FE 元数据、BE 副本、导入事务与查询 Profile 建立 Doris 分层巡检,验证数据可见性、容量余量与小范围调优效果。

  • 数据 / 请求
  • 控制 / 管理
  • 观测 / 查询

点击组件,在图下方查看职责;连线编号对应流向解读。小屏可横向滚动,或直接展开文字说明。

Doris 集群巡检与导入查询治理架构:组件关系图从 FE 元数据、BE 副本、导入事务与查询 Profile 建立 Doris 分层巡检,验证数据可见性、容量余量与小范围调优效果。 业务与导入客户端 → FE 元数据与协调:请求与事务协调;FE 元数据与协调 → BE 执行与存储:计划与事务调度;BE 执行与存储 → 其他 BE 副本:Tablet 副本关系;FE 元数据与协调 → 巡检证据:角色与事务记录;BE 执行与存储 → 巡检证据:容量与执行证据。箭头说明见下方流向解读。
逻辑参考图,待环境验证。以 Doris 3.x 存算一体集群为主线,记录 FE Master、Follower、Observer 和 BE 故障域。存算分离另含 Meta Service、共享存储和计算组,不可套用本流程的本地副本判断。

业务与导入客户端

入口 / 来源

记录查询、导入批次和业务键,驱动 FE 协调;HTTP 导入数据路径取决于具体方式。

全部组件职责 5 个组件
业务与导入客户端
记录查询、导入批次和业务键,驱动 FE 协调;HTTP 导入数据路径取决于具体方式。
FE 元数据与协调
解析计划、管理元数据和导入事务;Observer 不参加选举。工具介绍 FE 元数据与协调
BE 执行与存储
存算一体模式承载查询、导入和 Tablet;不把本图用于共享存储模式。工具介绍 BE 执行与存储
其他 BE 副本
同 Tablet 副本分布到其他节点,用健康状态和版本而非心跳判断冗余。工具介绍 其他 BE 副本
巡检证据
关联管理状态、算子耗时和业务可见性,给出问题影响范围。
流向解读 5 条连接
  1. 1

    业务与导入客户端 FE 元数据与协调

    数据 / 请求 · 请求与事务协调

    客户端入口与管理协调关系;不是所有导入字节都经 FE 转发。

  2. 2

    FE 元数据与协调 BE 执行与存储

    控制 / 管理 · 计划与事务调度

    FE 向 BE 分配执行任务并协调可见性。

  3. 3

    BE 执行与存储 其他 BE 副本

    数据 / 请求 · Tablet 副本关系

    示意同一数据的跨节点冗余,具体写入路径按导入协议核验。

  4. 4

    FE 元数据与协调 巡检证据

    观测 / 查询 · 角色与事务记录

    保存元数据角色、批次和提交状态。

  5. 5

    BE 执行与存储 巡检证据

    观测 / 查询 · 容量与执行证据

    保存节点水位与有界查询 Profile。

故障域与操作边界

适用版本与部署模式

以 Doris 3.x 存算一体集群为主线,记录 FE Master、Follower、Observer 和 BE 故障域。存算分离另含 Meta Service、共享存储和计算组,不可套用本流程的本地副本判断。

数据与变更边界

本场景不包含强制选主、直接删除 Tablet、取消状态不明的事务或生产压测。Observer 不参与选主,增加 Observer 不能修复选举多数派。

架构依据与版本核对 2 篇官方资料

图解是本站基于官方资料整理的逻辑参考;实施前仍需核对实际部署版本、组件支持范围与变更审批。

适用范围与共同基线

本文用于 Doris 3.x、StarRocks 3.3+ 与 ClickHouse 之间的同口径 OLAP 对账,适合迁移、双读和物化视图验收。所有操作先核对实际版本、表模型与设置;示例基于隔离的规范化样本,不假定三个引擎处于同一个事务快照。本文不执行 SQL,验证等级保持 PENDING。

对账开始前写清指标:统计事件还是订单当前状态,金额是分值增量还是修订总额,按事件时维度还是当前维度归类。再固定源快照、截止位点、时间窗口、币种和去重规则。两个查询都叫“交易额”,并不证明它们回答同一个业务问题。

先证明读取的是同一批输入

分别记录源端范围与各引擎确认可见的进度,不能用查询开始时间相近冒充共同快照。Doris 事务已提交但未可见、StarRocks 视图尚未刷新、ClickHouse 历史回填未完成,都可能产生时间性差异。

用于验证的封闭窗口应包含一份确定的输入清单,并确保后续修订已冻结或被排除。事件数、去重后业务键数、删除数和有效状态数分别统计。若一侧保存事件而另一侧按主键覆盖,先还原到共同粒度,再比较指标,模型背景见 Doris 表设计

时区、时间精度与日期边界

保存原始时间字符串或 epoch、单位、来源时区和目标字段精度。毫秒当秒会改变数量级;把不带时区的墙钟时间当 UTC,也会把边界事件分到错误日期。日报应先定义业务时区,再转换为明确的左闭右开 UTC 区间。

Doris 与 StarRocks 可用 CONVERT_TZ 进行明确转换,但不能假设更改会话时区会自动修复已入库的 DATE/DATETIME 值。ClickHouse DateTime64 的精度与时区属性也要单独记录。依据见 Doris 时区StarRocks 时区DateTime64

边界样本至少包含区间起点、终点前的最小精度单位、终点以及夏令时切换附近事件。不要假定所有本地自然日都等于 24 小时,也不要在双方使用不同精度的 BETWEEN 上下界。时区转换规则和数据库时区数据版本应随对账记录保存。

NULL、空串和未匹配维度

COUNT(*) 统计行数,COUNT(amount) 排除 amount 为 NULL 的行,SUM 对空集合或全 NULL 的返回还需按具体查询类型核验。先单列 NULL 数量,再决定是否把缺失值转为零;默认填零会掩盖导入映射失败。

ClickHouse 外连接未匹配值受 join_use_nulls 影响,可能是 NULL,也可能是数据类型默认值。若一侧用 NULL 判断未匹配,另一侧得到 0 或空串,分类指标会出现差异。应核对会话设置并使用可辨识的匹配标记,参见 ClickHouse Join 建议。不能未经证明就认定合法维度键 0 等于“未知”。

金额、除法与聚合精度

优先使用明确币种的整数最小单位或固定精度 Decimal 保存金额,并记录乘除发生在聚合前还是聚合后、舍入位数与方式。逐行四舍五入再 SUM 与先 SUM 再舍入可能不同,不能随意放大误差容忍度来消除差异。

固定精度也有溢出与缩放边界。ClickHouse Decimal 除法的缩放和精度规则不能直接按浮点结果推断,整数与 Decimal 混合表达式亦需核验,见 Decimal 运算。平均值应保留分子与分母,避免再次平均各分区平均值;精确去重也不应与 HLL、bitmap 或近似函数的结果未经约定直接比较。

在隔离快照上建立小范围指纹

假设三个引擎各自已有经过核对的 lab.recon_snapshot,列含相同 snapshot_id、UTC 日期、租户、稳定 bucket_id、事件键及可空整数分值。每个桶的输入规模已登记,示例只检查一个桶:

SELECT COUNT(*) AS rows_all,
       COUNT(amount_minor) AS rows_with_amount,
       SUM(CASE WHEN amount_minor IS NULL THEN 1 ELSE 0 END) AS rows_null,
       SUM(CAST(amount_minor AS DECIMAL(38, 0))) AS total_minor
FROM lab.recon_snapshot
WHERE snapshot_id = 'recon_20260901_v1'
  AND event_day_utc = '2026-09-01'
  AND tenant_id = 42 AND bucket_id = 7;

输入金额和汇总值必须先证明落在类型范围内。若约定样本为 100 行、2 行 NULL,则 rows_with_amount 应为 98、rows_null 为 2;总额需与独立来源核对。这里列名和类型是前置契约,不是让同一 SQL 直接作用于三套不同生产表。

从指标差异下钻到业务键

先按日期和租户对比,再对异常桶比较事件键集合,最后查看同键的版本、金额、删除和维度。总数相同可能存在一漏一重,总额相同也可能存在正负抵消。应分类记录缺失键、多余键和相同键字段不一致,避免直接把所有差异归为延迟。

哈希仅能辅助定位,不能替代原始键检查。跨引擎直接对比默认 hash 函数值没有意义,算法、字符编码、NULL 标记、Decimal 序列化和字段顺序都可能不同。若需要指纹,应由共同规范定义字节表示和算法,并保留少量可回溯明细。

维表更新与物化时间

对账需要约定维度采用事件发生时版本还是查询时最新版本。ClickHouse 增量视图中的右表更新不会追溯触发已生成结果;Doris、StarRocks 异步视图则需要观察刷新覆盖与时间。不能用“源表最终相同”推断物化结果马上相同,机制见 ClickHouse 增量视图

准备一个商户分类从 A 改为 B 的样本,同时保存变化前后事件与维表版本。若双方总金额相同但 A、B 分类相反,应先核对物化与关联时间,而不是立即重导事实表。基表基线还要确认没有透明重写到同一个待验视图。

验收、停止与恢复

通过条件是约定输入窗口、业务键集合、NULL 数量、金额、分类和数据截止点都能解释;容许误差仅用于事先约定的近似计算或浮点指标,不能掩盖确定性的缺失。每条差异都应带来源快照、SQL、设置、查询 ID 与归因依据。

若窗口仍变化、源端位点不明、数据类型溢出或基线不独立,停止发布“已对平”结论。保留两侧原始结果和旧读路径,优先修正转换或口径后重新建立样本。对账本身不修复数据;补写、删除和重新回填应使用独立方案,避免在差异原因未知时破坏证据。相关实践见 Doris 视图刷新StarRocks 新鲜度ClickHouse 回填

参考资料

从现象到判断

先收集证据,再缩小范围。以下是判读路径,不代表已经确认根因或获准变更。

  1. 总额只在日界线附近不一致,区间中间的业务键可以对上。

    只读核对
    核对时间戳单位、来源时区、字段精度和左右边界,检查夏令时及入库转换规则。
    如何判读
    可能是同一瞬间被分入不同业务日期,更改会话时区不一定能修复已入库值。
  2. 行数一致,但金额非空数或未匹配维度数量不同。

    只读核对
    比较 COUNT(*)、COUNT(amount)、NULL 数,核对 ClickHouse join_use_nulls 与双方默认值处理。
    如何判读
    可能是 NULL、空串或外连接标记的语义差异,统一填零会掩盖真正的映射缺口。
  3. 整体金额吻合,分类报表不同,差异与一次维表修订相邻。

    只读核对
    固定维表版本,核查各侧使用事件时关联、查询时关联还是已物化结果,并确认刷新与回填范围。
    如何判读
    可能是维度时间口径不一致,不能因为源表现状相同就要求所有物化结果立即相同。
常见误区与判断边界 2 项

扩大误差范围掩盖缺失

整数金额、业务键和确定性计数的差异应精确解释。容差只用于事先约定的浮点或近似指标,且保留分子分母与舍入顺序;不能以大范围误差把溢出、重复或遗漏一并判为通过。

对账途中直接补写修数

窗口仍变化或根因未知时修改数据会破坏原始证据,使后续无法分辨转换差异与人为修复。先保存两侧查询、设置和结果,修复或回填用独立方案,再以新的明确快照验收。

交接时应留下的证据

作为记录提纲使用,不是自动检查结果;未取得的证据应标记缺口,并注明负责人。

  • 保存指标粒度、源快照、各侧可见位点、删除和去重规则,说明共同窗口如何保持封闭。
  • 记录时区、时间单位、字段精度、NULL 与外连接设置,以及金额缩放、舍入和溢出边界。
  • 按日期、租户与稳定桶归档键集合和字段差异,关联维表版本、物化时点与查询 ID。
  • 交接差异类别、原始样本、允许容差依据和旧读路径,未知原因未关闭前不宣告已对平。

记录需包含环境、版本、时间与时区;分享前脱敏,不附访问令牌、密码或完整业务敏感数据。

继续阅读与资料核对

补充相关主题,再结合当前环境的实施记录形成结论。

返回原理导读

DOUYA OPS ECOSYSTEM

贡献你的经验,帮助更多运维人

把故障复盘、标准流程和最佳实践沉淀为可检索、可复用的知识内容。