前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >eBCC性能分析最佳实践(1) - 线上lstat, vfs_fstatat 开销高情景分析

eBCC性能分析最佳实践(1) - 线上lstat, vfs_fstatat 开销高情景分析

作者头像
Linux阅码场
发布2019-06-05 15:41:43
9730
发布2019-06-05 15:41:43
举报
文章被收录于专栏:LINUX阅码场LINUX阅码场

Guide:

  • eBCC性能分析最佳实践(0) - 开启性能分析新篇章
  • eBCC性能分析最佳实践(1) - 线上lstat, vfs_fstatat 开销高情景分析
  • eBCC性能分析最佳实践(2) - 一个简单的eBCC分析网络函数的latency
  • 敬请期待…

0. Intro

BCC是基于4.x kernel版本上的ebpf发展出来的一套性能分析工具集;

eBCC,顾名思义则是extended BCC的缩写,是阿里巴巴内核团队在Aliyun Linux 2 上对BCC项目的拓展,包含BCC本身已有的工具集,和我们新开发的一些小的工具;eBCC则是基于在最新的BCC版本0.9之上做了一些拓展。

Aliyun Linux则使用了相对比较前沿,较新的kernel版本,支持ebpf特性,所以,如果想尝试ebpf,eBCC带来的系统上对“性能优化调试” 和 “问题诊断”上的新体验,那就请赶快升级到 Aliyun Linux 2 上吧。

1. eBCC 分析 "A业务线" 线上机器cpu sys - lstat开销大

对于kernel团队的同学来说,排查问题,和性能数据分析的时候,通常情况下会先从宏观的脚本去分析整机各个子系统:SCHED,MEM,IO,NET的性能是否存在bottleneck。然后再通过各种专业的工具来剖析对应的子系统。

当我们遇到cpu sys很高的情况的时候,根据我们的经验,比较常见的可能原因为:

  1. 可能是某个kernel thread在疯狂
  2. 可能是某个syscall被用户层频繁调用,或者是某个syscall的链路上出现很大的latency

第一种情况可能比较好发现问题,针对第二种情况,比较麻烦,难以发现。

于是我们开发了eBCC工具集,来帮助用户定位问题。

下面让我们开始寻找一个线上机器, 看是否存在性能瓶颈吧….

  • 业务方: A业务
  • 诊断物理机: xxxxx
  • 内核版本: 4.19
  • 诊断工具: eBCC

1.1 SYS级别诊断 - 发现问题

如下图所示,是目标机器top10开销较大的syscall。其中TIME, MIN, MAX的时间单位都是ns

注意,这里我们的工具实际上采集了4个数据,次数,时间,最小时间,最大时间。

实际上,只有这四个数据都存在的时候,我们才能很快的分析出这里是否存在问题,是否正常。如果我们仅仅知道COUNT,不知道时间,这是不能说明问题的。

因为次数多,不一定代表开销大。开销大,不一定代表次数多。

实际上select,poll这些操作所占用的时间开销是属于正常的的,但是,看到lstat系统调用时间开销多达338769324ns(338ms), 就是不正常的现象了!因此,这可能就是一个可以优化的地方…

进一步分析lstat的MIN TIME, MAX TIME看上去都不大,因此可以确定这个syscall链路上并没有出现latency很大的问题,但是COUNT多达124724次,这也许才是开销很大的关键。。。

换几台线上机器,发现都存在lstat开销比较大的问题…

image

因此我们需要进一步排查哪个pid导致?

1.2 PID级别诊断 - 定位问题

  • eBCC的syscall性能分析模块,支持SYS级别和PID级别的数据采集, 我们一般应该先从SYS级别入手,发现问题的方向之后,再通过PID级别找到触发问题的元凶。
  • 第1列:pid, 第2列:syscall NR , 第3列:syscall name, 第4列 是调用次数, 第5列 是调用时间开销,单位ns, 第6列:min time (ns), 第7列:max time(ns)image

1.3 找到元凶:PID:91885

1.4 Code分析

代码语言:javascript
复制
 1tools/perf/builtin-trace.c:     { .name     = "lstat",      .errmsg = true, .alias = "newlstat", },
 2
 3SYSCALL_DEFINE2(newlstat, const char __user *, filename,
 4        struct stat __user *, statbuf)
 5{
 6    struct kstat stat;
 7    int error;
 8
 9    error = vfs_lstat(filename, &stat);
10    if (error)
11        return error;
12
13    return cp_new_stat(&stat, statbuf);
14}
15
16int vfs_lstat(const char __user *name, struct kstat *stat)
17{
18    return vfs_fstatat(AT_FDCWD, name, stat, AT_SYMLINK_NOFOLLOW);
19}
20EXPORT_SYMBOL(vfs_lstat);

1.5 perf辅助证明

通过perf来帮助证明eBCC的数据采集是否精确。

代码语言:javascript
复制
1[root@xxx /root]
2#perf stat -e syscalls:sys_enter_newlstat  -a sleep 4
3
4 Performance counter stats for 'system wide':
5
6            449931      syscalls:sys_enter_newlstat
7
8       4.000941076 seconds time elapsed

基本可以说明,lstat的触发次数确实很大。

1.6 syscall次数统计

代码语言:javascript
复制
 1[root@xxx /root]
 2#ebcc syscount
 3Tracing syscalls, printing top 10... Ctrl+C to quit.
 4
 5^C[14:58:52]
 6SYSCALL                   COUNT
 7close                   1173795
 8lstat                   1052795
 9futex                    667981
10read                     325349
11getdents64               257280
12epoll_wait               255386
13epoll_ctl                250355
14write                    144328
15openat                   115240
16open                     111810

eBCC另外一个工具syscount 同样可以采集出次数。

1.7 vfs层证明

lstat 系统调用同样会反应到vfs的触发次数:vfs_fstatat

代码语言:javascript
复制
 1[root@xxx /root]
 2#ebcc vfscount
 3Tracing... Ctrl-C to end.
 4
 5^C
 6ADDR             FUNC                          COUNT
 7ffffffff8124f8b1 vfs_symlink                       1
 8ffffffff8124f711 vfs_create                       11
 9ffffffff812426e1 vfs_readv                        22
10ffffffff8124fbd1 vfs_unlink                       27
11ffffffff81277c31 vfs_fsync_range                  98
12ffffffff812790d1 vfs_statfs                     1126
13ffffffff81269d51 vfs_getxattr                   1248
14ffffffff812428f1 vfs_writev                     1749
15ffffffff81250b01 vfs_rename                     2353
16ffffffff8129bb51 vfs_lock_file                  6167
17ffffffff8124d031 vfs_get_link                  21829
18ffffffff812476b1 vfs_fstat                     50744
19ffffffff81242301 vfs_write                    151061
20ffffffff81240891 vfs_open                     181734
21ffffffff812421d1 vfs_read                     336899
22ffffffff81247711 vfs_fstatat                 1055146    --- tigger counts
23ffffffff81247681 vfs_getattr                 1109493
24ffffffff81247401 vfs_getattr_nosec           1130229

1.8 核心分析:开销来自于 “用户调用次数” 还是 “内核里vfs_fstatat 函数本身的latency” ?

Answer:

如下图所示,基本都在2-3个us就完成了。基本上可以说,latency不是很大,基本符合disk,nvme本身的latency,因此,开销主要来自counts,因此,优化调用次数,比 优化 这个内核函数本身的latency要有意义。

image

1.9 根本原因

通过eBCC中的工具追踪,发现logagent疯狂的使用vfs_fstatat,遍历A业务/home/admin/XXXX/worker/slave/disk_links/9999/ 目录下的文件, 至此,我们基本就把问题分析清楚了。

代码语言:javascript
复制
 1[root@xxx /home]
 2#/usr/share/ebcc/tools/trace -p 91885 'vfs_fstatat "%s", arg2'
 391885   121566  logagent        vfs_fstatat      /home/admin/XXXX/worker/slave/disk_links/9999/auto_umars_YYYY_4_YYYY.TPP_mc
 491885   121566  logagent        vfs_fstatat      /home/admin/XXXX/worker/slave/disk_links/9999/auto_umars_YYYY_4_YYYY.TPP_mc
 591885   121566  logagent        vfs_fstatat      /home/admin/XXXX/worker/slave/disk_links/9999/auto_umars_YYYY_4_YYYY.TPP_mc
 691885   121566  logagent        vfs_fstatat      /home/admin/XXXX/worker/slave/disk_links/9999/auto_umars_YYYY_4_YYYY.TPP_mc
 791885   121566  logagent        vfs_fstatat      /home/admin/XXXX/worker/slave/disk_links/9999/auto_umars_YYYY_4_YYYY.TPP_mc
 891885   121566  logagent        vfs_fstatat      /home/admin/XXXX/worker/slave/disk_links/9999/auto_umars_YYYY_4_YYYY.TPP_mc
 991885   121566  logagent        vfs_fstatat      /home/admin/XXXX/worker/slave/disk_links/9999/auto_umars_YYYY_4_YYYY.TPP_mc
1091885   121566  logagent        vfs_fstatat      /home/admin/XXXX/worker/slave/disk_links/9999/auto_umars_YYYY_4_YYYY.TPP_mc
1191885   121566  logagent        vfs_fstatat      /home/admin/XXXX/worker/slave/disk_links/9999/auto_umars_YYYY_4_YYYY.TPP_mc
1291885   121566  logagent        vfs_fstatat      /home/admin/XXXX/worker/slave/disk_links/9999/auto_umars_YYYY_4_YYYY.TPP_mc
1391885   121566  logagent        vfs_fstatat      /home/admin/XXXX/worker/slave/disk_links/9999/auto_umars_YYYY_4_YYYY.TPP_mc
1491885   121566  logagent        vfs_fstatat      /home/admin/XXXX/worker/slave/disk_links/9999/auto_umars_YYYY_4_YYYY.TPP_mc
1591885   121566  logagent        vfs_fstatat      /home/admin/XXXX/worker/slave/disk_links/9999/auto_umars_YYYY_4_YYYY.TPP_mc
1691885   121566  logagent        vfs_fstatat      /home/admin/XXXX/worker/slave/disk_links/9999/auto_umars_YYYY_4_YYYY.TPP_mc
1791885   121566  logagent        vfs_fstatat      /home/admin/XXXX/worker/slave/disk_links/9999/auto_umars_YYYY_4_YYYY.TPP_mc
1891885   121566  logagent        vfs_fstatat      /home/admin/XXXX/worker/slave/disk_links/9999/auto_umars_YYYY_4_YYYY.TPP_mc
1991885   121566  logagent        vfs_fstatat      /home/admin/XXXX/worker/slave/disk_links/9999/auto_umars_YYYY_4_YYYY.TPP_mc
2091885   121566  logagent        vfs_fstatat      /home/admin/XXXX/worker/slave/disk_links/9999/auto_umars_YYYY_4_YYYY.TPP_mc
2191885   121566  logagent        vfs_fstatat      /home/admin/XXXX/worker/slave/disk_links/9999/auto_umars_YYYY_4_YYYY.TPP_mc
2291885   121566  logagent        vfs_fstatat      /home/admin/XXXX/worker/slave/disk_links/9999/auto_umars_YYYY_4_YYYY.TPP_mc
2391885   121566  logagent        vfs_fstatat      /home/admin/XXXX/worker/slave/disk_links/9999/auto_umars_YYYY_4_YYYY.TPP_mc
2491885   121566  logagent        vfs_fstatat      /home/admin/XXXX/worker/slave/disk_links/9999/auto_umars_YYYY_4_YYYY.TPP_mc
2591885   121566  logagent        vfs_fstatat      /home/admin/XXXX/worker/slave/disk_links/9999/auto_umars_YYYY_4_YYYY.TPP_mc
2691885   121566  logagent        vfs_fstatat      /home/admin/XXXX/worker/slave/disk_links/9999/auto_umars_YYYY_4_YYYY.TPP_mc
2791885   121566  logagent        vfs_fstatat      /home/admin/XXXX/worker/slave/disk_links/9999/auto_umars_YYYY_4_YYYY.TPP_mc
2891885   121566  logagent        vfs_fstatat      /home/admin/XXXX/worker/slave/disk_links/9999/auto_umars_YYYY_4_YYYY.TPP_mc

2. Conclution

image

  • logagent在这个机器上有大量的lstat操作,平均每秒:11w次;整机open次数,平均每秒:12w次。
  • 整机看vfs_fstatat 本身的latency,基本都在2-3us内完成, 没有太大的内核态似乎没有太大latency可以优化,因此,用户态的程序 优化 也许有更好的 效果。
  • logagent在机器运行1s内,大概开销占用总cpu的:338ms;现在整机96core,那么就相当于有96s, 如果整机cpu sys占用:3%, 机器运行1s内,内核sys大概占用了3.456s,那么如果优化掉这338ms,cpu sys利用率会降低9.7%=(338ms/3.456s)。
  • 查看“A业务线”多个机器,发现是个通用现象。
本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2019-05-05,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 Linux阅码场 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 0. Intro
  • 1. eBCC 分析 "A业务线" 线上机器cpu sys - lstat开销大
    • 1.1 SYS级别诊断 - 发现问题
      • 1.2 PID级别诊断 - 定位问题
        • 1.3 找到元凶:PID:91885
          • 1.4 Code分析
            • 1.5 perf辅助证明
              • 1.6 syscall次数统计
                • 1.7 vfs层证明
                  • 1.8 核心分析:开销来自于 “用户调用次数” 还是 “内核里vfs_fstatat 函数本身的latency” ?
                    • 1.9 根本原因
                    • 2. Conclution
                    • image
                    领券
                    问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档