Skip to content

Commit

Permalink
更新可观测内容
Browse files Browse the repository at this point in the history
  • Loading branch information
isno committed Feb 4, 2024
1 parent b00308d commit 0c43a7c
Show file tree
Hide file tree
Showing 13 changed files with 96 additions and 49 deletions.
16 changes: 11 additions & 5 deletions .vuepress/config.js
Original file line number Diff line number Diff line change
Expand Up @@ -295,11 +295,17 @@ export default defineUserConfig({
sidebarDepth: 1,
children: [
"/observability/history.md",
'/observability/metrics.md',
'/observability/logging.md',
'/observability/tracing.md',
'/observability/profiles.md',
'/observability/dumps.md',
{
text: "9.2 可观测数据分类",
link: '/observability/signals.md',
children: [
'/observability/metrics.md',
'/observability/logging.md',
'/observability/tracing.md',
'/observability/profiles.md',
'/observability/dumps.md',
]
},
'/observability/OpenTelemetry.md',
'/observability/conclusion.md',
]
Expand Down
10 changes: 7 additions & 3 deletions Observability/OpenTelemetry.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
# 9.5 OpenTelemetry
# 9.3 可观测性大统一

建设完善的可观测体系,很可能会形成链路监控、日志监控、指标监控等多套不同的监控系统,要打通是相当困难的。不同的业务线间,日志规则不互通,要完全互通也很困难。系统一旦过多,相关维护以及故障排除的时间成本就会大幅增加。

收集应用数据并不是什么新鲜事。但是,从一个应用到另一个应用,收集机制和格式很少是一致的。这种不一致,对于只是试图了解应用健康状况的开发人员和 SRE 来说,可能是一场噩梦。

先是 CNCF 提出了 OpenTracing 分布式追踪的标准协议,定义了一套厂商无关、语言无关的规范,也有 Jaeger 、Zipkin 等项目的实现和支持。随后 Google 和微软提出了 OpenCensus 项目,在定义分布式追踪协议的基础上,规范了应用性能指标,并实现了一套标准的 API ,为可观测性能力统一奠定了基础。

Expand All @@ -15,4 +16,7 @@ OpenTelemetry 的核心工作主要集中在三部分:
<img src="../assets/otel-diagram.svg" width = "550" align=center />
</div>

OpenTelemetry 定位明确,专注于数据采集和标准规范的统一,对于数据如何去使用、存储、展示、告警,标准本身并不涉及。但就总体来说,可观测的技术方案成以下趋势:对于 Metrics 使用 Prometheus 做存储 Grafana 展示,使用 Jaeger 做分布式跟踪存储和展示,对于日志则使用 Loki 存储 Grafana 展示。
OpenTelemetry 定位明确,专注于数据采集和标准规范的统一,对于数据如何去使用、存储、展示、告警,标准本身并不涉及。但就总体来说,可观测的技术方案成以下趋势:对于 Metrics 使用 Prometheus 做存储 Grafana 展示,使用 Jaeger 做分布式跟踪存储和展示,对于日志则使用 Loki 存储 Grafana 展示。


OpenTelemetry 的特点在于制定统一的协议数据格式,并提供底层数据采集器。这使得 OpenTelemetry 既不会因动了“数据的蛋糕”,引起生态抵制,也极大保存了精力,得以专注于数据采集器,努力去兼容“所有的语言、所有的系统”。
5 changes: 4 additions & 1 deletion Observability/conclusion.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,7 @@

- 《cncf 可观测性白皮书》https://github.com/cncf/tag-observability/blob/main/whitepaper.md
https://github.com/cncf/tag-observability/blob/dec82aa5bd39a8834f58da0377d1e2b8fdeeac63/whitepaper-zh.md
- 《Gorilla:快速、可扩展的内存时间序列数据库》https://blog.acolyer.org/2016/05/03/gorilla-a-fast-scalable-in-memory-time-series-database/
- 《Gorilla:快速、可扩展的内存时间序列数据库》https://blog.acolyer.org/2016/05/03/gorilla-a-fast-scalable-in-memory-time-series-database/
- https://github.com/open-telemetry/docs-cn/blob/main/OT.md

- https://medium.com/lightstephq/observability-will-never-replace-monitoring-because-it-shouldnt-eeea92c4c5c9
2 changes: 1 addition & 1 deletion Observability/dumps.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# core dump
# 9.2.5 core dump

CNCF 可观测性白皮书中只提到了 core dump。只提 core dump 有局限,dump 还应该包含更多,例如 Heap dump(某时刻 Java 堆栈的快照)、Thread dump(某一时刻 Java 线程快照)等。

Expand Down
27 changes: 2 additions & 25 deletions Observability/history.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ The information that you will use to determine whether an application is healthy

在过去,一个物理机器的状态确实可以通过几个监控指标描述,但是随着我们的系统越来越复杂,观测对象正渐渐的从 Infrastructure 转到 应用,观察行为本身从 Monitoring(监控)到 Observability(观测)。虽然看上去这两者只是文字上的差别,也确实容易引起误解,但是请仔细思考背后的含义。

如下图所示,套用 Donald Rumsfeld 关于 Known、Unknowns 的名言[^3],把系统的理解程度和可收集信息之间的关系进行象限化分析。
如下图所示,套用 Donald Rumsfeld 关于 Known、Unknowns 的名言[^2],把系统的理解程度和可收集信息之间的关系进行象限化分析。

<div align="center">
<img src="../assets/observability-knowns.png" width = "500" align=center />
Expand All @@ -42,29 +42,6 @@ X 轴的右侧称为 Known Knows(已知且理解)和 Known Unknowns(已知
<img src="../assets/Monitoring-vs-Observability.png" width = "450" align=center />
</div>

## 可观测性数据分类

工业界和学术界一般会将可观测性的遥测数据分解为三个更具体方向进行研究,它们分别是**事件日志(Logging)、链路追踪(Tracing)和聚合度量(Metrics)**

- Metrics,一般用来计算 Events 发生数量的数据集,这些数据通常具有原子性、且可以聚合。从操作系统到应用程序,任何事物都会产生 Metrics 数据,这些数据可以用来度量操作系统或者应用是否健康。
- Logging,描述一系列离散的事件,在缺乏有力的监控系统时,Logging 数据通常是工程师在定位问题时最直接的手段。如果说 Metrics 告诉你应用程序出现问题,那么 Logging 就告诉你为什么出现问题。
- Tracing,微服务下,多个服务之间或多或少存在依赖,Tracing 通过有向无环图的方式记录分布式系统依赖中发生 Events 之间的因果关系。


2017 年的分布式追踪峰会结束后,Peter Bourgon 撰写了总结文章《Metrics, Tracing, and Logging》[^2]系统地阐述了这三者的定义、特征以及它们之间的关系与差异,受到了业界的广泛认可。

<div align="center">
<img src="../assets/observability.png" width = "350" align=center />
</div>

来自于 Cindy Sridharan 的《Distributed Systems Observability》著作中进一步将这三个类型的数据称为可观测性的三大支柱(three pillars),不过将它们成为支柱容易让人产生误解,支柱就像一个房子的均匀受力支撑点,缺一不可。而事实上这三者都可以独立存在,系统中只存在 Logging、Tracing 也未尝不可。

所以,在最新 CNCF 发布的可观测性白皮书中,将这些可观测的数据统一称为信号(Signals),主要的信号除了 Metrics、logs、traces 之外又额外增加了 Profiles 和 Dumps。


[^1]: 参见 https://medium.com/lightstephq/observability-will-never-replace-monitoring-because-it-shouldnt-eeea92c4c5c9


[^1]: 参见 https://cloud.google.com/learn/what-is-opentelemetry
[^2]: 参见 https://peter.bourgon.org/blog/2017/02/21/metrics-tracing-and-logging.html
[^3]: 参见 https://blog.sciencenet.cn/blog-829-1271882.html
[^2]: 参见 https://blog.sciencenet.cn/blog-829-1271882.html
38 changes: 29 additions & 9 deletions Observability/logging.md
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
# 9.3 事件日志
# 9.2.2 事件日志

你可能不知道 Metrics、Tracing,但你一定了解点 logging。logging 系统中最成熟的部分就是打印日志。尤其是本地日志打印,各式各样层出不穷的 logging Library,同步的异步的、有锁的无锁的、有上下文的无上下文的、高性能的低性能的,花活最多轮子也造的最多
Logs 作为最古老而又最具体的一个 Signal,大部分的时候都是基于可读性较好的文本

可观测性白皮书中把日志分为5类:Application Logs、Security Log、System Log、Audit log、Infrastructure log。

日志最出名的方案莫过于 ELK,不过 2019 年 Grafana Labs 公司推出一个更能打的选手 Loki。但对于日志这种有时效性的数据而言,笔者也一时想也找不到一定要用到 Elasticsearch 的场景。

## 收集
你可能不知道 Metrics、Tracing,但你一定了解点 logging。logging 系统中最成熟的部分就是打印日志。尤其是本地日志打印,各式各样层出不穷的 logging Library,同步的异步的、有锁的无锁的、有上下文的无上下文的、高性能的低性能的,花活最多轮子也造的最多。

目前官方有自己的 client: Promtail,也支持主流的组件,如 Fluentd、Logstash、Fluent Bit 等。
日志最大的挑战是数据量大(PB 级别)

日志最出名的方案莫过于 ELK。

:::tip ELKB

Expand All @@ -24,19 +25,35 @@ Elastic Stack 之所以流行的一个原因之一,可能是它的无侵入性
我们来看一个典型的 Elastic Stack 使用场景,大致系统架构如下(整合了消息队列和 Nginx 的架构)。

<div align="center">
<img src="../assets/loki-overview-2.png" width = "550" align=center />
<img src="../assets/ELK.png" width = "550" align=center />
<p>Loki 架构:与 Prometheus、Grafana 密切集成</p>
</div>


这个系统中,Beats 部署到日志所在地,用来收集原始数据,然后使用 MQ 做缓冲换取更好的吞吐,接着发给 logstash 做数据清洗,最后落地到 es 集群并进行索引,使用时通过 Kibana 来检索和分析,如果有必要挂上 Nginx 做各类访问控制。


## 存储与查询
采用全文检索对日志进行索引,优点是功能丰富,允许复杂的操作。但是,这些方案往往规模复杂,资源占用高,很多功能往往用不上,大多数查询只关注一定时间范围和一些简单的参数(如:host、service 等),使用这些解决方案难免感觉杀鸡用牛刀。

loki 一个明显的特点是非常经济,Loki 不再根据日志内容去建立大量的索引,而是借鉴了 Prometheus 核心的思想,使用标签去对日志进行特征标记,然后归集统计。Loki 只索引与日志相关的元数据标签,而日志内容则以压缩方式存储于对象存储中, 不做任何索引,这样的话,能避免大量的内存资源占用,转向廉价的硬盘存储。相较于 ES 这种全文索引的系统,数据可在十倍量级上降低,加上使用对象存储,最终存储成本可降低数十倍甚至更低。
## 低成本方案 Loki

说白了,Loki 吸引人的地方就在于拥有和 Prometheus 类似机制的时序数据库以及方便拓展的硬盘资源。
如果只是需求只是把日志集中起来,最多用来排查问题,且对成本敏感。那么久不得不提日志领域的另外一个方案,Grafana Labs 公司推出 Loki,官方的项目介绍是 like Prometheus, but for logs,类似于 Prometheus 的日志系统。

<div align="center">
<img src="../assets/loki-arc.png" width = "550" align=center />
<p>Loki 架构:与 Prometheus、Grafana 密切集成</p>
</div>


Loki 一个明显的特点是非常经济,Loki 不再根据日志的原始内容建立大量的全文索引,而是借鉴了 Prometheus 核心的思想,使用标签去对日志进行特征标记,然后归集统计。Loki 只索引与日志相关的元数据标签,而日志内容则以压缩方式存储于对象存储中, 不做任何索引,这样的话,能避免大量的内存资源占用,转向廉价的硬盘存储。相较于 ES 这种全文索引的系统,数据可在十倍量级上降低,加上使用对象存储,最终存储成本可降低数十倍甚至更低。


Loki 使用与 Prometheus 相同的服务发现和标签重新标记库,编写了 Pormtail,在 Kubernetes 中 Promtail 以 DaemonSet 方式运行在每个节点中,通过 Kubernetes API 得到日志的正确元数据,并将它们发送到 Loki。

也正是因为这个原因,通过这些标签,既可以查询日志的内容,也可以查询到监控的内容,这两种查询被很好的兼容,节省了分别存储相关日志和监控数据的成本,也减少了查询的切换成本。


说白了,Loki 吸引人的地方就在于拥有和 Prometheus 类似机制的时序数据库以及方便拓展的硬盘资源。

数据由标签、时间戳、内容组成

Expand All @@ -53,7 +70,10 @@ loki 一个明显的特点是非常经济,Loki 不再根据日志内容去建
}
```

总体而言,Loki和ELK都是优秀的日志解决方案,适合不同的使用场景。Loki相对轻量级,具有较高的可扩展性和简化的存储架构,但需要额外的组件和有一定的学习曲线。ELK则具有丰富的可视化选项和插件库,易于学习,但相对重量级,需要复杂的存储架构和较高的硬件要求,部署和管理也比较复杂。


具体如何选择取决于具体场景,若是数据量适中,数据属于时序类,如应用程序日志和基础设施指标,并且应用使用kubernetes Pod形式部署,则选择Loki比较合适;而ELK则适合更大的数据集和更复杂的数据处理需求,以及更多其他组件的日志收集场景。


## 日志展示
Expand Down
2 changes: 1 addition & 1 deletion Observability/metrics.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# 9.2 聚合指标
# 9.2.1 聚合指标

作为传统监控和告警领域的代名词,Metrics 最广为人知,也被各类可观测系统支持的最丰富。Metrics 一般是用来计算 Events 发生数量的数据集,例如服务 QPS、API 响应延迟、某个接口的失败数等。它们大部分都是以数字化指标出现,特征是可聚合性,在数据的处理上,Metrics 可以是实时的,也可能是区间范围的,是跟随着时间变化的时序数据。既能做常见的监控告警,也可以用来做趋势分析。

Expand Down
2 changes: 1 addition & 1 deletion Observability/profiles.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Profiles
# 9.2.4 Profiles

熟悉 Go 语言的朋友一定了解 pprof,进行性能分析时,通过 pprof 的 CPU profiling 或者 Memory profiling 功能分析函数耗时以及内存占用情况。Profiles 就是进行 profiling 时程序运行的动态画像,当于动态的内部数据,说明各类资源分配的情况,能精确到进程、代码。

Expand Down
37 changes: 37 additions & 0 deletions Observability/signals.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
# 9.2 可观测性数据分类

工业界和学术界一般会将可观测性的遥测数据分解为三个更具体方向进行研究,它们分别是**事件日志(Logging)、链路追踪(Tracing)和聚合度量(Metrics)**

- Metrics(聚合度量),一般用来计算事件发生数量的数据集,这些数据通常具有原子性、且可以聚合。从操作系统到应用程序,任何事物都会产生 Metrics 数据,这些数据可以用来度量操作系统或者应用是否健康。
- Logging(事件日志),描述一系列离散的事件,在缺乏有力的监控系统时,Logging 数据通常是工程师在定位问题时最直接的手段。如果说 Metrics 告诉你应用程序出现问题,那么 Logging 就告诉你为什么出现问题。
- Tracing(链路追踪),分布式系统中多个服务之间或多或少存在依赖,Tracing 通过有向无环图的方式记录分布式系统依赖中发生事件之间的因果关系。


2017 年的分布式追踪峰会结束后,Peter Bourgon 撰写了总结文章《Metrics, Tracing, and Logging》[^1]系统地阐述了这三者的定义、特征以及它们之间的关系与差异,受到了业界的广泛认可。

<div align="center">
<img src="../assets/observability.png" width = "350" align=center />
</div>

来自于 Cindy Sridharan 的《Distributed Systems Observability》著作中进一步将这三个类型的数据称为可观测性的三大支柱(three pillars),不过将它们成为支柱容易让人产生误解,支柱就像一个房子的均匀受力支撑点,缺一不可。而事实上这三者都可以独立存在,系统中只存在 Logging、Tracing 也未尝不可。所以,在最新 CNCF 发布的可观测性白皮书中,将这些可观测的数据统一称为信号(Signals),主要的信号除了 Metrics、logs、traces 之外又额外增加了 Profiles 和 Dumps。

## 可观测数据联系

<div align="center">
<img src="../assets/observability-signals.png" width = "650" align=center />
</div>


1. 最开始我们通过各式各样的预设报警发现异常(通常是Metrics/Logs)。
2. 发现异常后,打开监控大盘查找异常的曲线,并通过各种查询/统计找到异常的模块(Metrics)。
3. 对这个模块以及关联的日志进行查询/统计分析,找到核心的报错信息(Logs)。
4. 最后通过详细的调用链数据定位到引起问题的代码(Traces/Code)。


通常的事件响应首先是从报警开始的,然后通过一些 Dashboard 查看信息,然后再指出错误的服务、主机或者实例。然后,工程师将尝试查找该服务、主机或者实例在该时间范围内的日志,希望能找到根本原因。由于当前的情况是指标和日志存储在两个不同的系统中,所以工程师们需要将查询从一种语言和界面切换到另外一种语言去操作。



该设计的第一个目的是将日志和指标之间的上下文切换成本降到最低。

[^1]: 参见 https://peter.bourgon.org/blog/2017/02/21/metrics-tracing-and-logging.html
6 changes: 3 additions & 3 deletions Observability/tracing.md
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
# 9.4 链路追踪
# 9.2.3 链路追踪

参阅 Uber(优步,国外的打车公司)公开的技术文档信息,它们的微服务架构中大约有 2,200 个服务,这些服务相互依赖的链路关系引用 Uber 博客中的配图[^1]供你直观感受。而分布式链路追踪所要做的事情就是通过请求粒度的轨迹追踪与数据透传,实现规模级服务之间的确定性关联
参阅 Uber 公开的技术文档信息,它们的微服务架构中大约有 2,200 个服务。这些服务之间的调用链路,引用 Uber 博客中的配图[^1]感受扑面来而的复杂。而分布式链路追踪所要做的事情就是**通过请求粒度的轨迹追踪与数据透传,实现分布式服务之间的确定性关联**

<div align="center">
<img src="../assets/uber-microservice.png" width = "350" align=center />
<p>Uber 使用 Jaeger 生成的追踪链路拓扑</p>
</div>

分布式链路追踪诞生的标志性事件就是 Google Dapper 论文的发表。2010年4月,Benjamin H. Sigelman 等人在 Google Technical Report 上发表了《Dapper, a Large-Scale Distributed Systems Tracing Infrastructure》[^2]Dapper 论文详细阐述了分布式链路追踪的设计理念,还提出了成为后续链路追踪系统设计的共识的两个概念:“追踪”(Trace)和“跨度”(Span)。
分布式链路追踪诞生的标志性事件就是 Google Dapper 论文的发表。2010年4月,Benjamin H. Sigelman 等人在 Google Technical Report 上发表了《Dapper, a Large-Scale Distributed Systems Tracing Infrastructure》[^2],论文详细阐述了 Google 内部分布式链路追踪系统 Dapper 的设计理念,还提出了成为后续链路追踪系统设计的共识的两个概念 Trace(追踪)和 Span(跨度)。

## Trace 和 Span

Expand Down
Binary file added assets/loki-arc.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/loki-overview.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/observability-signals.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.

0 comments on commit 0c43a7c

Please sign in to comment.