sysdig's chisels 是内置的脚本,供使用者来追踪系统调用或者查看系统的性能瓶颈,它是用强大而且高效的脚本语言Lua写的。
今天来分享一下fdbytes_by的用法,该案例可以探测到系统的那个文件的I/O占用最高(不光是file,还可以是network I/O),而且可以查到哪个进程在读写该文件,并且可以查看到内核级的I/O活动明细。应用场景可以观察一下你的文件系统是否是在高效运转,或者调查一个磁盘I/O延迟的故障。配合dstat --top-io可以更容易定位到进程名字,但是今天介绍的主要是sysdig的fdbytes_by chisel用法,可以想象成没有dstat工具可用的场景下。
首先我们先来看一下今天的主角fdbytes_by的用法明细:
# sysdig -i fdbytes_by Category: I/O ------------- fdbytes_by I/O bytes, aggregated by an arbitrary filter field Groups FD activity based on the given filter field, and returns the key that ge nerated the most input+output bytes. For example, this script can be used to li st the processes or TCP ports that generated most traffic. Args: [string] key - The filter field used for grouping
答题意思是以文件描述符的各种活动所产生的IO大小来进行排序。
首先我们来抓取30M的sysdig包来用分析使用。
sysdig -w fdbytes_by.scap -C 30
然后我们来分析这次抓包没个文件描述符对文件系统的I/O活动:
# sysdig -r fdbytes_by.scap0 -c fdbytes_by fd.type Bytes fd.type -------------------------------------------------------------------------------- 45.16M file 9.30M ipv4 87.55KB unix 316B60B pipe
可以看到file占用的45.16M,是最大的FD,然后我们来看一下按目录的I/O活动来排序:
# sysdig -r fdbytes_by.scap0 -c fdbytes_by fd.directory Bytes fd.directory -------------------------------------------------------------------------------- 38.42M /etc 7.59M / 5.04M /var/www/html 1.38M /var/log/nginx 304.73KB /root/.zsh_history/root 7.31KB /lib/x86_64-linux-gnu 2.82KB /dev 2.76KB /dev/pts 1.62KB /usr/lib/x86_64-linux-gnu
发现访问最多的是/etc目录,那我们看一下,具体访问的是哪个文件呢?
# sysdig -r fdbytes_by.scap0 -c fdbytes_by fd.name fd.directory=/etc Bytes fd.name -------------------------------------------------------------------------------- 38.42M /etc/services
Bingo!找到了,原来是/etc/services被访问的最多,因为services是系统文件,所以可以判断肯定是read的操作达到了38.42M,那我们来看一下哪个进程访问的此文件呢?
# sysdig -r fdbytes_by.scap0 -c fdbytes_by proc.name "fd.filename=services and fd.directory=/etc" Bytes proc.name -------------------------------------------------------------------------------- 38.42M nscd
找到元凶了,原来是nscd缓存程序,那他为什么会读取这么多次的services文件呢?在继续看:
# sysdig -r fdbytes_by.scap0 -A -s 4096 -c echo_fds proc.name=nscd ------ Read 12B from ffff880009dc6900->ffff880009dc6180 /var/run/nscd/socket (nscd) ------ Read 6B from ffff880009dc6900->ffff880009dc6180 /var/run/nscd/socket (nscd) hosts ------ Write 14B to ffff880009dc6900->ffff880009dc6180 /var/run/nscd/socket (nscd) hostsO ------ Read 12B from ffff880009dc6900->ffff880009dc6180 /var/run/nscd/socket (nscd) ------ Read 7B from ffff880009dc6900->ffff880009dc6180 /var/run/nscd/socket (nscd) 28060/ ------ Read 4.00KB from /etc/services (nscd) # Network services, Internet style # # Note that it is presently the policy of I ------ Read 4.00KB from /etc/services (nscd) # IPX ipx213/udp imap3220/tcp# Interactive Mail Access imap3220/udp ------ Read 4.00KB from /etc/services (nscd) nessus1241/tcp# Nessus vulnerability nessus1241/udp# assessment scann ------ Read 4.00KB from /etc/services (nscd) qmaster6444/tcpsge_qmaster# Grid Engine Qmaster Service sge-qmaster6444/udp ------ Read 3.10KB from /etc/services (nscd)
原来是nscd在读取services中定义的端口跟服务名称之间的关系,我在抓包的过程中是运行了ab做nginx的静态页面压力测试,本来希望看到的是nginx的读写会很高,没想到中途出现了这个nscd来捣乱:
ab -k -c 2000 -n 300000 http://shanker.heyoa.com/index.html
# sysdig -r fdbytes_by.scap0 -c topprocs_file Bytes Process PID -------------------------------------------------------------------------------- 38.42M nscd 1343 6.43M nginx 4804 304.89KB zsh 32402 9.20KB ab 20774 2.79KB screen 18338 2.37KB sshd 12812
后来我分别测试了一下开启nscd的情况下ab的测试时间,和不开nscd做缓存的情况下,确实开启nscd做本地services的缓存会提高10.189%。
ab -k -c 2000 -n 300000 http://shanker.heyoa.com/index.html 0.94s user 2.77s system 9% cpu 38.561 total ab -k -c 2000 -n 300000 http://shanker.heyoa.com/index.html 0.93s user 2.79s system 10% cpu 34.632 total
nscd缓存加速可以参考之前的这篇文章
http://shanker.blog.51cto.com/1189689/1735058
至此,整个分析就结束了,本文只是一个例子,跟大家分享如何使用chisel的fdbytes_by,sysdig还提供了很多chisel共大家分析系统。
欢迎补充!