结论先行:观测数据从来不是一种数据。至少有三类:指标(随时间变化的数值)、调用拓扑(服务之间的依赖关系)、明细(单次请求的链路与日志)。三类的查询方式完全不同——指标要按时间范围做聚合,拓扑要按关系逐层展开,明细要按条件精确过滤。把它们混在一处存,结果是两个症状同时出现:查一条链路要等很久,而存储账单却一直涨。可行的做法是先按三类数据分别选存储,再按「指标发现异常、拓扑定位范围、明细取证」的路径设计查询。
本文只谈观测数据该分几类、分别存在什么形态的存储里、以及查询路径怎么顺着走,不谈容量该按什么口径估,也不谈告警规则该怎么配。
三类数据,三种查询
| 数据类别 | 典型内容 | 查询方式 | 合适的存储形态 |
|---|---|---|---|
| 指标 | 接口吞吐量、平均响应时间、分位时延、错误率、调用频次 | 按时间范围聚合、按维度分组对比 | 时序库 |
| 拓扑 | 服务之间的调用关系、依赖方向、上下游层级 | 按关系逐层展开、查上下游与影响范围 | 图数据库 |
| 明细 | 完整调用链、报错堆栈、慢语句、日志原文 | 按条件精确过滤、按单次请求回放 | 列式存储 |
三类的差别不在数据量,而在「你打算怎么问它」。
指标的查询模式是「某个时间范围内,某个维度的值是多少、变化趋势如何」。这类查询每次扫描的数据量小、聚合计算多,要求写入快、按时间索引高效。时序库就是为这个模式设计的。
拓扑的查询模式是「这个服务挂了,上游有谁、下游有谁、影响扩散到哪一层」。这类查询本质是在图上做遍历,用表结构表达会变成多层连接,越深越慢。图数据库把关系本身作为存储对象,深度遍历的成本主要取决于层数而不是数据总量。
明细的查询模式是「找出满足这几个条件的那些请求,然后逐条看」。这类查询要支持任意字段组合过滤、要能读取大字段(堆栈、原文),并且要在总量很大的情况下保持扫描效率。列式存储按列压缩、按列读取,在「只取几列但要过滤全表」这类场景里优势明显。
混着存,两个症状会一起来
常见的简化做法是全部塞进一套存储,通常是一套日志系统加一套指标系统,拓扑则靠人从明细里拼。
症状之一是查询慢。明细数据被用来回答聚合类问题(「过去一小时各接口的错误率」),意味着每次查询都要扫描海量明细再做聚合;反过来,指标数据被放进明细系统,字段多、行数大,做时间范围聚合时效率同样很低。
症状之二是存储贵。为了支撑查询效率,通常会靠加副本、加索引、加热节点来解决,而成本是按数据总量算的。当明细数据占了绝大部分体积时,为它配的高性能存储就成了账单的主要部分——但真正需要高性能查询的,其实只是最近一段时间的数据。
两个症状同时出现时,团队往往会在两个方向之间来回:先加硬件,硬件加完还是慢,再改查询方式,改到最后发现瓶颈在数据模型上。这时候返工的成本已经很高了。
查询路径:从指标到拓扑到明细
三类存储分开之后,查询这件事要按路径设计,否则用起来仍然别扭。
先看指标,发现异常。看的内容是接口的错误率、分位时延、吞吐量的趋势。这一层的信息密度最高,也最快——几秒钟就能看出「哪个接口、从什么时候开始、偏离了多少」。
再查拓扑,定位范围。知道哪个接口异常之后,下一件事是「影响面有多大」。这时查的是调用关系:这个接口的上游有哪些业务、下游依赖哪些服务、哪一层是瓶颈。这一步回答的是「要不要升级、叫谁一起来」。
最后进明细取证。范围确定后,进入具体请求的排查:取几条典型请求的完整链路,看报错堆栈、慢语句、以及那一段的日志原文。这一步的数据量最小,但读取的字段最深。
三步的价值在于每一步的代价都是递增的:先用最便宜的方式缩小范围,再用最贵的方式看细节。反过来做——一上来就翻明细——是很多团队效率低下的直接原因,因为明细里的信息量太大,人在里面找不到方向。
冷热分层,依据不是时间
分层存储几乎是必然的,但判断依据常常被简化成「几天以前的数据进冷存储」。
按天数分层的问题在于,它假设了查询热度随时间均匀衰减。实际情况不是这样:有些数据一周内没人看,但一旦出事会被反复查(典型的是一次事故的完整链路);有些数据每天都被查,但价值很低(比如某个固定报表的口径)。
更可用的判断依据是两个维度:查询频次与取证需要。
按频次分层:最近一段时间高频访问的数据放热存储,其余下沉。这一条与按时间分层接近,但它按实际访问统计,而不是按天数拍。
按取证需要分层:与事件、变更、故障相关的数据要单独标记并保留更久。这类数据的量很小,但一旦需要就是关键证据。
两个维度叠加之后,规则可以写成几条具体的:日常明细按访问统计分层,被标记为事件相关的数据保留完整的原样,指标数据长期保留但降低采样精度。第三条尤其值得做——指标是三类里最适合降精度的,历史指标看的是趋势,不需要每秒一个点。
一个容易忽略的边界:平台自己的数据
观测平台自身也是一个系统,它产生的数据(谁查了什么、什么时候改的规则、告警何时被关闭)同样需要留痕。这一类数据常被遗漏,原因是它不属于被观测对象。
但恰恰是这类数据,在事后复盘时最有价值:一条告警为什么没被发现、某次查询是谁做的、配置什么时候被改过。这些问题的答案不在业务数据里,而在平台自己的操作记录里。
深圳市奇摩计算机有限公司在做全链路监测类项目时,存储方案一般会先把三类数据分开定,再谈分层与容量。这样做的原因不复杂:先把「什么数据回答什么问题」定清楚,容量和成本的讨论才有依据——否则讨论的永远是「要不要再多买一点存储」。
落地清单
- 先把观测数据分成指标、拓扑、明细三类,逐类定查询模式。
- 按查询模式选存储形态,不要用一套存储回答三类问题。
- 查询路径按「指标发现异常、拓扑定位范围、明细取证」的顺序设计。
- 冷热分层按查询频次与取证需要判断,不只用天数。
- 与事件、变更、故障相关的明细单独标记,保留原样并延长留存。
- 历史指标降精度保留,不必保留逐秒原始点。
- 平台自身的操作记录(查询、改规则、关告警)单独留存,作为复盘依据。
若您正在规划可观测平台的存储与查询结构,或需要梳理现有监测体系的存储成本,欢迎 预约咨询。
