监控指标与日志应当分开存储,指标进时序数据库,日志进检索或对象存储,这是监控系统避免资源浪费和查询瓶颈的基础。 它们就像体检单上的数字和监控视频的流水账,混在一起谁也看不清。
监控指标和日志有什么区别,为什么要分开存
指标是“数”,日志是“事”
监控指标和日志虽然同样来自服务器,但性格完全不同,指标是结构化数值:CPU使用率、请求延迟、磁盘队列深度,每几秒上报一次,字段固定、体积小,日志是非结构化文本:一行报错可能带几百字节堆栈,一条请求可能带完整参数,查询时还要做关键字匹配。
两类数据的工作负载也不一样,指标的核心操作是时间范围内的聚合,最近5分钟P99延迟是多少”,日志的核心操作是翻出原始记录,这个订单号在那一刻到底报了什么错”。
把它们放进同一个存储,会出现两个冲突:
- 写入模式冲突:指标是高频小写入,日志是批量大写入,同一套写入路径会互相阻塞。
- 压缩方式冲突:时序数据用浮点压缩效果极佳,日志文本压缩出来体积仍然可观,混存后两者都吃不饱。
存储引擎的底层设计截然不同
时序数据库(TSDB)为单调递增的时间序列做了索引和压缩优化,比如Prometheus、VictoriaMetrics,日志系统为全文检索做了倒排索引,比如Elasticsearch、Loki。
行业共识认为,这两类数据在底层模型上天然对立,混用会让查询和压缩都陷入被动,把指标写进ES,等于用词典当记事本,索引开销大,聚合性能差;把日志写进TSDB,等于用二维码存文章,细节全部丢掉。
所以在设计监控系统时,第一件事就是从物理层面把两种数据分开,这里的“介质”不一定是硬盘类型,而是存储引擎和索引模型,哪怕两台服务共用一块磁盘,只要表结构是分开的,也算介质隔离。
监控指标存储选什么数据库:时序库是底线

指标写入和查询的典型压力
指标数据有固定的“脾气”:每个实例每几秒上报一次,数据点按时间顺序进入,但网络抖动会造成乱序,查询端则希望看到“一分钟内整个集群的趋势”,而不是单独某台机器。
这种模式对数据库的要求很具体:
- 写入必须是顺序追加,不能因为索引更新而停顿。
- 查询要能快速完成范围聚合,而不是全表扫描。
- 旧数据要能自动过期删除,否则磁盘会被填满。
时序库与关系库的对比
| 对比维度 | 时序数据库(如Prometheus、VictoriaMetrics) | 关系型数据库(如MySQL) |
|---|---|---|
| 写入模式 | 追加写入,批量压缩 | 随机写入,事务开销 |
| 压缩效率 | 针对浮点数优化,体积小 | 行式存储,冗余明显 |
| 典型查询 | 范围聚合、降采样 | 明细查询、多表关联 |
| 运维复杂度 | 单机可承载高指标量 | 数据增长后需分库分表 |
业内专家指出,监控查询的大部分压力都集中在最近一段时间,控制指标成本的关键不是不停买磁盘,而是降低历史数据的精度。
实操:保留周期与降采样配置
以Prometheus为例,可以在启动参数中指定保留周期和最大体积:
./prometheus \
--storage.tsdb.retention.time=15d \
--storage.tsdb.retention.size=30GB
超过保留周期的旧数据由TSDB自动清理,若想保留更长时间的历史趋势,可以开启服务端聚合,用Recording Rule把原始数据降采样后再保存:
groups:
- name: downsampling
interval: 5m
rules:
- record: job:http_requests_total:avg5m
expr: avg(rate(http_requests_total[5m]))
这样原始数据只占前15天的空间,长期数据以聚合方式存在,查询趋势时速度依然很快。
日志存储用es还是clickhouse:先看成本模型
日志的宿命:全文检索还是批量分析
日志查询通常有两种典型需求,一是定位问题,用订单号或异常关键字搜索原文;二是统计趋势,比如计算某接口错误率,前者靠全文检索,后者靠列式聚合。
Elasticsearch用倒排索引解决关键字搜索,查起来快,但每个字段都要建立索引,磁盘开销随之上涨,ClickHouse用列式存储解决海量扫描,聚合性能好,但检索原文需要额外的表结构和函数支持,Loki则直接索引标签,日志原文放对象存储,成本最低,但查询速度依赖搜索范围。
日志存储成本高怎么办:分热度治理
日志存储成本高并不是因为日志本身大,而是索引冗余,不少团队把几十个字段全部建索引,日志量才几十GB,ES已经吃掉了数倍磁盘。
常见的解决路径很明确:
- 把日志按热度分开,热日志保留1天,温日志保留30天,冷日志转存对象存储。
- 生产环境的日志做完整索引,开发测试环境只收不索引,甚至直接丢弃。
- 能用规则识别的错误类型,提前用日志分析工具做聚合,减少原始日志的检索频率。
这套做法在不同规模的系统里验证过多轮,从几十台到上千台的监控场景,都可以通过分级治理把日志成本拉回合理范围。
自建还是云托管:监控存储方案对比
一套架构中拆分指标和日志
在具体落地时,可以采用“采集统一、存储分流”的方式,Fluent Bit或Vector负责采集所有日志和节点指标,然后按类型发给不同后端。
以Fluent Bit为例,日志输出到Loki的配置非常简单:
[INPUT]
Name tail
Tag app.log
Path /var/log/app.log
[OUTPUT]
Name loki
Host loki
Port 3100
Labels job=app
指标部分仍然由Prometheus抓取,写入VictoriaMetrics,两套存储互不干扰,查询却在同一个Grafana面板中完成。
自建与云托管的真实差异
| 对比维度 | 自建时序库+日志库 | 云托管监控套件 |
|---|---|---|
| 成本结构 | 硬件投入,长期可控 | 按量付费,后劲需评估 |
| 扩容速度 | 需采购和部署 | 秒级伸缩 |
| 数据控制 | 完全自主 | 受制于厂商策略 |
对于已有机房的团队,自建往往性价比较高,对于临时项目或快速增长的业务,云托管省心很多,但要注意日志检索的按量计费项经常在账单里占到大头,尤其是华东、华北地域的云上环境,这项费用往往成为月度账单的主要组成部分,这也是监控存储方案对比中最容易忽略的部分。
监控指标与日志分开存储,等于把“数”和“事”安置在各自擅长的地方,指标负责趋势预警,日志负责细节定位,两者各司其职,故障排查时才能快速把时间线拼起来。
监控指标和日志分开存储的常见问题
监控指标和日志必须分开存储吗?
不一定必须,但强烈建议,小规模系统可以临时共用Elasticsearch,但当指标写入量上来后,索引压力会直接影响日志查询响应,最直观的判断标准是:一类数据的写入是否拖垮了另一类数据的查询,若出现这种情况,就该立刻拆分。
日志量很大,存储成本高怎么办?
优先缩短热日志保留周期,把超过30天的数据转入对象存储,或使用Loki的boltdb-shipper方案对接S3,对于没有检索价值的开发日志,直接做采样丢弃,成本高的根因通常不是日志本身的体量,而是索引策略过于激进,优化字段映射比扩容机器更有效。
小规模系统也需要用两套存储吗?
可以用轻量组合:单机Prometheus负责指标,Loki单二进制模式负责日志,两者共用一块主机磁盘就能运行,这套组合能支撑数百台机器的监控负载,且迁移成本很低,当规模继续增长时,再分别把Prometheus换成VictoriaMetrics、把Loki换成Elasticsearch集群即可。
