
本文字数:14190;估计阅读时间:36 分钟
作者:Miel Donkers
本文在公众号【ClickHouseInc】首发

Dash0 的创始团队拥有深厚的 Instana 背景——这家公司以其在可观测性工具方面的创新而闻名。在 Instana 发展的早期阶段,我们主要依赖 Cassandra 和 ElasticSearch 作为存储方案。随着平台不断扩展,为满足不断增长的客户需求和功能要求,团队逐渐转向 ClickHouse,作为核心数据库技术,以提升系统的效率和可扩展性。

在创建 Dash0 之初,选择 ClickHouse 作为主要存储系统是一个自然而然的决定,尤其是因为我们的两位联合创始人曾参与构建 ClickHouse 的云产品。如今,ClickHouse 承载了我们所有的 OpenTelemetry 数据,唯一使用的其他数据库是 PostgreSQL,专门用于处理客户相关的配置与数据。
本文将分享我们使用 ClickHouse 的完整历程——从最初的评估到技术实现的细节,并重点介绍一些关键特性,正是这些能力让 Dash0 得以实现。
决策阶段
Dash0 的目标是构建一个原生支持 OpenTelemetry 的系统,充分发挥 OpenTelemetry 信号所提供的丰富信息价值:
- 跨信号关联:工程师可以从指标出发,深入查看相关的追踪信息,并在同一工作流程中排查关联的日志。
- 服务健康监控:平台保留了 OpenTelemetry 的语义约定,可自动生成有意义的仪表板,并创建具备可操作性的告警。
- 简化故障排查:通过维护各类信号之间的关联,Dash0 显著缩短了事故的平均恢复时间(MTTR)。
这些能力对底层存储也提出了新的要求:
-
能够处理并存储所有类型的信号:指标(Metrics)、日志(Logs)和追踪(Spans)
-
能够通过资源属性(Resource attributes)或字段(如 TraceId 和 SpanId)在不同信号之间建立引用关系,例如通过日志中的 TraceId 关联到对应的追踪
-
支持高基数数据结构,因为属性既存在于资源层,也存在于信号层
为了满足这些需求,将所有数据整合到一个统一的系统中是最合适的方案。这不仅使我们可以直接通过 SQL 的 JOIN 操作将不同类型的信号关联起来,同时也能充分利用 ClickHouse 在大规模监控负载中的可扩展能力。
ClickHouse 的列式存储架构特别擅长处理 OpenTelemetry 属性中的高基数数据(即包含丰富上下文和元数据的键值对)。虽然这些属性可以作为 Map(String, String) 类型存储,但我们通常会将查询频率较高的属性(如 service.name)提取为独立的物化列,以提升查询效率。此外,ClickHouse 最近引入的原生 JSON 支持,更高效地处理了复杂的动态数据结构。这种新特性既保留了 Map 的灵活性,又具备物化列的高性能,从而让系统配置更加简洁。
ClickHouse 还提供了完善的 Java 和 Golang 客户端库,这两种语言都是 Dash0 技术栈中的核心。我们团队本身精通 Java,同时也自然地选择了 Golang —— 不仅因为很多 OpenTelemetry 相关的集成库都是用 Golang 编写,还因为我们打算使用的 OpenTelemetry Collector 也是用 Golang 构建的,并且已经在其官方代码库中集成了 ClickHouse 导出器。
ClickHouse 运维实践
除了支持 Dash0 功能所需的表结构(后文会详细说明),我们还基于过往经验对 ClickHouse 的运行策略进行了全面优化,在可维护性、系统性能和成本控制之间实现了良好平衡。当然,我们也通过 Dash0 平台自身实时监控 ClickHouse 的运行状态,确保系统持续稳定。
存储策略
对于任何可观测性平台来说,随着客户数量增长,数据体量会迅速膨胀,因此控制存储成本至关重要。但与此同时,又必须满足对查询性能的严格要求。虽然日志和追踪数据(Spans)在几周后可能价值下降,但我们希望能长期保留指标数据(Metrics),以支持一年以上的季节性趋势分析。
借助我们在 ClickHouse 工作期间积累的实践经验,我们采用了混合存储架构:将 AWS S3 作为主要存储,同时结合本地临时存储。ClickHouse 原生就很好地支持这一架构。从用户行为来看,大多数查询集中在过去 1 到 2 天的数据,这正好契合仪表板查看、故障排查等典型场景。
得益于 ClickHouse 高效的压缩能力,数据从热存储迁移至冷存储的时机可以有效延后,这使得短期内保留 1-2 天的热数据成为可行的做法。
我们的多层磁盘结构设计如下:
-
本地磁盘保留近 1-2 天的热数据
-
历史数据归档到 AWS S3
-
使用本地磁盘作为查询缓存
本地缓存机制能够暂时保留从 S3 获取的数据,加快后续相同数据的查询速度,并有效减少 S3 的 GET 请求次数,从而降低整体成本。
磁盘的具体配置如下所示:
<clickhouse>
<storage_configuration>
<disks>
<default>
<keep_free_space_bytes>536870912</keep_free_space_bytes>
</default>
<disk_s3>
<data_cache_enabled>true</data_cache_enabled>
<endpoint>...s3 endpoint...</endpoint>
<type>s3</type>
</disk_s3>
<disk_s3_cache>
<disk>disk_s3</disk>
<path>/mnt/cache-disk/</path>
<type>cache</type>
</disk_s3_cache>
</disks>
<policies>
<s3tiered>
<move_factor>0.100000</move_factor>
<volumes>
<n_1_hot>
<disk>default</disk>
</n_1_hot>
<n_2_cold>
<disk>disk_s3_cache</disk>
</n_2_cold>
Dash0用ClickHouse构建可观测性方案

最低0.47元/天 解锁文章
34

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



