监控账单贵,多半是你舍不得扔数据

简介: 监控账单贵,多半是你舍不得扔数据

监控账单贵,多半是你舍不得扔数据

上个季度有个组来找我看账单。机器没加,QPS 也没翻倍,Mimir 和日志的费用却涨了将近四成。打开用量一看,不是业务火了,是某个服务把 user_id、order_id 打进了指标标签,再配上默认的全量 trace。后端很老实,你送多少它就存多少,然后按存储和样本数跟你算账。

我的看法很简单。降监控成本的主战场不在 Grafana 看板,在数据进库之前。 Grafana Agent 负责把指标在边上剃干净,OpenTelemetry Collector 负责把日志和链路里那堆“看起来有用”的噪音丢掉。两边都不做,你在后端写再狠的保留策略,也只是在为已经付过钱的数据办葬礼。

钱到底花在哪

指标贵在基数。一条指标乘上标签组合,就是时间序列。status、method、route 这种低基数标签,留着。user_id、trace_id、完整 URL,留一条就等于给每个用户开一张表。序列一旦写进库,查询慢是小事,存储和内存是按月交钱。

链路贵在量。一条请求十几个 span,再乘实例数,对象存储和索引都会涨。排障时你真正回头看的,是错误、慢请求,再加上一点点正常样本。剩下的百分之九十,进了库也没人点开。

日志同理。健康检查、心跳、循环打印的 debug,白天看着没感觉,月底账单最有感觉。

所以刀要落在采集侧。进库之后再删,省的是明天的盘,不是今天已经产生的写入。

Agent 做指标门卫

Grafana Agent 这几年的位置要说清楚。新集群我会直接上 Grafana Alloy,Agent 已经进入维护期,配置模型也在往 River 靠。但线上还有一大批 Agent 在跑,短期不会一夜换掉。下面这段就是 Agent Flow 模式里我最常留的一种写法:先抓,再按指标名留白名单,最后才 remote_write。

prometheus.scrape "apps" {
  targets    = [{"__address__" = "app:8080", "service" = "order"}]
  forward_to = [prometheus.relabel.keep.receiver]
  scrape_interval = "30s"
}

prometheus.relabel "keep" {
  rule {
    source_labels = ["__name__"]
    regex         = "http_requests_total|http_request_duration_seconds_bucket|process_cpu_seconds_total|process_resident_memory_bytes"
    action        = "keep"
  }
  rule {
    regex  = "user_id|order_id|trace_id"
    action = "labeldrop"
  }
  forward_to = [prometheus.remote_write.mimir.receiver]
}

prometheus.remote_write "mimir" {
  endpoint {
    url = "https://mimir.example.internal/api/v1/push"
  }
}

这段在干什么:默认不信任应用暴露的全部指标。只留请求量、延迟分布、CPU、内存。再把三个最容易把基数打爆的标签扔掉。

为什么用白名单而不是黑名单:应用一发版就会多出一批“临时调试指标”。黑名单永远在追新名字,白名单是你主动说“看板需要这些”。少抓一点不可怕,看板缺了再加,是一次配置变更。多抓进去的高基数序列,清理起来要等比写入更难受。

生产上我会改三处。抓取间隔别一律 15 秒,在线接口 30 秒够用,批处理任务 60 秒也够。remote_write 要配队列和重试上限,Agent 挂了可以丢一小段,不要在本地把磁盘打满。白名单放到代码库,和看板一起评审。谁要加 user_id,让他先算一下这个服务有多少用户,再决定要不要为这条线付费。

Collector 做链路和日志的过滤器

指标适合在边上直接丢。链路不太一样。如果在应用里就按百分比把头采样做死,你会发现:被采中的全是成功请求,真正的 500 被掷硬币扔了。所以采样放在 Collector 上做尾部采样,先看完整 trace,再决定留不留。

receivers:
  otlp:
    protocols:
      grpc:
        endpoint: 0.0.0.0:4317

processors:
  memory_limiter:
    check_interval: 1s
    limit_mib: 512
    spike_limit_mib: 128
  filter/health:
    error_mode: ignore
    traces:
      span:
        - 'attributes["http.route"] == "/health" or attributes["http.route"] == "/ready"'
  tail_sampling:
    decision_wait: 10s
    policies:
      - name: keep-errors
        type: status_code
        status_code: {
   status_codes: [ERROR]}
      - name: keep-slow
        type: latency
        latency: {
   threshold_ms: 800}
      - name: keep-some-ok
        type: probabilistic
        probabilistic: {
   sampling_percentage: 5}
  batch:
    timeout: 5s
    send_batch_size: 8192

exporters:
  otlphttp:
    endpoint: https://tempo.example.internal

service:
  pipelines:
    traces:
      receivers: [otlp]
      processors: [memory_limiter, filter/health, tail_sampling, batch]
      exporters: [otlphttp]

错误和慢请求全留,正常请求留 5%,健康检查直接丢掉。decision_wait 是在用内存换判断时间,trace 要凑齐再决定,所以 Collector 不能无脑缩成小规格。memory_limiter 放在最前面,内存顶不住就丢,别把节点拖死。丢数据要在日志里看得见,不然你会以为采样策略很稳,其实是进程在 OOM 边缘随机丢。

日志我也走 Collector,不走“全部进 Loki 再在查询里过滤”。查询过滤不省钱,入库前丢掉才省钱。健康检查、低于 info 的调试日志、已知的心跳报文,在 filter 里按属性丢掉。保留周期仍然后端说了算,但写入量已经小一截。

一个假设的账

数字是假设,方便感受量级,不是某家公司的账单。

一个服务每天 2 亿 span。全量进 Tempo,对象存储和索引都按这个量计。改成错误全留、慢请求全留、成功只留 5% 之后,真正落盘的大约是原来的一成出头,具体取决于错误率。错误率如果已经到 20%,尾部采样省不下这么多,这时该修的是服务,不是采样率。

指标这边,假设原来 40 万条活跃序列,其中三成来自一个高基数标签。在 Agent 上把这个标签丢掉,序列回到个位数万。远端存储的内存和查询延迟会一起下来。这不是调优魔法,是你不再为“每个用户一个序列”付费。

几个容易想岔的地方

采样率不是越低越好。 正常流量留太少,延迟分位会漂,发布对比也失真。我的习惯是错误和超时不采样,正常流量按看板能不能看清来定百分比,而不是按“能省多少”来定。

先缩保留天数,往往是安慰剂。 30 天改 15 天,看起来账单腰斩,其实高基数写入还在,近两周的查询一样贵,索引一样大。保留期是第二刀。第一刀是别写进去。

Agent 和 Collector 不要叠两层同样的抓取。 我见过同一组指标,DaemonSet 里的 Agent 抓一遍,应用 sidecar 里的 Collector 再抓一遍,remote_write 打到同一个租户。账单翻倍的原因有时候就这么笨。谁是指标出口、谁是链路出口,画在一张图上,一个信号只允许一条路。

还有一句不太中听的。全量可观测是销售话术,不是工程目标。你要的是出了问题能定位,不是把生产当成数据仓库养着。能回答“这个接口现在慢不慢、错没错、是不是这次发布引入的”,指标加少量链路就够了。剩下的,等真正需要时再临时打开,比全年开着便宜得多。

落地时我实际守的线

Collector 按节点或按命名空间部署,给内存限额,限额到了就丢并告警,不要无限撑。尾部采样的等待时间别超过 10 到 15 秒,不然排障的人会觉得 trace“丢了”,其实还在内存里排队。

Agent 的白名单和 Collector 的丢弃规则进 Git,走评审。线上临时加一个 debug 指标可以,过一周没人认领就收回。这个比任何成本仪表盘都有效。

别把这套说成万能。合规要求全量审计日志的系统,不能用同一把刀去砍。极低流量的核心支付链路,5% 成功样本可能不够复盘,就单独放宽。成本优化是默认策略,关键路径可以买保险,但不能让保险变成全公司的默认套餐。

新环境我不会再新写一套 Agent 配置,会迁到 Alloy,处理器模型是同一套思路。已经跑着的 Agent 不值得为了“新名字”连夜替换,等下次改采集规则时一并迁走就行。工具会换,边上先过滤这件事不会换。

数据进库之前丢掉,才叫省钱。进库之后再删,叫付完钱再后悔。

目录
相关文章
|
13天前
|
Linux 开发工具 iOS开发
Codex保姆级教程(下载+安装+登录+使用,含所有版本,2026最新)
Codex是OpenAI推出的开源AI编程智能体,本地运行,可理解整个代码库,支持自然语言指令改代码、执行命令、跑测试、修Bug,兼容Win/macOS/Linux。(239字)
5438 40
|
13天前
|
JavaScript API iOS开发
DeepSeek Harness下载、安装、配置一篇搞定(2026整理,送常用插件)
DeepSeek Harness(DSH)是DeepSeek于2026年开源的MIT协议AI Agent框架,支持插件化组装模型、工具、沙箱与UI,兼容主流大模型。本文提供免Node.js的桌面端安装包(Win/macOS),含详细图文教程及热门插件推荐。
4771 56
|
8天前
|
Linux 开发工具 iOS开发
2026最新codex下载安装保姆级使用教程(下载+安装+登录+使用,含所有历史版本)
本文详解OpenAI Codex国内快速上手指南:提供Win/macOS/Linux全平台免安装包、npm/Homebrew等多方式安装、账号/API Key双登录、简体中文切换,覆盖下载、安装、汉化、使用及高频避坑(如微软商店失败、npm超时等),10分钟即可跑通。
1969 6
|
14天前
|
iOS开发 Docker MacOS
【2026实测】Docker Desktop下载、安装、汉化、配置教程(附官网安装包)
Docker Desktop 是 Docker 官方推出的桌面容器管理工具,集成引擎、CLI、图形界面与 Kubernetes,支持 Win/macOS/Linux。2026 最新版 4.88.1 强化 ARM 原生运行、镜像加速及资源可视化,附中文汉化与国内镜像配置指南。
2267 7
|
5天前
|
人工智能 安全 API
DeepSeek Harness下载、安装、配置一篇搞定(2026整理,送常用插件)
DeepSeek Harness(dsh)是DeepSeek AI于2026年开源的轻量级Agent运行框架,基于Cordis内核,践行“一切皆插件”理念。支持Web/桌面双端,开箱即用;内置多模型接入、丰富插件生态(超3.5万),适配编程、办公、创作等场景。(239字)
1249 0
|
8天前
|
云安全 人工智能 安全
|
1天前
|
云安全 人工智能 安全
|
7天前
|
人工智能 并行计算 调度
本地 AI 一键部署工具 LocModel:Windows 端集成画图、视频生成、Agent 的开源模型运行方案
LocModel 是专为 Windows 设计的一站式本地 AI 工具,支持零配置启动、自动硬件检测、GGUF 模型一键加载、文生图/视频生成及 Agent 自动化任务。适配 8G 显存,内置显存分片调度,轻松实现 AI 漫剧批量创作与离线大模型调用。(239 字)