AWS Community Day Hong Kong 2025 Recap

利用另一类遥测数据,借助 AI 智能体更快改进——Yoshi Yamaguchi

Recap Series

性能剖析简介

  • 性能分析器的定义:性能分析器是一种遥测工具,可以提供系统运行性能以及系统资源消耗情况的信息。
  • 性能剖析的目的:性能剖析有助于调查程序的资源消耗,并提供一段时间内特定资源使用情况的统计信息。
  • 与追踪的区别:追踪以时间序列方式记录资源消耗,而性能剖析提供特定时间段内的统计信息。
  • 常用的性能剖析工具:
  • Java:Java Flight Recorder(JFR)
  • Python:cProfile(标准库)和 line_profiler(第三方工具)
  • Linux:适用于任意可执行文件的 perf 命令

性能剖析在性能问题调查中的重要性

  • 练习场景:假设一个 Web 应用出现延迟问题,客户端向 Web 服务器发出的请求响应缓慢。
  • 目标:找出性能问题的原因并加以修复。
  • 可观测性:可观测性通常与日志、指标和追踪相关,而性能剖析能够提供解决性能问题可能需要的额外洞察。

日志、指标和分布式追踪的局限性

  • [ 1 ] 指标:
  • 定义:指标是最常见的遥测数据类型,可以提供 CPU 使用率、内存使用率等信息。
  • 局限性:指标追踪的是实例或服务的整体资源消耗(例如运行 Web 服务器的容器),无法说明应用程序中究竟是哪个具体函数或实现消耗了资源。例如,指标可以显示 Web 服务器占用了大量 CPU,却无法确定是哪个函数导致 CPU 使用率过高。
  • [ 2 ] 分布式追踪:
  • 定义:分布式追踪可以提供有关系统内部延迟问题的重要信息。
  • 局限性:常见的分布式追踪方案需要对系统或程序进行插桩。如果某个函数未插桩,就无法获得该函数的延迟信息。为每个函数插桩不仅耗时,还可能引入性能问题。
  • [ 3 ] 日志:
  • 定义:日志提供特定函数在特定时间执行特定操作的信息。
  • 局限性:日志只会显示处理成功或错误消息。如果函数正确处理了请求,日志只会显示成功消息,不会指出任何延迟问题。除非发生错误,否则日志无法提供延迟问题成因的信息。

结论

  • 问题:日志、指标和分布式追踪虽然有用,却无法完整说明延迟问题的原因。要深入了解资源消耗并识别性能瓶颈,就必须进行性能剖析。

当前状态与理想状态总结

  • [ 1 ] 目标:
  • 使用可观测性的目标是找出性能问题的原因并加以修复。
  • [ 2 ] 当前状态:
  • 遥测数据缺口:系统存在延迟问题,CPU 或内存使用量出现激增,分布式追踪显示延迟发生变化,而日志又显示函数正常处理了请求,但仍然无法确定延迟问题的确切原因。
  • [ 3 ] 理想状态:
  • 精确定位:理想状态是能够找出导致性能问题的确切代码行,从而进行精准修复。

可观测性的定义

  • 控制理论中的可观测性:可观测性用于衡量能在多大程度上根据系统的外部输出(遥测数据)推断其内部状态。
  • 理想的可观测性:可观测性的理想状态是仅通过遥测数据就能确定问题的确切原因。

性能剖析的作用

  • 填补缺口:性能剖析能够填补日志、指标和追踪无法覆盖的信息缺口。
  • 最后一公里信息:要从日志、指标和追踪提供的数据进一步找到性能问题的确切原因,性能剖析可以提供最后一块关键信息。

性能剖析的传统用法

  • 插桩:要使用性能剖析,需要对程序进行插桩以收集遥测数据。
  • 分析:分析收集到的遥测数据,找出并修复性能问题。

为程序插桩以进行性能剖析

Go

  • 标准包:使用 Go 自带的 pprof 包。
  • 步骤:
  • 导入 pprof 包。
  • 创建性能分析器实例。
  • 启动性能分析器。
  • 定义停止性能剖析测量的位置。

Python

  • 逐行性能分析器:使用 line_profiler 包。
  • 步骤:
  • 导入 line_profiler 包。
  • 启用性能分析器。
  • 编写需要进行性能剖析的具体处理逻辑。
  • 禁用性能分析器。

面向常驻系统的持续性能剖析

  • [ 1 ] 区别:
  • 单次性能分析器:测量单次运行所需的时间(启动和停止计时器)。
  • 持续性能分析器:按设定间隔定期采集性能剖析数据(例如每 10 秒采集一次,持续 5 分钟),并将其存储到外部(例如 Amazon S3)。
  • [ 2 ] 使用场景:
  • 非常适合守护进程或 Web 服务器等常驻系统,尤其适用于流量激增期间。
  • [ 3 ] 解决方案:
  • AWS:使用 Amazon CodeGuru,或将 Amazon Managed Grafana 与 Pyroscope 结合使用。
  • 开源方案:Pyroscope,现已成为 Grafana 解决方案的一部分。

性能剖析数据分析

  • 截图示例:安装了 Pyroscope 插件的 Amazon Managed Grafana,展示每个调用栈的资源使用统计。
  • 下一步:数据收集完成后,进入分析阶段,找出并修复性能问题。

使用火焰图可视化性能剖析数据

  • 火焰图:一种广为人知的性能剖析数据可视化方式。
  • 挑战:要读懂火焰图,需要了解源代码、可视化图形的含义以及计算机科学基础概念。

解读火焰图

  • [ 1 ] 示例图:
  • 将整个程序调用栈的 CPU 使用情况可视化。
  • [ 2 ] 解读:
  • 长条:表示资源消耗较高。
  • sys.call.read:执行读取操作的系统调用,消耗了大量 CPU。
  • os.file.read:用于读取物理文件的 Go 标准库函数,通常实现良好且性能出色。
  • [ 3 ] 结论:问题可能出在自定义函数(模拟 GNU Cut 命令的 Cut 函数)调用 os.file.read 的方式效率低下。

函数实现示例

  • cut 函数:模拟 GNU Cut 命令行为的函数。
  • 下一步:检查 Cut 函数的实现,找出其调用 os.file.read 时可能存在的低效之处。

演示

文件读取效率低下

  • 已发现的问题:程序逐字节读取文件,效率很低,因为每读取一个字节都会触发一次系统调用。
  • 知识要求:要理解这种方式效率低下的原因,需要掌握用户空间、内核空间以及计算机科学原理方面的知识。

AI 助手在性能剖析中的作用

  • AI 辅助:AI 助手,尤其是大语言模型(LLM),可以帮助解读性能剖析数据。
  • 更适合运维:与开发相比,LLM 更适合运维工作,因为运维的输出规模较小、确定性更高(例如识别问题),并且拥有丰富的上下文(系统规格、遥测数据和日志)。
  • 开发与运维:开发工作需要生成大量源代码,输出具有不确定性,因此不太适合 LLM。

利用 AI 助手分析性能剖析数据

  • 演示:一名 AWS 员工使用 AI 助手分析性能剖析数据和源代码,以找出性能问题。
  • 流程:
  • [ 1 ] 请 AI 助手分析性能剖析数据和源代码。
  • [ 2 ] 助手判断需要使用工具将性能剖析数据可视化。
  • [ 3 ] 获得批准后,助手将各函数的 CPU 使用情况可视化,并确定导致问题的具体函数。
  • [ 4 ] 助手提供逐行的 CPU 使用情况,并给出改进建议。

总结

  • 性能剖析数据:将性能问题与实际代码改进联系起来的关键。
  • 传统分析:需要深厚的系统和计算机科学知识。
  • AI 辅助:利用性能剖析数据帮助用户了解其使用方法,并加快开发进程。