SysAK 应用抖动诊断篇—— eBPF又立功了! | 龙蜥技术
简介:且看 SysAK 是如何打造一款性能开销不大、安全可靠、且灵活的关中断检测工具。
文 / 系统运维 SIG
编者按:还记得曾经风靡一时的狄仁杰探案系列之《他抖任他抖,IO诊断在我手》、《netinfo:揭开网络抖动面纱的神器》、《coredump 瘦身风云》等带大家领略了青囊在网络、IO、内存等领域叱咤风云的魅力。如今,系统运维 SIG 组重磅归来,前面已介绍了 Kernel module 对付 IO 夯,今天继续分享 eBPF 硬扛系统中断,快随我一起来看看 SysAK 是如何打造一款性能开销不大、安全可靠、且灵活的关中断检测工具。
一、背景
日常业务运行时会经常受到各种各样的干扰而产生抖动、影响客户体验。其中的一种干扰源是关中断,当关中断过久时可能会导致业务进程调度不及时、数据收发延迟等,这种干扰已经伴随 Linux 内核存在很长时间了,因而 Linux 内核包括业界也有不少相关的关中断检测手段。这里列举几个比较典型方案:
1、内核最大关中断检查
内核自身在系统中所有的关/开中断路径中添加了 TRACE_IRQ_OFF 的 trace 点,以对系统中所有开/关中断进行监控。
优点:关中断检测精确且全面,同时课观测到关中断的时间、甚至堆栈。
缺点:依赖于 CONFIG_IRQSOFF_TRACER 内核配置,该配置在不少发行版不支持。插桩点太多而且是热路径,对性能影响较大。
2、watchdog/hardlock detecter
内核注册一个 PMU 硬件 event 定期检查自己注册的 watchdog hrtimer 中断是否有及时更新时间戳。
优点:周期性的检测,对性能影响小,适用于系统中关中断或者中断处理有 BUG 的情况。
缺点:监控的粒度太大,无法提供更细粒度级别的系统观察指标。对于一些无 PMU 硬件 event 的虚拟化环境该方案不生效。
3、trace_irq_handler_exit/trace_irq_handler_exit && irq_enter/irq_exit
在所有中断处理函数的入口/出口安插 trace 以及时间记录。
优点:提供所有中断处理时长的原始数据。
缺点:只能够观察到中断处理的时间情况,对于其他关中断路径无法监控,没有 threshold 触发机制,需要人工事后分析。
4、其他开源检查工具
在 Github 上也有不少相关的关中断检查工具,它们以 .ko 模块方式提供,利用 hrtimer 定时器检查到期时间是否超过预期时间。
优点:周期采样系统开销不大,提供了毫秒级的监控粒度。
缺点:以第三方模块方式提供,稳定性无法保障。hrtimer 作为普通中断,需要等到关中断恢复后才能检测到,精确度无法保障。同时,对于中断函数延迟的情况会丢失掉前一个中断的信息。
上面的各个检测机制各有千秋,也有各自的缺陷和不满足的场景。且看 SysAK 是如何打造一款性能开销不大、安全可靠、且灵活的关中断检测工具。
二、技术选择
上面的工具选用的技术、实现手段和检测逻辑不同,导致了在不同场景中有着不同的场景中有着不同的优劣。而对于生产环境而言,监控工具的稳定性和工具的开销是比较重要的考虑因素。因而在内核热路径使用插桩以及使用内核模块的方式都不是太理想的选择:前者可能在某些场景下对性能产生较大影响,后者对于内核模块的编码安全性要求非常高,稍不注意容易引发系统宕机,对于批量部署的生产环境风险太大。
面对上面两个问题有没有方案或者技术手段能够解决呢?当然有。
针对内核模块的安全问题,eBPF 绝对是 Linux 业界当前最好的解决方案,不仅安全而且还提供了大量易用的库来提升编程体验。
而热路径插桩的性能问题,在关中断时间过长这个场景中,使用定时采样、检查的方式即可解决,而采样当首选的还是 perf 事件采样。
三、方案设计
针对前面的背景和应用场景分析初步完成了技术选型,此时关中断检测工具大致原理也基本有了原型:
如果系统支持 perf 硬件采样(HW)事件,首先使用 eBPF 启动一个内核定时器,定时器周期性产生中断并在中断处理函数中定时更新一个标志,然后 perf HW 事件再周期检查该标志是否按时更新,以此来判断时钟中断是否有按时产生或者延时发生的情况。
对于不支持 perf HW 的系统,我们无法利用 perf HW 事件了。退而求其次,我们同样通过 eBPF 需要启动内核定时器,定时器中断函数会检查本次定时器中断到期时间与预期时间是否有差异,以此来判断中断是否有延迟的情况。
四、技术实现
实际上要实现上面的功能,需要解决如下几个问题:
1) eBPF 如何安装定时器?
2) 如何把 perf 事件触发后我们的检查逻辑挂接到 perf 事件回调处理中?
3) 如何根据系统对于 perf 硬件采样事件的支持与否让 eBPF 选择不同的检查机制?
1、eBPF 安装定时器
在前面设计分析中,我们了解到要使用 eBPF 启动内核定时器来做一个中断样本。不过很不巧,eBPF 在 Linux-5.15 以下的内核版本不支持定时器创建。幸好条条道路通罗马,perf SW 事件中的 PERF_COUNT_SW_CPU_CLOCK 的事件其在 Linux 内核的底层就是通过高精度时钟实现的。因此只要巧妙的利用利用了这个原理,然后结合 eBPF 就能实现我们需要的 eBPF 定时器。
2、eBPF prog 处理函数关联到 perf HW/SW 事件 overflow 回调函数
虽然 perf 在用户态提供来 perf_event_open 系统调用和 ioctl 方式来创建 perf HW 和 perf SW 事件采样(如前面 PERF_COUNT_SW_CPU_CLOCK 事件,以及 perf 硬件事件 PERF_COUNT_HW_CPU_CYCLES,通过 man perf_event_open 查看更详细的信息),但是传统的用户态 perf 使用中并不能在这些事件触发后在内核去实施我们想要的 hack 动作,例如执行我们需要进行关中断检测的回调函数,只能够在内核代码或者内核模块中调用 perf_event_create_kernel_counter 函数注册我们需要的回调函数到 perf 事件的 overflow_handler 上达成我们的目的。
然而这个窘境随着 eBPF 的出现带来了变化。Perf event 为 ebpf 提供了专门的 ioctl 通道,以便为 ebpf 在内核中施展它的超能力(别忘了 eBPF 代码本质上还是在内核执行)。而 eBPF 与用户态又有着天然的"亲和力",这样用户态就可以非常方便的通过 ioctl 往 perf 事件挂接自己的回调处理逻辑。在代码层面上就是利用:
ioctl(PERF_EVENT_IOC_SET_BPF)
来将 eBPF prog 处理函数注册到 perf event 的 overflow_handler 回调处理中。
3、针对系统是否支持 perf HW 事件选择不同的检查策略
通过 perf_event_open 系统调用的返回值判断系统是否支持 perf HW 事件。
同时在 eBPF 中定义两组 prog,如果支持 perf HW 则 attach HW 事件检测的 prog,否则 attach SW 事件检测的 prog。
五、运行流程
本章主要对工具的实现做一个详细的分解。下图是工具运行的一个简单原理图:
整个流程如下:
1.首先进行参数解析,包括阈值、运行时间、日志记录文件指定等等参数对解析。
2.进行 eBPF 初始化,这一步主要是加载 eBPF 程序。
3.安装 eBPF 事件。首先创建 perf event,接着将 ebpf prog attach 关联到 perf event,最后创建一个poll event,并监听。于此同时 perf event 开始工作,perf event 触发后将调用 eBPF prog 程序运行。eBPF prog 程序检测到阈值事件后唤醒用户态到 poll 任务。
4.用户态 poll 被唤醒后将结果写到日志文件。
六、工具使用
安装 SysAK 后,使用如下命令:
sysak irqoff [--help] [-t THRESH(ms)] [-f LOGFILE] [duration(s)]
-t:关中断的门限值,单位是 ms。
-f:指定 irqoff 结果记录的文件。
duration:工具的运行时长,如果不指定默认会一直运行。
通过内核模块创建 worker 来构造了一个长时关中断的场景,下面是通过 irqoff 抓取的结果展示。
TIME(irqoff) CPU COMM TID LAT(us)
2022-05-05_11:45:19 3 kworker/3:0 379531 1000539
<0xffffffffc04e2072> owner_func
<0xffffffff890b1c5b> process_one_work
<0xffffffff890b1eb9> worker_thread
<0xffffffff890b7818> kthread
<0xffffffff89a001ff> ret_from_fork
结果中有若干部分组成:
第一行是 log header。总共 5 列,从左到右依次是 时间戳(模块信息) 、关中断长的 CPU、关中断长的 current 线程 ID、总的关中断延时。
第二行对应 log header 的实际信息。
第三行及后面是抓取到关中断的现场堆栈信息,方便进行下一步对源码进行分析。
本文为阿里云原创内容,未经允许不得转载。
SysAK 应用抖动诊断篇—— eBPF又立功了! | 龙蜥技术的更多相关文章
- http://stblog.baidu-tech.com/?p=1684) coredump调试记录 - PHP篇 原创: 扶墙 贝壳产品技术 今天
http://stblog.baidu-tech.com/?p=1684) coredump调试记录 - PHP篇 原创: 扶墙 贝壳产品技术 今天
- 【SSM之旅】Spring+SpringMVC+MyBatis+Bootstrap整合基础篇(一)项目简介及技术选型相关介绍
试水 一直想去搭建个自己的个人博客,苦于自己的技术有限,然后也个人也比较懒散.想动而不能动,想动而懒得动,就这么一直拖到了现在.总觉得应该把这几年来的所学总结一番,这样才能有所成长. 不知在何时,那就 ...
- Spring+SpringMVC+MyBatis+easyUI整合基础篇(一)项目简述及技术选型介绍
作者:13GitHub:https://github.com/ZHENFENG13版权声明:本文为原创文章,未经允许不得转载. 萌芽阶段 很久之前就开始打算整理一下自己的技术博客了,由于各种原因(借口 ...
- [APM] 解读2016之APM国内篇:快速增长的APM市场和技术
前言 2016年是APM技术和市场快速发展的一年,在这一年里APM市场特别是国内的市场取得了极大的增长,用户对APM价值的认识和接受度也有了很大的提升,国内市场已基本完成了用户教育和市场培养的阶段.与 ...
- 了解 MongoDB 看这一篇就够了【华为云技术分享】
版权声明:本文为博主原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明. 本文链接:https://blog.csdn.net/devcloud/article/detai ...
- 黑客攻防技术宝典Web实战篇(一)Web应用程序技术基础
在开展Web应用程序渗透测试之前请先了解下面列出的这些内容,如果不是很懂的话,请读David Gourley & Brian Totty的HTTP权威指南也叫HTTP:The Definiti ...
- Redis学习篇(十二)之管道技术
通过管道技术降低往返时延 当后一条命令不依赖于前一条命令的返回结果时,可以使用管道技术将多条命令一起 发送给redis服务器,服务器执行结束之后,一起返回结果,降低了通信频度.
- 两篇好文 清晰地描述bug 技术总监的忠告
如何清晰的描述一个bug 一个技术总监的忠告 --2020-02-26--
- QoS专题-第1期-QoS理论篇
QoS理论篇 1 QoS的产生 随着网络技术的飞速发展,IP网络已经从当初的单一数据网络向集成数据.语音.视频.游戏的多业务网络转变.网络中所承载的数据呈几何级倍数增长,而且这些业务对网络带 ...
- 解密国内BAT等大厂前端技术体系-阿里篇(长文建议收藏)
进入2019年,大前端技术生态似乎进入到了一个相对稳定的环境,React在2013年发布至今已经6年时间了,Vue 1.0在2015年发布,至今也有4年时间了. 整个业界在前端框架不断迭代中,也寻找到 ...
随机推荐
- 大年学习linux(第四节---文件权限)
四.文件权限 文件类型 Linux文件类型和linux文件的文件名所代表的意义是两个不同的概念.我们通过一般应用程序而创建的比如 file.txt.file.tar.gz ,这些文件虽然要用不同的程序 ...
- django项目(博客二)
扩展1:admin路由分发的本质 路由分发本质 include 可以无限制的 嵌套N多层 url(r'^index/',([],None,None)) 扩展2: 由于url方法第一个参数是正则表达式, ...
- eviacam在Arch/Manjaro Linux下的安装
安装base-devel 安装编译工具,默认的依赖里没有编译工具 sudo yay -S base-devel 如果安装编译工具,会报类似下面的错误: 安装eviacam yay -S eviacam ...
- LOTO示波器实测过压保护芯片LP5300工作效果
过压保护电路是电子产品设置中经常要用到的,以前都是用分立元件搭的各种经典电路,最近LOTO虚拟示波器客户推荐了一款很便宜的集成的过压保护芯片LP5300,体积很小,使用简单,外接两个电容就可以了, ...
- FPGA原语初步试验
FPGA原语初步实验 1.实验原理 将FPGA的原语基本语法加入到实际的工程中,可以通过实验具体得到相应的数字电路.这里先从与.或.非门开始,准备将数字电路的设计思路引入verilog细节设计. 2. ...
- 基于SCCB协议的FPGA实现
SCCB协议 1.协议内容 SCCB协议常用于vo系列的摄像头的寄存器配置中,是有IIC协议演变而来.本来,本人接触这个协议也是想配置摄像头用于摄像模块.但是,由于配置寄存器实在是太多,而且需要找的资 ...
- scala入门输出hello world!
官网下载scala 2.12.11 版zip包,解压到自定义目录并配置环境变量.
- Python爬虫爬取ECVA论文标题作者摘要关键字等信息并存储到mysql数据库
网站截图: 源代码: 1 import re 2 import requests 3 import pymysql 4 from bs4 import BeautifulSoup 5 import l ...
- 机器语言编写helloworld
kvmtool下载编译 git clone https://github.com/kvmtool/kvmtool.git 下载后进入到目录执行make即可. 补码 计算机怎么表示负数?以四位有符号数为 ...
- ET介绍——强大的基于.dotnet7+Unity3d的双端C#开源游戏框架
ET是一个开源的游戏客户端(基于unity3d)服务端双端框架,服务端是使用C# .net core开发的分布式游戏服务端,其特点是开发效率高,性能强,双端共享逻辑代码,客户端服务端热更机制完善,同时 ...