diff --git a/.vuepress/config.js b/.vuepress/config.js index fc9bb93e..f3d7d92a 100644 --- a/.vuepress/config.js +++ b/.vuepress/config.js @@ -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', ] diff --git a/Observability/OpenTelemetry.md b/Observability/OpenTelemetry.md index 9874a862..cdd7d31f 100644 --- a/Observability/OpenTelemetry.md +++ b/Observability/OpenTelemetry.md @@ -1,6 +1,7 @@ -# 9.5 OpenTelemetry +# 9.3 可观测性大统一 + +建设完善的可观测体系,很可能会形成链路监控、日志监控、指标监控等多套不同的监控系统,要打通是相当困难的。不同的业务线间,日志规则不互通,要完全互通也很困难。系统一旦过多,相关维护以及故障排除的时间成本就会大幅增加。 -收集应用数据并不是什么新鲜事。但是,从一个应用到另一个应用,收集机制和格式很少是一致的。这种不一致,对于只是试图了解应用健康状况的开发人员和 SRE 来说,可能是一场噩梦。 先是 CNCF 提出了 OpenTracing 分布式追踪的标准协议,定义了一套厂商无关、语言无关的规范,也有 Jaeger 、Zipkin 等项目的实现和支持。随后 Google 和微软提出了 OpenCensus 项目,在定义分布式追踪协议的基础上,规范了应用性能指标,并实现了一套标准的 API ,为可观测性能力统一奠定了基础。 @@ -15,4 +16,7 @@ OpenTelemetry 的核心工作主要集中在三部分: -OpenTelemetry 定位明确,专注于数据采集和标准规范的统一,对于数据如何去使用、存储、展示、告警,标准本身并不涉及。但就总体来说,可观测的技术方案成以下趋势:对于 Metrics 使用 Prometheus 做存储 Grafana 展示,使用 Jaeger 做分布式跟踪存储和展示,对于日志则使用 Loki 存储 Grafana 展示。 \ No newline at end of file +OpenTelemetry 定位明确,专注于数据采集和标准规范的统一,对于数据如何去使用、存储、展示、告警,标准本身并不涉及。但就总体来说,可观测的技术方案成以下趋势:对于 Metrics 使用 Prometheus 做存储 Grafana 展示,使用 Jaeger 做分布式跟踪存储和展示,对于日志则使用 Loki 存储 Grafana 展示。 + + +OpenTelemetry 的特点在于制定统一的协议数据格式,并提供底层数据采集器。这使得 OpenTelemetry 既不会因动了“数据的蛋糕”,引起生态抵制,也极大保存了精力,得以专注于数据采集器,努力去兼容“所有的语言、所有的系统”。 \ No newline at end of file diff --git a/Observability/conclusion.md b/Observability/conclusion.md index 045e45e9..a9d7fee1 100644 --- a/Observability/conclusion.md +++ b/Observability/conclusion.md @@ -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/ \ No newline at end of file +- 《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 \ No newline at end of file diff --git a/Observability/dumps.md b/Observability/dumps.md index 6f30cd8c..0f784df8 100644 --- a/Observability/dumps.md +++ b/Observability/dumps.md @@ -1,4 +1,4 @@ -# core dump +# 9.2.5 core dump CNCF 可观测性白皮书中只提到了 core dump。只提 core dump 有局限,dump 还应该包含更多,例如 Heap dump(某时刻 Java 堆栈的快照)、Thread dump(某一时刻 Java 线程快照)等。 diff --git a/Observability/history.md b/Observability/history.md index b45e733b..60065cb2 100644 --- a/Observability/history.md +++ b/Observability/history.md @@ -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],把系统的理解程度和可收集信息之间的关系进行象限化分析。
@@ -42,29 +42,6 @@ X 轴的右侧称为 Known Knows(已知且理解)和 Known Unknowns(已知
-## 可观测性数据分类 - -工业界和学术界一般会将可观测性的遥测数据分解为三个更具体方向进行研究,它们分别是**事件日志(Logging)、链路追踪(Tracing)和聚合度量(Metrics)**。 - -- Metrics,一般用来计算 Events 发生数量的数据集,这些数据通常具有原子性、且可以聚合。从操作系统到应用程序,任何事物都会产生 Metrics 数据,这些数据可以用来度量操作系统或者应用是否健康。 -- Logging,描述一系列离散的事件,在缺乏有力的监控系统时,Logging 数据通常是工程师在定位问题时最直接的手段。如果说 Metrics 告诉你应用程序出现问题,那么 Logging 就告诉你为什么出现问题。 -- Tracing,微服务下,多个服务之间或多或少存在依赖,Tracing 通过有向无环图的方式记录分布式系统依赖中发生 Events 之间的因果关系。 - - -2017 年的分布式追踪峰会结束后,Peter Bourgon 撰写了总结文章《Metrics, Tracing, and Logging》[^2]系统地阐述了这三者的定义、特征以及它们之间的关系与差异,受到了业界的广泛认可。 - -
- -
- -来自于 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 \ No newline at end of file +[^2]: 参见 https://blog.sciencenet.cn/blog-829-1271882.html \ No newline at end of file diff --git a/Observability/logging.md b/Observability/logging.md index beaac785..5b3b1ae7 100644 --- a/Observability/logging.md +++ b/Observability/logging.md @@ -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 @@ -24,19 +25,35 @@ Elastic Stack 之所以流行的一个原因之一,可能是它的无侵入性 我们来看一个典型的 Elastic Stack 使用场景,大致系统架构如下(整合了消息队列和 Nginx 的架构)。
- + +

Loki 架构:与 Prometheus、Grafana 密切集成

+ 这个系统中,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 的日志系统。 + +
+ +

Loki 架构:与 Prometheus、Grafana 密切集成

+
+Loki 一个明显的特点是非常经济,Loki 不再根据日志的原始内容建立大量的全文索引,而是借鉴了 Prometheus 核心的思想,使用标签去对日志进行特征标记,然后归集统计。Loki 只索引与日志相关的元数据标签,而日志内容则以压缩方式存储于对象存储中, 不做任何索引,这样的话,能避免大量的内存资源占用,转向廉价的硬盘存储。相较于 ES 这种全文索引的系统,数据可在十倍量级上降低,加上使用对象存储,最终存储成本可降低数十倍甚至更低。 + + +Loki 使用与 Prometheus 相同的服务发现和标签重新标记库,编写了 Pormtail,在 Kubernetes 中 Promtail 以 DaemonSet 方式运行在每个节点中,通过 Kubernetes API 得到日志的正确元数据,并将它们发送到 Loki。 + +也正是因为这个原因,通过这些标签,既可以查询日志的内容,也可以查询到监控的内容,这两种查询被很好的兼容,节省了分别存储相关日志和监控数据的成本,也减少了查询的切换成本。 + + +说白了,Loki 吸引人的地方就在于拥有和 Prometheus 类似机制的时序数据库以及方便拓展的硬盘资源。 数据由标签、时间戳、内容组成 @@ -53,7 +70,10 @@ loki 一个明显的特点是非常经济,Loki 不再根据日志内容去建 } ``` +总体而言,Loki和ELK都是优秀的日志解决方案,适合不同的使用场景。Loki相对轻量级,具有较高的可扩展性和简化的存储架构,但需要额外的组件和有一定的学习曲线。ELK则具有丰富的可视化选项和插件库,易于学习,但相对重量级,需要复杂的存储架构和较高的硬件要求,部署和管理也比较复杂。 + +具体如何选择取决于具体场景,若是数据量适中,数据属于时序类,如应用程序日志和基础设施指标,并且应用使用kubernetes Pod形式部署,则选择Loki比较合适;而ELK则适合更大的数据集和更复杂的数据处理需求,以及更多其他组件的日志收集场景。 ## 日志展示 diff --git a/Observability/metrics.md b/Observability/metrics.md index e743fa68..568c456d 100644 --- a/Observability/metrics.md +++ b/Observability/metrics.md @@ -1,4 +1,4 @@ -# 9.2 聚合指标 +# 9.2.1 聚合指标 作为传统监控和告警领域的代名词,Metrics 最广为人知,也被各类可观测系统支持的最丰富。Metrics 一般是用来计算 Events 发生数量的数据集,例如服务 QPS、API 响应延迟、某个接口的失败数等。它们大部分都是以数字化指标出现,特征是可聚合性,在数据的处理上,Metrics 可以是实时的,也可能是区间范围的,是跟随着时间变化的时序数据。既能做常见的监控告警,也可以用来做趋势分析。 diff --git a/Observability/profiles.md b/Observability/profiles.md index c4a86974..46a2c454 100644 --- a/Observability/profiles.md +++ b/Observability/profiles.md @@ -1,4 +1,4 @@ -# Profiles +# 9.2.4 Profiles 熟悉 Go 语言的朋友一定了解 pprof,进行性能分析时,通过 pprof 的 CPU profiling 或者 Memory profiling 功能分析函数耗时以及内存占用情况。Profiles 就是进行 profiling 时程序运行的动态画像,当于动态的内部数据,说明各类资源分配的情况,能精确到进程、代码。 diff --git a/Observability/signals.md b/Observability/signals.md new file mode 100644 index 00000000..c30d742d --- /dev/null +++ b/Observability/signals.md @@ -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]系统地阐述了这三者的定义、特征以及它们之间的关系与差异,受到了业界的广泛认可。 + +
+ +
+ +来自于 Cindy Sridharan 的《Distributed Systems Observability》著作中进一步将这三个类型的数据称为可观测性的三大支柱(three pillars),不过将它们成为支柱容易让人产生误解,支柱就像一个房子的均匀受力支撑点,缺一不可。而事实上这三者都可以独立存在,系统中只存在 Logging、Tracing 也未尝不可。所以,在最新 CNCF 发布的可观测性白皮书中,将这些可观测的数据统一称为信号(Signals),主要的信号除了 Metrics、logs、traces 之外又额外增加了 Profiles 和 Dumps。 + +## 可观测数据联系 + +
+ +
+ + +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 diff --git a/Observability/tracing.md b/Observability/tracing.md index 3629b825..126b3544 100644 --- a/Observability/tracing.md +++ b/Observability/tracing.md @@ -1,13 +1,13 @@ -# 9.4 链路追踪 +# 9.2.3 链路追踪 -参阅 Uber(优步,国外的打车公司)公开的技术文档信息,它们的微服务架构中大约有 2,200 个服务,这些服务相互依赖的链路关系引用 Uber 博客中的配图[^1],供你直观感受。而分布式链路追踪所要做的事情就是通过请求粒度的轨迹追踪与数据透传,实现规模级服务之间的确定性关联。 +参阅 Uber 公开的技术文档信息,它们的微服务架构中大约有 2,200 个服务。这些服务之间的调用链路,引用 Uber 博客中的配图[^1],感受扑面来而的复杂。而分布式链路追踪所要做的事情就是**通过请求粒度的轨迹追踪与数据透传,实现分布式服务之间的确定性关联**。

Uber 使用 Jaeger 生成的追踪链路拓扑

-分布式链路追踪诞生的标志性事件就是 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 diff --git a/assets/loki-arc.png b/assets/loki-arc.png new file mode 100644 index 00000000..8ca45edb Binary files /dev/null and b/assets/loki-arc.png differ diff --git a/assets/loki-overview.png b/assets/loki-overview.png new file mode 100644 index 00000000..a04ab29e Binary files /dev/null and b/assets/loki-overview.png differ diff --git a/assets/observability-signals.png b/assets/observability-signals.png new file mode 100644 index 00000000..f7f5b1a0 Binary files /dev/null and b/assets/observability-signals.png differ