> ## Documentation Index
> Fetch the complete documentation index at: https://clickhouse.com/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# 使用 ClickHouse 实现可观测性

> 将 ClickHouse 用作可观测性解决方案

export const Image = ({img, alt, size = "lg"}) => {
  const normalizedSize = ["sm", "md", "lg"].includes(size) ? size : "lg";
  return <div className={`ch-image-${normalizedSize}`}>
      <Frame>
        <img src={img} alt={alt} />
      </Frame>
    </div>;
};

<div id="introduction">
  ## 介绍
</div>

如果你希望使用 ClickHouse 构建基于 SQL 的自建可观测性解决方案，并重点关注日志和链路追踪，那么本指南就是为你准备的。它涵盖了构建此类解决方案的各个方面，包括摄取方面的考量、根据你的访问模式优化 schema，以及从非结构化日志中提取结构。

仅凭 ClickHouse 本身并不能构成开箱即用的可观测性解决方案。不过，它可以作为可观测性数据的高效存储引擎，具备无与伦比的压缩率和极快的查询响应速度。要在可观测性解决方案中使用 ClickHouse，还需要配备用户界面和数据采集框架。我们目前建议使用 **Grafana** 来可视化可观测性信号，并使用 **OpenTelemetry** 进行数据采集 (两者都是官方支持的集成) 。

<Image img="https://mintcdn.com/private-7c7dfe99/xE8TEsdF6028Tf3x/images/use-cases/observability/observability-1.webp?fit=max&auto=format&n=xE8TEsdF6028Tf3x&q=85&s=ec3d00845f5f828990407fe802f2450f" alt="简单 OTel" size="md" width="1000" height="164" data-path="images/use-cases/observability/observability-1.webp" />

<br />

<Info>
  **不只是 OpenTelemetry**

  虽然我们建议使用 OpenTelemetry (OTel) 项目进行数据采集，但也可以使用其他框架和工具构建类似的架构，例如 Vector 和 Fluentd (请参阅使用 Fluent Bit 的[示例](https://clickhouse.com/blog/kubernetes-logs-to-clickhouse-fluent-bit)) 。此外，也有其他可视化工具可供选择，包括 Superset 和 Metabase。
</Info>

<div id="why-use-clickhouse">
  ## 为什么使用 ClickHouse？
</div>

对于任何集中式可观测性存储而言，最重要的能力都是能够快速聚合、分析并搜索来自不同来源的海量日志数据。这种集中化能够简化故障排查，更容易定位服务中断的根本原因。

随着用户对价格愈发敏感，并且发现这些开箱即用方案相较其带来的价值而言成本高昂且难以预测，因而具备成本效益、成本可预测且查询性能可接受的日志存储方案，变得前所未有地重要。

凭借出色的性能和成本效益，ClickHouse 已成为可观测性产品中用于日志和链路追踪存储引擎的事实标准。

更具体地说，以下特性使 ClickHouse 特别适合存储可观测性数据：

* **压缩** - 可观测性数据通常包含一些字段，其取值来自有限的集合，例如 HTTP 状态码或服务名称。ClickHouse 的列式存储会将值按序存放，因此这类数据的压缩效果非常好；若再结合一系列面向时间序列数据的专用 codec，效果会更佳。与其他数据存储不同，后者通常需要接近原始数据大小的存储空间，而这些数据往往采用 JSON 格式；ClickHouse 对日志和链路追踪的平均压缩率最高可达 14 倍。除了能为大规模可观测性部署显著节省存储成本外，这种压缩还可以加快查询速度，因为需要从磁盘读取的数据更少。
* **快速聚合** - 可观测性解决方案通常高度依赖图表进行数据可视化，例如展示错误率的折线图或展示流量来源的柱状图。聚合，也就是 GROUP BY，是支撑这些图表的核心能力；而且在问题诊断流程中应用过滤器时，这些图表也必须保持快速响应。ClickHouse 的列式格式结合向量化查询执行引擎，非常适合快速聚合；同时，稀疏索引也能在用户操作后快速过滤数据。
* **快速线性扫描** - 虽然其他技术依赖倒排索引来实现日志的快速查询，但这往往会带来较高的磁盘和资源消耗。尽管 ClickHouse 也提供倒排索引作为一种可选的附加索引类型，但线性扫描本身具备高度并行化能力，并会使用机器上的所有可用 CPU 核心 (除非另有配置) 。这意味着它有可能以每秒数十 GB (压缩后) 的速度扫描数据以查找匹配项，并使用[高度优化的文本匹配运算符](/docs/zh/reference/functions/regular-functions/string-search-functions)。
* **SQL 的熟悉度** - SQL 是所有工程师都熟悉的通用语言。经过 50 多年的发展，它已经证明自己是数据分析领域的事实标准语言，并且仍然是[第 3 大最流行的编程语言](https://clickhouse.com/blog/the-state-of-sql-based-observability#lingua-franca)。可观测性本质上也只是另一类数据问题，而 SQL 正是解决这类问题的理想工具。
* **分析函数** - ClickHouse 在 ANSI SQL 的基础上扩展了分析函数，让 SQL 查询更简单、更易于编写。如果你要执行根因分析，需要对数据进行多维切片和深入剖析，这些函数就至关重要。
* **次级索引** -  ClickHouse 支持次级索引，例如布隆过滤器，可用于加速特定查询模式。这些索引可以按列选择性启用，从而为用户提供细粒度控制，并让他们评估其中的成本收益。
* **开源与开放标准** - 作为开源数据库，ClickHouse 拥抱 OpenTelemetry 等开放标准。既可以参与贡献并积极投身相关项目，也能避免供应商锁定带来的挑战，这一点颇具吸引力。

<div id="when-should-you-use-clickhouse-for-observability">
  ## 何时应使用 ClickHouse 做可观测性
</div>

将 ClickHouse 用于可观测性数据，意味着用户需要接受基于 SQL 的可观测性。想了解基于 SQL 的可观测性的发展历程，我们推荐阅读[这篇博文](https://clickhouse.com/blog/the-state-of-sql-based-observability)；不过简而言之：

如果符合以下情况，基于 SQL 的可观测性适合你：

* 你或你的团队成员熟悉 SQL (或希望学习 SQL)
* 你倾向于遵循 OpenTelemetry 等开放标准，以避免厂商锁定并获得扩展性。
* 你愿意采用一套从采集到存储再到可视化、由开源创新驱动的生态系统。
* 你预计所管理的可观测性数据量会增长到中等或大型规模 (甚至超大规模)
* 你希望掌控 TCO (总拥有成本) ，避免可观测性成本不断攀升。
* 你无法接受，或不希望仅仅为了控制成本，就把可观测性数据的保留期压得很短。

如果符合以下情况，基于 SQL 的可观测性可能并不适合你：

* 学习 SQL (或生成 SQL！) 对你或你的团队成员没有吸引力。
* 你想要的是一套打包好的端到端可观测性体验。
* 你的可观测性数据量太小，不足以带来明显差异 (例如 \<150 GiB) ，且预计不会增长。
* 你的用例以指标为主，并且需要 PromQL。在这种情况下，你仍然可以将 ClickHouse 用于日志和链路追踪，将 Prometheus 用于指标，并通过 Grafana 在展示层统一呈现。
* 你更愿意等待生态系统进一步成熟，以及基于 SQL 的可观测性变得更加开箱即用。

<div id="logs-and-traces">
  ## 日志和链路追踪
</div>

可观测性有三大支柱：日志、链路追踪和指标。它们各自对应不同的数据类型和访问方式。

我们目前建议使用 ClickHouse 存储两类可观测性数据：

* **日志** - 日志是系统内发生事件的带时间戳记录，用于记录软件运行过程中各个方面的详细信息。日志中的数据通常是非结构化或半结构化的，可能包括错误消息、用户活动日志、系统变更以及其他事件。日志对于故障排查、异常检测，以及理解系统中问题发生前的具体事件至关重要。

```response theme={null}
54.36.149.41 - - [22/Jan/2019:03:56:14 +0330] "GET
/filter/27|13%20%D9%85%DA%AF%D8%A7%D9%BE%DB%8C%DA%A9%D8%B3%D9%84,27|%DA%A9%D9%85%D8%AA%D8%B1%20%D8%A7%D8%B2%205%20%D9%85%DA%AF%D8%A7%D9%BE%DB%8C%DA%A9%D8%B3%D9%84,p53 HTTP/1.1" 200 30577 "-" "Mozilla/5.0 (compatible; AhrefsBot/6.1; +http://ahrefs.com/robot/)" "-"
```

* **链路追踪** - 链路追踪用于记录请求在分布式系统中穿越不同服务时的完整过程，详细呈现这些请求的路径和性能。链路追踪中的数据具有高度结构化的特点，由 span 和 trace 组成，用于刻画请求经历的每一个步骤，包括耗时信息。链路追踪能够为系统性能提供宝贵洞察，帮助识别瓶颈、延迟问题，并优化微服务的运行效率。

<Info>
  **指标**

  虽然 ClickHouse 可用于存储指标数据，但这一支柱在 ClickHouse 中的成熟度相对较低，对 Prometheus 数据格式和 PromQL 等功能的支持仍在完善中。
</Info>

<div id="distributed-tracing">
  ### 分布式链路追踪
</div>

分布式链路追踪是可观测性的关键能力之一。分布式 trace (通常简称为 trace) 用于描述一个请求在系统中的完整流转路径。请求通常来自终端用户或应用程序，并在系统中逐步扩散，通常体现为微服务之间一系列操作的传递。通过记录这一序列并将后续事件关联起来，即使架构十分复杂，或采用了无服务器架构，也能帮助可观测性用户或 SRE 诊断应用流程中的问题。

每个 trace 都由多个 span 组成，其中与初始请求对应的 span 称为根 span。根 span 记录了整个请求从开始到结束的全过程。位于根 span 之下的后续 span 则提供了请求处理过程中各个步骤或操作的详细信息。如果没有链路追踪，在分布式系统中诊断性能问题会非常困难。链路追踪通过详细呈现请求在系统中流转时的事件序列，让调试和理解分布式系统变得更加容易。

大多数可观测性厂商会将这些信息以瀑布图的形式可视化，并用按比例显示的水平条展示相对时序。例如，在 Grafana 中：

<Image img="https://mintcdn.com/private-7c7dfe99/xE8TEsdF6028Tf3x/images/use-cases/observability/observability-2.webp?fit=max&auto=format&n=xE8TEsdF6028Tf3x&q=85&s=104309242fe846b92642f947a818de8b" alt="示例 trace" size="lg" border width="1600" height="762" data-path="images/use-cases/observability/observability-2.webp" />

对于希望深入了解日志和链路追踪相关概念的用户，我们强烈推荐阅读 [OpenTelemetry 文档](https://opentelemetry.io/docs/concepts/).
