架构设计 · 大数据运维

待环境验证

ClickHouse MergeTree 数据组织与建模

从排序键、分区与数据 Part 设计分析表,解释 ReplacingMergeTree、重试去重和 TTL 的正确性及合并成本。

ClickHouse大数据监控告警
阅读导引 · 理解后再操作

这篇知识解决什么问题

本篇围绕查询过滤、业务更新和写入批次选择 MergeTree 数据组织。先解释排序键与分区各自的职责,再区分最终合并、查询去重和重试去重;设计验收同时看结果正确性与 part 成本,不能只比较一次查询耗时。

排序与分区服从不同设计问题

排序键帮助组织相关行和使用稀疏索引,分区控制数据集合与维护范围。按高基数字段过细分区会产生大量 part;主键也不是唯一约束,必须用真实过滤路径和更新语义评价设计。

更新模型必须稳定识别同一实体

ReplacingMergeTree 根据完整 ORDER BY 识别相同记录,后台合并并不即时。可变字段进入排序键或分区会让版本无法按预期相遇,查询侧还需明确最终版本逻辑,不能用无限等待合并代替正确性。

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

图中的分片本地表是排序、分区与 part 的实际落点,同分片副本用于复制同一数据集合。图没有展开 ReplacingMergeTree 版本规则或具体保留策略,不能将复制箭头理解为去重,也不能从节点数估算逻辑行数。

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

ClickHouse 合并、副本与查询运维架构

联查 MergeTree parts、查询内存、复制队列和备份恢复,区分本地表、分片与副本,完成有界诊断和隔离验收。

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

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

ClickHouse 合并、副本与查询运维架构:组件关系图联查 MergeTree parts、查询内存、复制队列和备份恢复,区分本地表、分片与副本,完成有界诊断和隔离验收。 客户端 / Distributed → 分片本地表:路由与执行;分片本地表 → 同分片其他副本:数据副本同步;分片本地表 → Keeper 协调:复制协调;同分片其他副本 → Keeper 协调:副本进度协调;分片本地表 → 独立备份目的地:独立备份。箭头说明见下方流向解读。
逻辑参考图,待环境验证。以开源自建 ClickHouse 的 MergeTree / ReplicatedMergeTree 为主线,执行前 SELECT version() 并对照对应版本字段。ClickHouse Cloud 使用不同的存储与运维机制,应采用服务文档。

客户端 / Distributed

入口 / 来源

示意路由到目标分片,Distributed 自身不等同底层持久数据副本。

查看关联工具
全部组件职责 5 个组件
客户端 / Distributed
示意路由到目标分片,Distributed 自身不等同底层持久数据副本。工具介绍 客户端 / Distributed
分片本地表
保存当前分片的数据 parts,排序键与分区用于数据组织。工具介绍 分片本地表
同分片其他副本
复制同一分片的数据,不能当作额外不同分片计算总数据量。工具介绍 同分片其他副本
Keeper 协调
协调复制元数据;数据 parts 不通过 Keeper 存储。工具介绍 Keeper 协调
独立备份目的地
保存备份数据和所需元数据,完整性仍需恢复演练证明。
流向解读 5 条连接
  1. 1

    客户端 / Distributed 分片本地表

    数据 / 请求 · 路由与执行

    本地表执行当前分片查询;跨分片聚合由入口查询计划协调。

  2. 2

    分片本地表 同分片其他副本

    数据 / 请求 · 数据副本同步

    示意同一复制组间获取数据 parts,不意味着所有写入必须先经过这个节点。

  3. 3

    分片本地表 Keeper 协调

    控制 / 管理 · 复制协调

    本地副本使用协调服务维护复制元数据。

  4. 4

    同分片其他副本 Keeper 协调

    控制 / 管理 · 副本进度协调

    其他副本独立维护复制进度和协调会话。

  5. 5

    分片本地表 独立备份目的地

    数据 / 请求 · 独立备份

    按经过核实的备份范围持久保存可恢复来源。

故障域与操作边界

适用版本与部署模式

以开源自建 ClickHouse 的 MergeTree / ReplicatedMergeTree 为主线,执行前 SELECT version() 并对照对应版本字段。ClickHouse Cloud 使用不同的存储与运维机制,应采用服务文档。

数据与变更边界

不自动执行 OPTIMIZE FINAL、删除 parts、重建 Keeper 路径或生产 RESTORE。分片分摊数据,副本复制数据;Distributed 表不凭自身保存底层全部数据。

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

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

适用范围与建模目标

本文讨论自建 ClickHouse 中 MergeTree 家族的分析表设计,覆盖排序键、分区、数据 part、更新去重与生命周期。示例使用通用 MergeTree SQL,并以在线官方文档核对语义;执行前仍需记录 SELECT version() 和现有表结构。ClickHouse Cloud 的 SharedMergeTree、自动扩缩容和存储管理需要采用相应产品文档。

建模从三份材料开始:主要查询的过滤条件与聚合维度、写入批次与峰值、保留及更新规则。下面 DDL 只供隔离沙箱评审,元数据查询限定为一张表,未运行实际建表或压测,验证等级为 PENDING。

排序键不是唯一约束

MergeTree 将写入的数据组织为多个不可变 part,后台逐步合并。part 内按 ORDER BY 排序,主键建立稀疏索引以帮助跳过无需读取的粒度;如果省略 PRIMARY KEY,排序键同时作为主键。它不提供关系数据库主键那样的唯一性约束,重复业务 ID 可以同时存在。

选择排序键时,优先考虑实际高频过滤路径,再考虑列的基数与压缩效果。对「租户加时间范围」查询,以租户开头通常值得评估;若大多数查询跨租户按时间检索,同一设计可能缺乏优势。主键越长也不一定越好,索引大小、写入成本与扫描缩减应一起比较。MergeTree 原理

分区控制数据组织和维护范围

分区把 part 归入不同集合,后台合并不会跨分区进行。分区键首先应服务于保留、装载和分区管理,不应为了每个查询条件建出大量细分区。按租户 ID 或精确时间戳分区容易产生大量小 part,并增加文件与合并管理成本。

月分区适合部分长期时间序列,短保留或日级替换场景可以评估日分区,但没有全业务通用的粒度。分区裁剪能够减少相关范围,分区键却不能替代排序键带来的数据跳过能力。对一个月份内仍要扫描大量数据的查询,应继续检查排序和过滤路径。

一个追加事件表的设计示例

以下演示表用于不可变事件明细,假设 sandbox 是已经建立的隔离数据库;同名表不存在时才纳入演练。它没有自动去重、删除或复制配置。

CREATE TABLE sandbox.events_design_demo
(
    tenant_id UInt32,
    event_id UInt64,
    event_time DateTime('UTC'),
    event_type LowCardinality(String),
    amount Decimal(18, 2)
)
ENGINE = MergeTree
PARTITION BY toYYYYMM(event_time)
ORDER BY (tenant_id, event_time, event_id);

金额使用定点小数表达明确精度,事件类型在低基数前提下考虑 LowCardinality。event_id 放在末尾不意味着全局唯一;如果查询经常只按它定位,需评估额外访问路径。生产容量、金额范围和时间精度都应根据业务修订,不能用演示类型截断真实数据。

从 Part 数量解释写入成本

每次小批次写入都可能带来新的 part,写入持续超过后台合并能力时,part 会积累。大批次也有延迟和客户端内存代价,应在有限样本中选择合适批次,并单独核对异步插入的确认与重试语义。

SELECT partition, count() AS active_parts,
       sum(rows) AS physical_rows,
       sum(bytes_on_disk) AS bytes_on_disk
FROM system.parts
WHERE database = 'REPLACE_WITH_DATABASE'
  AND table = 'REPLACE_WITH_TABLE' AND active
GROUP BY partition
ORDER BY active_parts DESC
LIMIT 12
SETTINGS max_execution_time = 5, max_threads = 2;

这是单节点元数据汇总,不是全分片逻辑行数。active 避免把已被替代的 part 混入当前数据量;物理行数对 ReplacingMergeTree 仍可能包含多个版本。LIMIT 只限制结果数量,应配合表过滤和执行预算,不能宣称只处理了 12 条元数据。system.parts

ReplacingMergeTree 的更新与去重边界

ReplacingMergeTree 在合并时按完整 ORDER BY 值识别相同记录,有版本列时按版本规则保留记录。它提供最终合并行为,不保证写入后立刻唯一;后台合并时间不可作为查询正确性的承诺。需要当前版本视图的查询,应评估 FINAL 或明确的版本聚合逻辑。

CDC 模型必须让同一业务实体的排序键保持稳定。把会改变的状态、更新时间放入排序键,会使新旧版本成为不同实体;把可变时间用作分区,也可能让版本分散到永不后台合并的不同分区。版本号应有可比较的顺序和冲突处理,不把不稳定到达次序当成业务最新状态。ReplacingMergeTree 语义

插入重试去重不是业务去重

写入去重主要用于一定窗口内识别重试的数据块,受引擎、设置、去重窗口和批次构造影响。将同一批数据换一种切分、顺序或生成方式重新发送,不能默认仍被识别;窗口过期也不能提供永久去重保证。

应保存生产端批次 ID、业务事件 ID 和每次请求结果,对超时但提交状态不明的批次单独核对。物化视图及异步插入还存在额外设置与版本边界,不能因为源表看起来不重复,就推断下游汇总也没有重复。跨系统管道的幂等设计需要与 Flink Sink 的实际交付语义一起验收。插入重试去重

TTL 与合并的运行代价

TTL 可以删除行、处理列或迁移数据,通常在后台合并过程中执行,并非到期瞬间的可见性保证。如果查询要求严格排除过期数据,应在业务查询层明确时间条件。缩短 TTL 会影响历史可恢复数据,改回旧规则无法找回已经删除的记录。

不要把 OPTIMIZE TABLE ... FINAL 当作日常小 part、去重或 TTL 的通用补救。它会强制重写大量数据,可能绕过后台合并的保护性选择并形成很大的 part;资源不足时进一步放大压力。查询中的 FINAL 与强制物理合并不是同一种操作。TTL 机制避免频繁 OPTIMIZE FINAL

设计验收、误区与回退

在固定且有限的数据集上比较代表性查询的读取行数、字节、耗时与内存,同时记录写入延迟、part 增长和压缩效果。更新模型增加乱序版本、重复重试与跨月变更样本,验收逻辑最新值而非只看物理行数。排序键或分区调整应先使用独立候选表验证并保留旧表及源数据。

常见误区是把分区数量当作并行能力、把主键当作唯一约束,以及认为后台最终会合并就无需查询去重。若候选表无法正确表达更新、part 增长失控或原始重放来源不完整,停止迁移。回退可以恢复读取旧表,但新写入和已删除历史需要明确同步或重放方案,不能仅改表名宣称数据已经回到原点。

后续可阅读查询与内存诊断副本与备份运维

参考资料

从现象到判断

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

  1. 单表 active parts 持续增长,每个 part 很小,写入批次频繁且分区数较多。

    只读核对
    按目标分区读取 system.parts 汇总,关联批次大小、写入频率、后台合并和 I/O。
    如何判读
    可能是微批与过细分区共同放大管理成本;应先控制增长来源,不默认强制全表合并。
  2. 使用 ReplacingMergeTree 后,同一业务 ID 仍查出多个版本,部分记录跨月分布。

    只读核对
    核对完整排序键、分区表达式、版本列与查询 FINAL 或版本聚合逻辑。
    如何判读
    可能是尚未合并,也可能实体键或分区不稳定;后台合并不跨分区,不能只增加等待时间。
  3. 生产端认为只是重试,目标明细或下游汇总却出现额外记录。

    只读核对
    核对业务事件 ID、请求批次、数据块顺序、去重窗口和下游物化视图设置。
    如何判读
    插入重试去重有窗口和批次前提,不等于永久业务去重;源表和下游结果需要分别对账。
常见误区与判断边界 2 项

把 MergeTree 主键当作唯一约束

主键用于稀疏索引,同一业务 ID 可以存在多行。追加事件与可更新实体应分别选择模型,不能把业务重复判定交给一个没有唯一性保证的键声明。

靠每日 OPTIMIZE FINAL 修补建模

强制合并会重写大量数据并改变资源压力,无法修复错误实体键或永久去重缺失。先改善写入与表设计,TTL 与查询 FINAL 的语义也应分开,避免把所有问题都变成物理合并任务。

交接时应留下的证据

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

  • 固定表引擎、版本、排序键、分区键、更新顺序及主要查询过滤路径。
  • 保留样本写入批次、part 数量与大小、压缩效果和后台合并变化。
  • 归档乱序版本、重复重试、跨月变更与过期样本的逻辑预期及真实查询结果。
  • 记录候选表与旧表的结果和资源对照、重放来源及新写入回退方案。

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

继续阅读与资料核对

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

返回原理导读

DOUYA OPS ECOSYSTEM

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

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