在 ClickHouse 的高级功能中,GraphiteMergeTree 是一个专门为 监控系统(Monitoring)和时间序列数据 优化的表引擎。它源自对 Graphite 数据模型 的深度支持,能够自动对时间序列指标进行降采样(Downsampling)与聚合,非常适合 Prometheus、Grafana、自研监控系统等场景。
本篇将全面详解 GraphiteMergeTree 的设计目标、工作原理、配置方法和最佳实践。
🌟 一、什么是 GraphiteMergeTree?
✅ 定义
GraphiteMergeTree 是 MergeTree 的一个变种,专为存储和查询 Graphite 风格的时间序列数据 而设计。它支持:
- 自动按时间窗口对指标进行预聚合
- 根据精度要求存储不同粒度的数据(如原始数据 + 汇总数据)
- 基于配置规则的降采样策略
📌 简单理解:
GraphiteMergeTree= 时间序列存储 + 自动降采样 + 多精度聚合
🏗️ 二、为什么需要 GraphiteMergeTree?
典型监控场景的挑战:
| 问题 | 描述 |
|---|---|
| 数据量巨大 | 每秒百万级指标点(如 CPU、内存) |
| 查询跨度大 | 查最近 1 小时(高精度) vs 查最近 1 年(低精度) |
| 存储成本高 | 原始数据长期保存不现实 |
| 查询性能差 | 大时间范围聚合慢 |
✅ 解决方案:降采样(Downsampling)
- 高精度数据:保留 7 天(每 10 秒一个点)
- 中精度数据:保留 90 天(每 1 分钟平均值)
- 低精度数据:保留 1 年(每 1 小时最大值)
GraphiteMergeTree 自动完成这一过程,无需外部 ETL。
🧩 三、数据模型:Graphite 的路径结构
Graphite 使用 分层路径命名 指标,例如:
servers.web01.cpu.usage
servers.web01.memory.used
services.api.latency.p99
ClickHouse 中通常用以下结构存储:
CREATE TABLE metrics (
Path String, -- 如 'servers.web01.cpu.usage'
Time DateTime, -- 时间戳
Value Float64, -- 指标值
Version UInt32 -- 版本(用于去重)
) ENGINE = GraphiteMergeTree(...)
ORDER BY (Path, Time);
🔧 四、GraphiteMergeTree 的语法
CREATE TABLE metrics_downsampled (
Path String,
Time DateTime,
Value Float64,
Version UInt32
) ENGINE = GraphiteMergeTree(
'graphite_config_name' -- 指向 config.xml 中的 graphite_rollup 配置
)
ORDER BY (Path, Time);
关键点:
graphite_config_name是一个在config.xml中定义的 rollup 策略名称- 必须配合
ORDER BY (Path, Time)使用
⚙️ 五、配置降采样策略(graphite_rollup)
在 config.xml 中定义聚合规则:
<graphite_rollups>
<graphite_config_name> <!-- 与表中引用的名称一致 -->
<!-- 规则 1:匹配所有指标,10秒原始数据 -->
<pattern>
<regexp>.*</regexp>
<function>any</function> <!-- 原始值 -->
<retention>
<age>0</age> <!-- 从 0 秒开始 -->
<precision>10</precision> <!-- 每 10 秒存一个点 -->
</retention>
</pattern>
<!-- 规则 2:60秒聚合,保留90天 -->
<pattern>
<regexp>.*</regexp>
<function>max</function> <!-- 取最大值 -->
<retention>
<age>604800</age> <!-- 7天后开始使用此规则 -->
<precision>60</precision> <!-- 每 60 秒聚合一次 -->
</retention>
</pattern>
<!-- 规则 3:5分钟聚合,保留1年 -->
<pattern>
<regexp>.*</regexp>
<function>avg</function> <!-- 取平均值 -->
<retention>
<age>7776000</age> <!-- 90天后使用 -->
<precision>300</precision> <!-- 每 5 分钟 -->
</retention>
</pattern>
</graphite_config_name>
</graphite_rollups>
参数说明:
| 参数 | 说明 |
|---|---|
regexp | 匹配指标路径(如 ^servers\.web.*\.cpu) |
function | 聚合函数:min, max, avg, any, sum |
age | 多久之后应用此规则(秒) |
precision | 聚合时间窗口(秒) |
✅ 支持多规则,按
age递增排序,自动选择匹配的规则。
🔄 六、工作流程(数据写入与合并)
客户端写入原始数据(每10秒一个点)
│
↓
数据按 (Path, Time) 排序存储
│
↓
后台 Merge 任务触发
│
↓
根据 graphite_rollup 规则:
- 7天后:将10秒点聚合成60秒点(max)
- 90天后:将60秒点聚合成300秒点(avg)
│
↓
生成多个“聚合层级”的数据片段
│
↓
查询时自动选择最合适的精度层级
📊 七、查询示例
-- 查询最近1小时(高精度)
SELECT
Path,
toStartOfInterval(Time, INTERVAL 10 SECOND) AS interval,
avg(Value)
FROM metrics_downsampled
WHERE Time >= now() - INTERVAL 1 HOUR
AND Path LIKE 'servers.web01.cpu%'
GROUP BY Path, interval;
-- 查询最近1年(自动使用低精度数据)
SELECT
Path,
toStartOfHour(Time) AS hour,
max(Value)
FROM metrics_downsampled
WHERE Time >= now() - INTERVAL 1 YEAR
AND Path = 'servers.web01.cpu.usage'
GROUP BY Path, hour;
✅ 查询无需关心降采样逻辑,ClickHouse 自动选择最优数据层级。
✅ 八、适用场景
| 场景 | 是否适合 |
|---|---|
| Prometheus 指标存储 | ✅(配合 clickhouse-remote-storage) |
| 自研监控系统 | ✅ |
| 日志分析 | ❌(用 MergeTree 更合适) |
| 用户行为分析 | ❌ |
| 高频金融行情 | ⚠️(需评估聚合策略) |
✅ 特别适合:写多读少、时间序列、需要长期存储的监控指标
⚠️ 九、注意事项与限制
| 项目 | 说明 |
|---|---|
| 版本要求 | ≥ v19.11,建议 ≥ v21+ |
| 聚合函数 | 仅支持 min, max, avg, any, sum |
| 不能更新 | 不支持 UPDATE,靠 Version 字段去重 |
| Path 必须有序 | ORDER BY (Path, Time) 是强制要求 |
| 配置复杂 | graphite_rollup 需在 config.xml 中定义 |
| 替代方案 | 可用 AggregatingMergeTree + 物化视图实现类似功能 |
🎯 十、与其他方案对比
| 方案 | 优点 | 缺点 |
|---|---|---|
GraphiteMergeTree | 内置降采样,透明查询 | 配置复杂,灵活性低 |
AggregatingMergeTree + MV | 灵活,可自定义聚合 | 需手动管理多个表 |
SummingMergeTree | 简单求和 | 不支持多精度 |
| 外部降采样(如 Thanos) | 架构解耦 | 增加系统复杂度 |
✅ 推荐使用
GraphiteMergeTree:如果你的数据模型接近 Graphite,它是最简洁、最集成的方案。
📌 十一、总结:GraphiteMergeTree 的核心价值
| 能力 | 说明 |
|---|---|
| 📉 自动降采样 | 按时间自动聚合,节省存储 |
| 📈 多精度存储 | 高精度近期,低精度远期 |
| ⚡ 查询透明 | 无需改 SQL,自动选择最优层级 |
| 💾 节省成本 | 减少 5~10 倍存储空间 |
| 🧩 原生支持 Graphite 模型 | 完美适配监控系统 |
🎯
GraphiteMergeTree是 ClickHouse 的“监控专用引擎”:
它让时间序列数据的存储与查询变得高效、自动、低成本。
242

被折叠的 条评论
为什么被折叠?



