1. 监控、链路追踪、日志
对于一个系统来说,监控、链路追踪、日志的这三者需求都是必然存在的,而有的时候我们会搞不清楚这三者相互之间是什么关系。
我之前在做系统设计的时候也考虑过,是不是有必要引入那么多组件,毕竟如果这三者完全分开每一个一项的话,就有三个组件了(事实上就是:Prometheus+Grafana、Jaeger、ELK)。
因此想做个笔记尝试举例来梳理下。
Metrics, tracing, and logging 地址:
http://peter.bourgon.org/blog/2017/02/21/metrics-tracing-and-logging.html
2. 监控
Monitoring(监控)举例来说就是:定期体检。
使用监控系统把需要关注的指标采集起来,形成报告,并对需要关注的异常数据进行分析形成告警。
特点是:
低频
定期
定量
这也是Prometheus的架构做得非常简单的原因,Monitoring的需求并没有包含非常高的并发量和通讯量。反过来说:高并发、大数据量的需求并不适用于Monitoring这个点。
3. 链路追踪
Tracing(链路追踪)举例来说就是:对某一项工作的定期汇报。某个工作开始做了A,制作A事件的报告,收集起来,然后这个工作还有B、C、D等条目,一个个处理,然后都汇总进报告,最终的结果就是一个Tracing。
特点是:
高频
巨量
有固定格式
因为Tracing是针对某一个事件(一般来说就是一个API),而这个API可能会和很多组件进行沟通,后续的所有的组件沟通无论是内部还是外部的IO,都算作这个API调用的Tracing的一部分。
可以想见在一个业务繁忙的系统中,API调用的数量已经是天文数字,而其衍生出来的Tracing记录更是不得了的量。其特点就是高频、巨量,一个API会衍生出大量的子调用。
也因此适合用来做Monitoring的系统就不一定适合做Tracing了,用Prometheus这样的系统来做Tracing肯定完蛋(Prometheus只有拉模式,全部都是HTTP请求,高并发直接挂掉)。
一般来说Tracing系统都会在本地磁盘IO上做日志(最高效、也是最低的Cost),然后再通过本地Agent慢慢把文本日志数据发送到聚合服务器上,甚至可能在聚合服务器和本地的Agent之间还需要做消息队列,让聚合服务器慢慢消化巨量的消息。
Tracing在现在的业界是有标准的:OpenTracing,因此它不是很随意的日志/事件聚合,而是有格式要求的日志/事件聚合,这就是Tracing和Logging最大的不同。
4. 日志
Logging(日志)举例来说就是:废品回收站。各种各样的物品都会汇总进入到配品回收站里,然后经过分门别类归纳整理,成为各种可回收资源分别回收到商家那里。一般来说我们在大型系统中提到Logging说的都不是简单的日志,而是日志聚合系统。
从本质上来说,Monitoring和Tracing都是Logging,Logging是这三者中覆盖面最大的超集,而前两者则是其一部分的子集。Logging最麻烦的是,开发者也不会完全知道最后记录进入到日志系统里的一共会有哪些东西,只有在使用(检索)的时候才可能需要汇总查询总量中的一部分。
要在一般的Loggin系统中进行Monitoring也是可以的,直接把聚合进来的日志数据提取出来,定期形成数据报告,就是监控了。Tracing也是一样,只要聚合进了Logging系统,有了原始数据,后面要做都是可以做的。因此Logging系统最为通用,其特点和Tracing基本一致,也是需要处理高频并发和巨大的数据量。
5. 总结
这样一看就很清楚了,每个组件都有其存在的必要性:
Monitoring系统(Prometheus)从根本的需求和基本设计上就不可能支持Tracing和Logging:低频 vs 高频、低量 vs 高量,其从设计到实现就只为了监控服务
Tracing系统(Jaeger)对提供的数据有格式要求,且处理方式和一般的Logging也不同,有更限定的应用范围
Logging系统(ELK)可以处理前两者的需求,但前两者的领域有更专业的工具就不推荐直接使用普通的日志聚合系统了;Logging系统一般用来处理大型系统的日志聚合以及检索查询