【ArchSummit】如何通过AIOps推动可量化的业务价值增长和效率提升?>>> 了解详情
写点什么

Observability 之深度采样 Sampling 场景和落地案例(下)

  • 2022-08-12
    北京
  • 本文字数:5172 字

    阅读完需:约 17 分钟

Observability之深度采样Sampling场景和落地案例(下)

案例分享和深度思考


整理过去自己项目和查阅了圈内一些朋友分享案例。


一方面,通过案例给大家一些技术实现和选型的参考。


另一方面,做可观测系统采样设计,从产品、业务、技术不同的维度去做一些思考。


希望对大家有帮助。

采样规则策略:要不要做全量采样?


业务系统接入全链路监控

伴鱼案例

2020 年,我们不断收到业务研发的反馈:能不能全量采集 trace?这促使我们开始重新思考如何改进调用链追踪系统。我们做了一个简单的容量预估:目前 Jaeger 每天写入 ES 的数据量接近 100GB/天,如果要全量采集 trace 数据,保守假设平均每个 HTTP API 服务的总 QPS 为 100,那么完整存下全量数据需要 10TB/天;乐观假设 100 名服务器研发每人每天查看 1 条 trace,每条 trace 的平均大小为 1KB,则整体信噪比千万分之一。可以看出,这件事情本身的 ROI 很低,考虑到未来业务会持续增长,存储这些数据的价值也会继续降低,因此全量采集的方案被放弃。退一步想:全量采集真的是本质需求吗?实际上并非如此,我们想要的其实是「有意思」的 trace 全采,「没意思」的 trace 不采。

货拉拉案例

2.0 架构虽然能满足高吞吐量,但是也存在存储成本浪费的问题。其实从实践经验看,我们会发现 80~90%的 Trace 数据都是无价值的、无意义的数据,或者说是用户不关心的。那么用户关心哪些数据呢?关心链路中错、慢的请求以及部分核心服务的请求。那么我们是不是可以通过某些方式,把这些有价值的数据给过滤采样出来从而降低整体存储成本?

在这个背景下,我们进行 3.0 的改造,实现了差异化的完成链路采样,保证 1H 以内的数据全量保存,我定义它为热数据,而一小时以外的数据,只保留错、慢、核心服务请求 Trace,定义为冷数据,这样就将整体的存储成本降低了 60%


伴鱼和货拉拉的落地实践看出:有一定数据量的链路系统,全量采样对于业务系统并非有价值,甚至说完全没必要。从业务角度,少量采样是一个很合理节省资源成本方案,这在生产环境是经过验证的。


阿里鹰眼


鹰眼是基于日志的分布式调用跟踪系统,其理念来自于 Google Dapper 论文,其关键核心在于调用链,为每个请求生成全局唯一的 ID(Traceld)目前支撑阿里集团泛电商、高德、优酷等业务,技术层面覆盖前端网关接入层、远端服务调用框架(RPC)、消息队列、数据库、分布式缓存、自定义组件(如支付、搜索 SDK、本地方法埋点等)


鹰眼在面对海量数据,采样比较简单:百分比取样

https://www.infoq.cn/article/kMPZTgJqs7VJC5vkVCR2

90%链路数据采集意义不大


思考「没意思」的 trace 不采,「有意思」的 trace 全采


生产环境绝大部分链路数据平时需要采集么?往往我们的生产环境就正如伴鱼情况类似:


1、监控系统采集了成千上万的链路数据,花了大量服务器资源存储数据,同时还不得不面对高并发带来的性能问题,投入不菲的研发人力做性能调优。


2、监控系统真正研发看的时间很低频,可能在请求量大的活动,或者重大发布时,研发团队会

只有在真正系统异常时候会关注链路数据,而且对每一个链路节点的信息都如视珍宝,很有可能从一些细节定位到故障和原因。


所以,生产环境是稳定性远远大于故障时间,我们很多公司甚至要求 SLO 达到 99% 可用性。从另外一个维度反映出:平时,系统稳定态,95%以上链路数据是正常的,所以它们并不需要那么关注。当然,并不是说你可以完全无视这些链路数据,它的价值体现在你怎么用它,比如下面一些场景:


1、链路数据用做用户行为分析的大数据来源。它往往不需要实时性计算,离线处理。


2、历史链路数据可以作为周期性异常预测的大数据来源。


只不过,95%链路数据价值已经很小了。如果你的场景不涉及 1、2,其实完全可以考虑节约成本。甚至在异常预测场景,也可以很小部分的全采样,只要达到你想要的数据样品范围足够。

哪些是应该全量采集的链路


关注的调用链全采样:研发在分析、排障过程中想查询的任何调用链都是重要调用链。比如伴鱼提到日常排障经验,总结以下三种优先级高场景:


A、在调用链上打印过 ERROR 级别日志


B、在调用链上出现过大于 200ms 的数据库查询


C、整个调用链请求耗时超过 1s


关心的调用链,从日志级别、响应时间、核心组件的性能指标(这里举例数据库)几个维度入手

只要服务打印了 ERROR 级别的日志就会触发报警,研发人员就会收到 im 消息或电话报警,如果能保证触发报警的调用链数据必采,研发人员的排障体验就会有很大的提升;

 

我们的 DBA 团队认为超过 200ms 的查询请求都被判定为慢查询,如果能保证这些请求的调用链必采,就能大大方便研发排查导致慢查询的请求;

 

对于在线服务来说,时延过高会令用户体验下降,但具体高到什么程度会引发明显的体验下降我们暂时没有数据支撑,因此先配置为 1s,支持随时修改阈值。当然,以上条件并不绝对,我们完全可以在之后的实践中根据反馈调整、新增规则,如单个请求引起的数据库、缓存查询次数超过某阈值等


尾部采样的好处


调用链追踪系统支持了稳态分析,而业务研发亟需的是异常检测。要同时支持这两种场景,采用尾部连贯采样 (tail-based coherent sampling)。相对于头部连贯采样在第一个 span 处就做出是否采样的决定,尾部连贯采样可以让我们在获取完整的 trace 信息后再做出判断


我们再看看货拉拉对「有意思」的 trace 策略 :错、慢、核心服务采样

提出另外一种方案,就是更深入一点,从 Trace 详情数据入手。我们可以看到这个 Trace 的结构是由多个 Span 组成,Trace 维度包含 APPID、Latency 信息 Span 维度又包含耗时、类型等更细粒度的信息,根据不同的 Span 类型设置不同的阈值,比如远程调用 SOA 耗时大于 500ms 可以认为是慢请求,而如果是 Redis 请求,阈值就需要设置小一些,比如 20ms,通过这种方式可以将慢请求规则更精细化,同样可以通过判断 APPID 是否为核心服务来过滤保留核心服务 Trace 数据



可以看出,货拉拉采样维度和伴鱼场景类似,相同的响应时间,核心组件的性能指标,还加了高级扩展:精细化采样,通过 APPID 来获取想要服务的全链路采样。

常用采样策略


根据 TraceId 中的顺序数进行采样,提供了多种采样策略搭配:


  • 百分比采样:主要用在链路最开始节点

  • 固定阈值采样:全局或租户内统一控制

  • 限速采样:在入口处按固定频率采样若干条调用链;

  • 异常优先采样:调用出错时优先采样;

  • 个性化采样:按用户 ID、入口 IP、应用、调用链入口、业务标识等配置开启采样

链路完整采样


链路完整性:


这里举个例子,如图现在有一条远程调用,经过 ABC 和分支 AD。这里有个前提就是 ABCD 它是 4 个不同的服务,独立异步上报 Trace 数据没有严格的时间顺序。在 B 调用 C 出现异常时,我们能轻松识别到并将 B 和 C 的 Trace 数据段采样到,只保留 B 和 C 的这种情况,称为部分采样。但是在实际的一个排障过程中,我们还需要 A 和 D 这条链路数据作为辅助信息来支持排障,所以最好的方式是把 ABCD 都采样到,作为一个完整的异常链路保存起来,这称为完整采样。

 

采样是如何保证链路的完整性?

我们的目标是完整采样,如何实现完整采样也是业界的一个难点,当前行业有一些解决方案,比如阿里鹰眼和字节的方案

阿里鹰眼方案


阿里鹰眼采用一直纯内存的解决方案:


例如现在有个链路经过 ABCD 和分支 AE,B 调用 C 出现异常时,他会做一个染色标记,那么 C 到 D 自然也携带了染色标记,理论上 BCD 会被采样的保存起来,但是 A 和 E 是前置的节点也没有异常也没被染色,该怎么办呢?他引入一个采样决策点的角色,假设 B 出了异常,采样决策点感知到,最后在内存里查是否存在像 A 和 E 这种异常链路的前置节点,然后将它保存起来。


这里需要注意这种场景对查询的 QPS 要求非常的高,那如果不是存在内存而是类似 HBase 这种服务里的话是很难满足这种高 QPS 的需求。所以他选择将一小时或者半小时内的 Trace 数据放内存中,来满足采样决策点快速查询的要求。


但基于内存存储也存在弊端,因为内存资源是比较昂贵的。我们做个简单的计算,如果想保存 1 小时以内的 Trace 数据,单条 Trace 2K 大小,要支撑百万 TPS,大约需要 6T 内存,成本比较高

字节跳动方案


提出 PostTrace 后置采样方案。


当一个 Trace 一开始未命中采样,但在执行过程中发生了一些令人感兴趣的事(例如出错或时延毛刺)时,在 Trace 中间状态发起采样。PostTrace 的缺点只能采集到 PostTrace 时刻尚未结束的 Span,因此数据完整性相较前置采样有一定损失。


发生错误的服务将采样决定强制进行翻转,如果这条链路没有进行采样的话。但这样的话会丢失采样决策改变之前的所有链路以及其他分支链路的数据。

我们结合一个示例来更好的理解什么是 PostTrace。左图是一个请求,按照阿拉伯数字标识的顺序在微服务间发生了调用,本来这条 trace 没有采样,但是在阶段 5 时发生了异常,触发了 posttrace,这个 posttrace 信息可以从 5 回传到 4,并传播给后续发生的 6 和 7,最后再回传到 1,最终可以采集到 1,4,5,6,7 这几个环节的数据,但是之前已经结束了的 2、3 环节则采集不到。右图是我们线上的一个实际的 posttrace 展示效果,错误层层向上传播最终采集到的链路的样子。PostTrace 对于错误链传播分析、强弱依赖分析等场景有很好的应用

 

染色采样:对特定的请求添加染色标记,SDK 检测到染色标对该请求进行强制采样

这些采样策略可以同时组合使用。采样不影响 Metrics 和 Log。Metrics 是全量数据的聚合计算结果,不受采样影响。业务日志也是全量采集,不受采样影响

货拉拉方案


基于 Kafka 延迟消费+布隆过滤器实现:

实时消费队列:根据采样规则写入 Bloom 过滤器,热数据全量写入热存储;

延迟消费队列:根据 Bloom 过滤器实现条件过滤逻辑,冷数据写入冷存储。

基于 Kafka 延迟消费+Bloom Filter 来实现完整采样。


比如说我们 Kafka 有两个消费组,一个是实时消费,一个是延迟消费,实时消费每条 Trace 数据时会判断下是否满足我们的采用规则,如果满足就将 TraceID 放在 Bloom Filter 里,另外一方面延时消费组在半小时(可配置)开始消费,从第一条 Trace 数据开始消费,针对每条 Trace 数据判断 TraceID 是否在 Bloom Filter 中,如果命中了,就认为这条 Trace 应该被保留的,从而能做到整个 Trace 链路的完整采样保存

https://www.sohu.com/a/531709613_411876


除此之外,里面其实还有一些细节,比如说 Bloom 不可能无限大,所以我们对其按分钟进行划分出多个小的 Bloom,又比如我们其实采用的是一个 Redis 的 Bloom,但 Redis Bloom 如果想达到百万 QPS 预计需要 10~20 个 2C4G 的节点,但是我们实际只用了 5 个 2C4G 的节点就能满足百万的一个吞吐量。这里涉及到专利保护规定,就不展开说了,大家如果感兴趣,有机会可以私底下聊。整体上我们就是具有这套采样方案实现整体成本的降低了 60%

OpenTelemetry 生产环境采样的案例


https://github.com/open-telemetry/opentelemetry-collector-contrib/pull/4958

OT 社区的 tailsampling 方案利用以下几个 processor 和 exporter 实现高伸缩性:

负载均衡网关 loadbalancingexporter:把属于同一个 TraceID 的所有 Trace 和 Log 分发给一组固定的下游 Collector

tailsamplingprocessor:通过预定义的组合策略进行采样

tailsamplingprocessor 支持 4 种策略:

always_sample:全采样

numeric_attribute:某数值属性位于 [min_value, max_value] 之间

string_attribute:某字符串属性位于集合 [value1, value2, …] 之中

rate_limiting:按照 spans 数量限流,由参数 spans_per_second 控制

 

以「在调用链上如果打印了 ERROR 级别日志」为例,按照规范我们会记录 span.SetTag("error" , true),但 tailsamplingprocessor 并未支持 bool_attribute;此外,未来我们可能会有更复杂的组合条件,这时仅靠 numeric_attribute 和 string_attribute 也无法实现。经过再三分析,我们最终决定利用 Processors 的链式结构,组合多个 Processor 完成采样,流水线如下图所示:



其中 probattr 负责在 trace 级别按概率抽样,anomaly 负责分析每个 trace 是否符合「有意思」的规则,如果命中二者之一,trace 就会被打上标记,即 sampling.priority。最后在 tailsamplingprocessor 上配置一条规则即可,如下所示:

tail_sampling:policies:[  {  name: sample_with_high_priority,  type: numeric_attribute,  numeric_attribute: { key: "sampling.priority", min_value: 1, max_value: 1 }  }]
复制代码


这里 sampling.priority 是整数类型,当前取值只有 0 和 1。按上面的配置,所以 sampling.priority = 1 的 trace 都会被采集。后期可以增加更多的采集优先级,在必要的时候可以多采样 (upsampling) 或降采样 (downsampling)。

OpenTelemetry Agent 

sampling OpenTelemetry 客服端的实现

Sampling using Javaagent

https://github.com/open-telemetry/opentelemetry-java-instrumentation/discussions/5803

作者介绍

蒋志伟,爱好技术的架构师,先后就职于阿里、Qunar、美团,前 pmcaff.com CTO,目前 OpenTelemetry 中国社区发起人,https://github.com/open-telemetry/docs-cn 核心维护者

欢迎大家关注 OpenTelemetry 公众号,这是中国区唯一官方技术公众号

2022-08-12 18:025778

评论

发布
暂无评论
发现更多内容

Linux环境,C/C++语言手写代码实现线程池

Linux服务器开发

c++ 线程池 Linux后台开发 服务端开发 线程池源码

T3 出行 Apache Kyuubi Flink SQL Engine 设计和相关实践

网易数帆

sql 大数据

怎样搭建企业内部wiki

小炮

企业 wiki

在线Javascript加密混淆工具

入门小站

工具

研发数字化管理,如何打破“上班摸鱼下班加班”的怪圈

方云AI研发绩效

团队管理 研发管理 研发效能 数字化转型 研发管理工具

在线HTML转MarkDown工具

入门小站

工具

乘数科技加入PolarDB开源数据库社区

阿里云数据库开源

数据库 阿里云 开源 开源数据库 polarDB

云效一站式DevOps平台

阿里云云效

云计算 阿里云 DevOps 云原生 云效

Dcm4chee--MySql版Docker镜像制作

birdbro

Docker DCM4CHE

6元自助洗车店加盟需要多少费用

共享电单车厂家

自助洗车加盟 6元自助洗车店加盟 6元自助洗车 自助洗车加盟费

万亿级超高清产业变奏,分布式存储支撑关键应用落地

焱融科技

云计算 分布式 高性能 文件存储 影视渲染

系列解读SMC-R:透明无感提升云上 TCP 应用网络性能(一)| 龙蜥技术

OpenAnolis小助手

网络协议 技术分享 龙蜥社区 RDMA SMC-R

深度剖析「圈组」消息系统设计 | 「圈组」技术系列文章

网易云信

开发 社交软件

与开源社区用户共创,首本《OceanBase 社区版入门到实战》电子书新鲜出炉啦!

OceanBase 数据库

自助洗车加盟需要投资多少?分析下

共享电单车厂家

自助洗车机 自助洗车加盟

自助扫码洗车机加盟怎么加

共享电单车厂家

自助洗车机价格 自助扫码洗车机 自助洗车怎么加盟 共享洗车加盟

2022 CCF国际AIOps挑战赛线上宣讲会成功举办

BizSeer必示科技

TiDB HTAP 遇上新能源车企:直营模式下实时数据分析的应用实践

PingCAP

高层次人才一站式服务平台系统开发 探索全方位服务新模式

a13823115807

Linux云计算之VSFTP服务器概述-安装vsftp服务器端、客户端

学神来啦

Linux 运维

阿里云数据库MongoDB版助力吉比特《一念逍遥》游戏斩获千万玩家,运营效率成倍增长

MongoDB中文社区

mongodb

Linux之tr命令

入门小站

参与开源项目很难吗?

捉虫大师

6元共享24小时自助洗车加盟如何

共享电单车厂家

24小时共享自助洗车 6元自助洗车加盟

江苏财政的数字新径,大型政企的云上坐标

脑极体

6元自助洗车设备一套多少钱一台

共享电单车厂家

自助洗车机多少钱 自助洗车机价格 自助洗车加盟 6元自助洗车设备 6元自助洗车机

脚本库详细说明 - 大屏云极简使用手册

shulinwu

体验了一把最近很火的开源项目-MASA Blazor

MASA技术团队

C# .net 微软 组件库

英特尔陈伟:以智能边缘解锁数智时代新未来

科技新消息

隐私计算势头迅猛,但金融行业用户需要“冷静”

易观分析

金融 隐私计算 AMC

架构训练营 - 模块一

junl

架构实战营

Observability之深度采样Sampling场景和落地案例(下)_语言 & 开发_蒋志伟_InfoQ精选文章