说出来你们可能不信,我差点因为一个数字,让整个运维监控系统直接“罢工”。对,就是那个藏在分布式追踪配置里,看起来人畜无害的——采样率。
刚开始搞分布式追踪那会儿,我和团队都挺兴奋的。看着Jaeger UI里一条条清晰的调用链路,那种“一切尽在掌握”的感觉别提多爽了。我们大手一挥,在配置文件里豪气地写下了:sampling.probability: 1.0。翻译成人话就是:来一个请求,我就记录一个,100%全采! 我们觉得,数据嘛,当然是越全越好,这才能不漏掉任何蛛丝马迹。
平静水面下的“存储海啸”
问题在流量洪峰到来时露出了獠牙。那是一次大促活动,平时温顺的QPS曲线瞬间变成了陡峭的山峰。起初一切正常,直到负责收集数据的服务开始疯狂报警,CPU和内存使用率直线拉满,紧接着,Jaeger的查询界面变得比蜗牛还慢,最后干脆打不开了。
我们手忙脚乱地登录服务器,用du -sh命令一看,好家伙,存储空间被追踪数据塞得满满当当,Jaeger的后端存储(我们用的Elasticsearch)索引数量暴增,磁盘I/O直接卡死。那一刻我才恍然大悟,100%采样率在流量面前,就像开着消防水龙头接露水,不仅浪费,而且灾难。 每一个Span都是要序列化、传输、存储、索引的,这背后全是真金白银的资源和算力。
“一刀切”的尴尬:要么太多,要么太少
吃一堑长一智,我们赶紧把采样率调到了0.01(也就是1%)。系统压力瞬间下去了,世界恢复了清净。但没过多久,新的烦恼来了。
当我们想复盘一个特定的、低概率的诡异bug时,发现它在追踪系统里“消失”了。因为采样率太低,那个触发bug的请求恰好没被采样到。我们只能又回到原始的日志海洋里“捞针”,分布式追踪的价值大打折扣。这感觉就像,你买了个高清监控摄像头,却为了省电,设定它每分钟只拍一张照片,结果小偷正好在没拍照的那59秒里光顾了。
动态采样:给聪明人的“后悔药”
真正的转折点,是我们开始研究“动态采样”。这玩意儿简直就是为生产环境量身定做的。它的核心思想不再是“随机抽查”,而是“智能抓取”。
- 抓“坏蛋”:任何返回5xx服务器错误、或4xx客户端高频错误的请求,采样率直接拉到100%。错误是排障的黄金线索,一个都不能放过。
- 抓“乌龟”:设定一个响应时间阈值,比如超过2秒的请求,采样率提高到50%甚至更高。慢请求是性能瓶颈的直观体现,必须重点关照。
- 抓“重点户”:对核心业务接口(比如支付、下单),保持一个中等偏上的固定采样率(比如10%),确保业务核心链路的可见性。
- 日常“巡视”:对于海量的、健康的普通请求,只保留一个很低的采样率(比如0.1%),用于监控整体链路拓扑和SLA情况,成本极低。
我们用OpenTelemetry Collector的probabilistic和tail采样处理器组合,配合一些自定义属性(比如http.status_code, duration)来实现这套规则。配置起来不复杂,但效果是革命性的。
系统资源占用变得平稳可控,再也没爆过。同时,所有我们关心的“异常事件”,几乎一个不落地被捕捉了下来。 排查问题时,我们不再需要祈祷“运气”好能让问题请求被采样到,而是有了一种笃定的掌控感。
所以,别再小看采样率这个参数了。它不是一个简单的百分比,而是一种资源与信息获取之间的平衡艺术,更是运维智慧的一种体现。从“全都要”的贪婪,到“一刀切”的无奈,再到“聪明选”的从容,这坑我踩过了,希望你能直接跨过去。毕竟,我们的目标不是收集最多的数据,而是用最小的代价,拿到最有价值的信息。

哈哈,跟我之前一模一样,上来就1.0,结果磁盘告警短信收麻了。