IT实战联盟博客:http://blog.100boot.cn

“为什么我的手机不能播放 Tiger King?”

— 一位 Twitter 网友留言

这是 Netflix on-call 工程师面临问题的一个例子:解决用户碰到的各种问题。排除这种分布式系统的故障非常困难。调查视频流故障需要检查用户账户的所有方面。在上一篇博文(1)中介绍了 Edgar,我们的流 sesion 故障排除工具。本文主要看我们是如何设计 Edgar 的追踪 (tracing) 基础设施。

(1) https://netflixtechblog.com/edgar-solving-mysteries-faster-with-observability-e1a76302c71f

分布式跟踪:提供大规模服务中故障排查的上下文

在使用 Edgar 之前,工程师必须从 Netflix 的各种微服务中筛选出大量的元数据和日志,以了解我们任何用户所经历的特定流媒体故障。重建流 session 是一个繁琐而耗时的过程,其中涉及到追踪 Netflix 应用、CDN 网络和后端微服务之间的所有交互(请求)。

这个过程从手动拉取作 session 的用户账户信息开始,并将所有的拼图碎片放在一起,希望由此产生的全景能够帮助解决用户问题。因此需要通过分布式请求追踪系统来提高生产力。

如果我们为每个流 session 提供一个ID,那么分布式追踪就可以通过提供服务拓扑、重试和错误标签以及所有服务调用的延迟测量来轻松重建会话失败。我们还可以通过将相关的跟踪与账户元数据和服务日志结合起来,获得有关流 session 的上下文信息。这种需求促使我们建立了 Edgar:一个分布式跟踪基础设施以及用户体验。

Edgar: a distributed tracing infrastructure and user experience.

图 1. 通过 Edgar 排查一个会话

4 年前,当开始构建 Edgar 时,能够满足我们需求的开源分布式追踪系统非常少。我们的策略是,在开源 trace 库成熟之前,使用 Netflix 专用工具来收集基于 Java 的流媒体服务的 trace 信息。

到 2017 年,Open-Tracing (1) 和 Open-Zipkin (2) 等开源项目已经足够成熟,可以在 Netflix 的混合运行环境中使用。我们选择了 Open-Zipkin。因为它能与我们基于 Spring Boot 的 Java 运行时环境有更好的集成。

我们使用 Mantis (3) 来处理收集到的数据,使用 Cassandra 来存储数据。分布式跟踪基础设施分为三个部分:跟踪工具库、 流式处理和存储。从各种微服务收集到的 trace 数据以流处理的方式进入数据存储中。下面的章节描述了构建这些组件的历程。

(1) https://opentracing.io/

(2) https://github.com/openzipkin

(3) https://netflixtechblog.com/open-sourcing-mantis-a-platform-for-building-cost-effective-realtime-operations-focused-5b8ff387813a

跟踪 Instrumentation:它将如何影响我们的服务?

这是我们工程团队在集成 tracer 库时提到的第一个问题。这是一个重要的问题,因为 tracer 库拦截了流经关键任务流服务的所有请求。对于 polyglot 运行时,安全集成和部署 tracer 库是我们的首要任务。我们理解工程师的运维负担,并专注于在运行时环境中提供高效的跟踪库集成,并赢得了工程师的信任。

分布式跟踪依赖于为本地进程间调用(IPC)和客户端调用远程微服务的任何任意请求传递的上下文。传递请求上下文,可以捕获运行时微服务之间调用的因果关系。

我们采用了 Open-Zipkin 的基于 B3 HTTP (1) 头的上下文传播机制。我们确保在各种集成的 Java 和 Node 运行时环境中,微服务之间正确传递了上下文传包头,这些环境既包括具有传统代码库的旧环境,也包括 Spring Boot 等新环境。

在面对 Python、NodeJS 和 Ruby on Rails 等环境的跟踪库时,执行我们文化中的自由与责任原则 (2) ,这些环境不属于集成的范围,我们松耦合但高内聚的工程团队,可以自由选择适合其运行时环境的跟踪库,并有责任确保正确的上下文传播和网络调用拦截器的集成。

(1) https://github.com/openzipkin/b3-propagation

(2) https://jobs.netflix.com/culture

我们的运行时环境集成注入了基础设施标签,如服务名称、自动伸缩组(ASG)和容器实例标识符。Edgar 使用这种基础设施标签模式来查询和加入带有日志数据的 trace 信息,以便对流 session 进行故障排除。

此外,由于标签的一致性,在 Edgar 中为不同的监控和部署系统提供深度链接变得很容易。在运行时环境集成到位后,我们必须设置一个合适的 trace 数据采样策略,以构建故障诊断功能。

流处理:采样,还是不采样?

这是我们在构建基础设施时考虑的最重要的问题,因为数据采样策略决定了记录、传输和存储的 trace 数量。宽松的跟踪数据采样策略,会在每个服务容器中产生大量的跟踪数据,并且会导致流服务的性能下降,因为跟踪库会消耗更多的 CPU、内存和网络资源。

宽松的采样策略的另一个影响是,需要可扩展的流处理和存储基础设施来处理增加的数据量。

大量取样的跟踪数据集对于故障诊断来说并不可靠,因为无法保证你想要的请求就在收集的样本中。我们需要一种周到的方法来收集微服务中的所有跟踪信息,同时保持基础设施运行的低操作复杂性。

大多数分布式跟踪系统在微服务调用图的请求摄取点强制执行采样策略。我们采取了一种基于头部的混合采样方法 (1),允许为特定的、可配置的请求集记录 100% 的跟踪,同时继续根据摄取点的策略集随机采样流量。

这种灵活性使得 tracer 库能够在关键任务流微服务中记录 100% 的 trace 信息,同时在离线批处理数据等辅助系统中 尽可能少的收集信息。我们的工程团队在考虑到由于跟踪而增加的资源使用率后,对其服务进行了性能调优。

(1) https://github.com/openzipkin-contrib/zipkin-secondary-sampling/blob/master/docs/design.md

下一个挑战是通过一个可扩展的数据处理平台来流式处理大量的跟踪数据。

Mantis 是我们处理 Netflix 运营数据的首选平台。我们选择 Mantis 作为传输和处理大量 trace 数据的主干,因为我们需要一个背压感知、可扩展的流处理系统。跟踪数据收集代理通过 Mantis Publish 库 (1) 将跟踪数据传输到 Mantis 作业集群。

(1) https://netflix.github.io/mantis/internals/mantis-publish/

我们对一个时间段的跨度进行缓冲,以便在第一个作业中收集一个跟踪的所有跨度。第二个作业从第一个作业中获取数据源,对数据进行尾部采样,并将 trace 写入存储系统。这种链式 Mantis 作业 (1) 的设置,使我们能够独立地扩展每个数据处理组件。

使用 Mantis 的另一个优势是能够使用 Mantis 查询语言 (MQL) (2) 在 Raven 中执行实时的临时数据探索。

(1) https://netflix.github.io/mantis/getting-started/concepts/#job-chaining

(2) https://netflix.github.io/mantis/reference/mql/

然而,如果你没有低成本的数据存储手段,拥有一个可扩展的流处理平台并没有什么帮助。

存储:尽量节约

由于 Elasticsearch 具备灵活的数据模型和查询能力,我们一开始就使用 Elasticsearch 作为数据存储。随着入驻更多的流媒体服务,trace 数据量开始成倍增长。由于高数据写入率导致 ElasticSearch 集群扩展的操作负担增加,这让我们感到很痛苦。数据读取查询需要越来越长的时间来完成,因为 ElasticSearch 集群使用了大量的计算资源来为新增的 trace 创建索引。

高数据摄取率最终降低了读写操作。我们通过迁移到 Cassandra 作为数据存储来解决这个问题,以处理高数据写入量。在 Cassandra 中使用简单的查找索引,使我们有能力在进行大量写入时保持可接受的读取延迟。

理论上,横向扩展可以让我们处理更高的写入率,并在 Cassandra 集群中保留更大量的数据。这意味着存储 trace 的成本与存储的数据量呈线性增长。我们需要确保存储成本的增长与存储的数据量呈亚线性关系。为了追求这个目标,我们概述了以下存储优化策略。

  1. 在 EC2 中使用更便宜的 Elastic Block Store(EBS) 卷而不是 SSD 实例存储。

  2. 采用更好的压缩技术来减少 trace 数据大小。

  3. 通过使用一些简单的基于规则的过滤器,只存储相关和有用的 trace 数据。

每当现有节点的 EC2 SSD 实例存储达到最大存储容量时,我们就会增加新的 Cassandra 节点。使用更便宜的 EBS 弹性卷,而不是 SSD 实例存储,是一个更合适的选择,因为 AWS 允许动态增加 EBS 卷的大小,而无需重新创建 EC2 节点。这使我们能够在不向现有集群添加新的 Cassandra 节点的情况下增加总存储容量。

2019 年,我们云数据库工程(CDE)团队的厉害的同事为我们的用例进行了 EBS 性能基准测试,并将现有集群迁移到使用 EBS 弹性卷。通过优化时间窗口压缩策略(TWCS)参数,他们减少了 Cassandra SSTable 文件的磁盘写入和合并操作,从而降低了 EBS 的 I/O 速率。

这种优化帮助我们减少了集群节点之间的数据复制网络流量,因为 SSTable 文件的创建频率低于之前的配置。此外,通过在 Cassandra 数据文件上启用 Zstd 块压缩,跟踪数据文件的大小减少了一半。有了这些优化后的 Cassandra 集群,现在运营集群的成本降低了 71%,而且可以比之前的配置多存储 35 倍的数据

我们观察到,Edgar 用户使用了不到 1% 的收集跟踪数据。这让我们相信,如果放弃那些用户不会关心的跟踪数据,可以减少写入压力,并在存储系统中保存更多的数据。

目前,我们在 Storage Mantis 工作中使用了一个简单的基于规则的过滤器,它可以保留 Edgar 中很少被查看的服务调用路径的有趣跟踪信息。该过滤器通过检查一个跟踪的所有缓冲跨度的警告、错误和重试标签,将一个跟踪限定为一个有趣的数据点。这种基于尾巴的采样方法在不影响用户体验的情况下,将跟踪数据量减少了 20%。

我们有机会使用基于机器学习的分类技术,来进一步减少跟踪数据量。

虽然已经取得了实质性的进展,但最近面临构建跟踪数据存储系统的另一个拐点。在 Edgar 上增加一些新的功能可能需要我们存储 10 倍于当前数据量的数据。

因此,目前正在试验一种新的数据网关的分层存储方式。这个数据网关提供了一个查询接口,抽象了从分层数据存储中读取和写入数据的复杂性。此外,数据网关将摄入的数据路由到 Cassandra 集群,并将压缩后的数据文件从 Cassandra 集群传输到 S3。我们计划将最近几个小时的数据保留在 Cassandra 集群中,其余数据保留在 S3 桶中,以便长期保留跟踪信息。

表格1:存储优化的时间表

其他收益

除了支持 Edgar 外,跟踪数据还用于以下使用场景。

应用程序健康监测

Trace 数据是 Telltale 用于监控 Netflix 宏观层面应用健康状况的关键信号。Telltale 使用 trace 中的关联信息来推断微服务拓扑,并将 trace 与 Atlas 的时间序列数据相关联。这种方法可以描绘出更丰富的应用健康状况的可观察性画像。

容错工程

我们的混沌工程团队使用 trace 来验证故障是否被正确注入,同时工程师通过故障注入测试(FIT)平台对其微服务进行压力测试。

地域容灾

需求工程团队利用跟踪数据来提高地域迁移期间伸缩的正确性。追踪提供了与微服务交互的设备类型的可见性,这样,当 AWS 区域迁移时,可以更好地解释这些服务需求的变化。

评估运行 A/B 测试的基础设施成本

数据科学和产品团队通过分析相关 A/B 测试名称的 trace 信息,评估微服务上运行 A/B 测试的效果。

下一步是什么?

随着 Netflix 的发展,系统的范围和复杂性不断增加。我们将专注于以下几个方面来扩展 Edgar。

  • 为收集所有运行时环境的 trace 提供良好的开发者体验。如果有简单的方法来尝试分布式跟踪,将吸引更多工程师用跟踪系统来检测他们的服务,并通过标记相关的元数据为每个请求提供额外的上下文。

  • 增强查询跟踪数据的分析能力,使公司的一些高阶用户能够针对特定的用例构建自己的仪表盘和系统。

  • 构建通用的能力,将来自指标、日志和跟踪系统的数据关联起来,为故障排除提供额外的上下文信息。

随着我们在构建分布式跟踪基础设施方面的进展,工程师继续依靠 Edgar 来解决诸如“为什么 Tiger King 在我的手机上不能播放”之类问题,我们的分布式追踪基础设施有助于确保 Netflix 用户继续享受像 Tiger King 这样的必看剧目!

英文原文:

https://netflixtechblog.com/building-netflixs-distributed-tracing-infrastructure-bb856c319304

构建 Netflix 分布式追踪(tracing)体系相关推荐

  1. 【学习笔记】分布式追踪Tracing

    在软件工程中,Tracing指使用特定的日志记录程序的执行信息,与之相近的还有两个概念,它们分别是Logging和Metrics. Logging:用于记录离散的事件,包含程序执行到某一点或某一阶段的 ...

  2. 专访 Zipkin 项目 Leader:如何用 Zipkin 做好分布式追踪?

    现代微服务架构由于业务系统模型日趋复杂,分布式系统中需要一套链路追踪系统来帮助我们理解系统行为,明确服务间调用.最近作者请到了 Zipkin 项目的主要开发维护人员 Adrian Cole 来介绍有关 ...

  3. 构建基于分布式SOA架构的统一身份认证体系

    摘要:本文充分利用SOA架构松耦合的特点,通过规范统一网络接口实现业务系统整合,既提升系统安全性,又简化资源访问操作,具有重要的理论和现实意义. 统一身份认证旨在将分散在各个信息系统中的用户和权限资源 ...

  4. 分布式追踪不是银弹 | 正确使用分布式追踪和 APM 系统

    2010-2020,十年间,应用系统的服务化和容器化程度越来越高,云原生技术也得到了更为广泛的运用,应用系统对于扩容和管理的需求逐步地提升,虽然大家也在反省微服务的拆分粒度,但是走向分布式的趋势,依然 ...

  5. Apache SkyWalking 为.NET Core带来开箱即用的分布式追踪和应用性能监控

    在大型网站系统设计中,随着分布式架构,特别是微服务架构的流行,我们将系统解耦成更小的单元,通过不断的添加新的.小的模块或者重用已经有的模块来构建复杂的系统.随着模块的不断增多,一次请求可能会涉及到十几 ...

  6. 分布式数据库 Tracing (一)— Opentracing

    Part 1 - 为什么需要 Tracing 当前微服务架构和分布式系统变得越来越流行,系统庞大且服务数量繁杂多样,甚至数据库也开始使用分布式架构.当一个生产系统面对真正的高并发,或者解耦成大量微服务 ...

  7. 让你的nginx支持分布式追踪opentracing

    Background NGINX 是一个通用且流行的应用程序.也是最流行的 Web 服务器,它可用于提供静态文件内容,但也通常与其他服务一起用作分布式系统中的组件,在其中它用作反向代理.负载均衡 或 ...

  8. MSE 微服务治理发布企业版,助力企业构建完整微服务治理体系

    作者:十眠.流士 微服务(MicroServices) 架构是一把双刃剑,随着微服务架构复杂化,在大规模之下,再小的问题都会牵一发而动全身,因此微服务架构带来的效率.稳定性问题很可能会远大于微服务本身 ...

  9. 40张图看懂分布式追踪系统原理及实践

    前言 在微服务架构中,一次请求往往涉及到多个模块,多个中间件,多台机器的相互协作才能完成.这一系列调用请求中,有些是串行的,有些是并行的,那么如何确定这个请求背后调用了哪些应用,哪些模块,哪些节点及调 ...

  10. 传递给系统调用的数据区域太小怎么解决_40张图看懂分布式追踪系统原理及实践...

    作 者:码海 原文链接:https://mp.weixin.qq.com/s/U-8ttlVCfYtjEPOWKBHONA 前言 在微服务架构中,一次请求往往涉及到多个模块,多个中间件,多台机器的相互 ...

最新文章

  1. 牛客练习赛40 A.小D的剧场
  2. [流媒体]实例解析MMS流媒体协议,下载LiveMediaVideo[4]
  3. float、double(浮点数)区别还有和decimal(定点数)的比较
  4. 二十个你必须知道的SEO概念
  5. Some about me
  6. jzoj4024-石子游戏【SG函数,博弈论】
  7. java中三个基本框架_对于Java基础者应该如何理解Java中的三大框架!
  8. 三角形描边css,[CSS] tips带有描边的小箭头
  9. Python之集合、解析式,生成器,函数
  10. 注解、垃圾回收和线程
  11. 一周愣降900元!这款iPhone不值了?
  12. window dockor mysql_windows下docker安装mysql
  13. android bitmap 获取像素点 太慢_Drawable与 Bitmap 转换总结
  14. codeforces 600A Extract Numbers
  15. 编程珠玑:位图法排序
  16. CCNA考试题库中英文翻译版及答案10
  17. 计算机安装系统后鼠标无法使用,电脑重装系统后鼠标键盘不能用怎么办
  18. SIP软电话开发的基本条件和要点
  19. index.html请连接网络,index.html
  20. GSAP教程之Tween详解

热门文章

  1. 绘制Linux/Android设备的内存动态变化趋势图
  2. MotionEstimate运动估计综述
  3. Linux Cgroups详解(一)
  4. 全国草地资源类型分布数据/植被类型分布数据/土地利用类型分布数据
  5. java线程系列一:Thread类中的start()方法与run方法
  6. python zip函数小结
  7. 交换两个数 不使用中间变量
  8. ctguoj--考新郎(排列组合+错排公式)
  9. bt php,bt.php · jiehu0992/家谱familytree - Gitee.com
  10. java内存泄露 垃圾回收_Java面试中底层垃圾回收、代码安全、内存泄露