Skip to main content
All quickstarts
可观测性OSS

前置条件

你将构建的内容

在 OpenTelemetry 中,每个 trace span 都会携带一组资源属性——也就是描述产生遥测数据的实体的键值元数据 (如服务名称、主机、云区域、Kubernetes pod (容器组) 等) 。这些键的集合会因服务和环境而异,因此很适合使用 ClickHouse 的 Map 类型:键是动态的,并且因应用而异,但任意一行通常只包含其中少数几个。 在本快速入门中,你将使用 clickhouse-local 将来自 CSV file 的真实 OTel trace 数据加载到包含 Map(LowCardinality(String), String) 列的表中,并学习如何对 map 数据进行查询、过滤、聚合和优化。
1

下载示例数据

该数据集包含从一个演示微服务应用导出的 6,120 个 OTel trace span。每一行都包含 ResourceAttributesSpanAttributes 两列,这两列中是以 JSON 映射形式存储的动态键值对。 将文件保存到一个便于引用的目录中,例如 ~/data/data-otel-traces.csv下载 data-otel-traces.csv (2.9 MB)单行数据如下所示:
2

创建表并加载数据

启动 clickhouse-local,并创建下列表,其 schema 与 CSV 相匹配。 关键列是 ResourceAttributes Map(LowCardinality(String), String)——在键类型上使用 LowCardinality,因为 OTel attribute 键通常来自一个相对较小且会重复出现的集合。
现在使用 file 表引擎加载 CSV。请将路径改为你保存该文件的位置:
确认数据已成功加载:
你应该会看到 6,120 行。
3

查询数据

访问特定键 — 使用方括号语法从 map 中取出值。如果某一行中不存在该键,则会返回该值类型的默认值 (String 的默认值为空字符串) :
按 Map 值过滤 — 查找特定服务名称的所有 spans:
检查某个键是否存在 —— 并非每个 span 都带有 Kubernetes 元数据。使用 mapContains 找出哪些 span 带有这些元数据:
查看数据集中出现的所有键 —— 有助于了解埋点产生了哪些内容:
使用 ARRAY JOIN 将 map 展开成多行 — 让每个键值对各自成为一行,便于构建属性清单或为仪表盘提供数据:
使用 mapFilter 过滤 Map — 仅提取每个 span 中与 Kubernetes 相关的属性:
查找错误 span 及其资源上下文 — 将常规列过滤条件与 Map 访问结合使用:
4

使用 -Map 组合器对 Map 进行聚合

ClickHouse 的 -Map 聚合组合器可让你将任意聚合函数应用到 Map 列上,并对每个键分别进行聚合。结果本身也是一个 Map——每个键对应一个条目,其中包含聚合后的值。这对 OTel 指标尤其有用,因为 counter 或 gauge 通常存储为 map 值。为便于演示,先创建一个小型指标表,其中每一行都将 HTTP 状态码计数记录为 Map(String, UInt64)
现在使用 sumMap 按服务汇总各状态码的计数:
-Map 后缀可用于任何聚合函数,因此你同样可以轻松使用 minMapmaxMapavgMap
你也可以将它与其他组合器结合使用。例如,sumMapIf 可以让你按条件聚合——这里仅对该服务已出现错误的分钟窗口求和:
**为什么这对 OTel 很重要:**当你的 OTel collector 将按分钟统计的状态码明细写入 ClickHouse 时,sumMap 可让你通过一次查询将其汇总为按小时或按天统计的总计——无需 ARRAY JOIN,无需进行反透视,也无需预先知道完整的键集合。任何在任意行中出现的键都会自动包含在结果中。
5

针对频繁查询的键进行优化

如果你发现自己总是按同一个 Map 键进行过滤——host.name 就是一个常见例子——可以将它提取为物化列。这样可以避免每次查询时都在线性扫描整个 Map:
对于现有数据,回填该列:
现在,WHERE HostName = 'prod-cart-01' 只会读取一个专用列,而不是整个 map。对于任何经常查询的 attribute,这都是 OTel ClickHouse schema 中推荐的模式。

关键要点

  • Map(LowCardinality(String), String) 是 OTel 属性的惯用类型——既足够灵活,能处理不断变化的键集合,又能借助 LowCardinality 保持键存储的高效性。
  • 方括号语法 (map['key']) 是访问值最常见的方式,但要记住它是线性扫描——对于只有几十个键的 Map 完全没问题,但对于几百个键就不太理想了。
  • 物化列是解决之道:当某个 map 键变成高频过滤目标时,可将其提升为真正的列,以获得带索引的列式访问。
  • mapContainsmapKeysmapValuesmapFilterARRAY JOIN 为你提供了一套强大的工具,让你无需离开 SQL 就能探索和转换 Map 数据。
  • -Map 聚合组合器 (sumMapavgMapmaxMap 等) 会跨行按键分别聚合——非常适合对 OTel 指标计数器进行汇总,而无需预先知道键集合。它还可以与其他组合器配合使用 (例如 sumMapIf) 。

后续步骤

接下来可查看以下快速入门: 或者深入阅读以下参考文档:
ClickHouse Academy — Master ClickHouse with expert-designed training for every skill level

Check out the ClickHouse academy for on-demand and live training

最后修改于 2026年8月28日