在Linux中是否可以查看来自用户空间的多少读写请求最终导致块设备的缓存命中和未命中?
在Linux中是否可以查看来自用户空间的多少读写请求最终导致块设备的缓存命中和未命中?
Answers:
您可以开发自己的SystemTap脚本。您需要考虑以下两个子系统:
SystemTap开发需要一些时间来学习。如果您是中级开发人员并且对Linux有很好的了解,则应在3-4天之内完成。是的,它需要花费一些时间来学习,但是您会对结果感到非常满意-SystemTap使您有机会(安全地)将探针放置在Linux内核的几乎任何位置。
请注意,您的内核必须支持加载和卸载内核模块。如今,大多数库存内核都支持此功能。您还需要为内核安装调试符号。对于我的Ubuntu系统,这就像下载一个数百MB的.deb文件一样容易,Ubuntu内核开发团队为我编译了该文件。例如,在SystemtapOnUbuntu Wiki页面上对此进行了说明。
PS仅在没有其他解决方案的情况下才采用SystemTap方法,因为这是您必须学习的全新框架,并且需要花费时间/金钱,有时还要感到沮丧。
我继续为此编写了一个装订脚本。systemtap Wiki上有一个,但似乎不正确。在基本测试中,这看起来非常准确,但YMMV。
#! /usr/bin/env stap
global total_bytes, disk_bytes, counter
probe vfs.read.return {
if (bytes_read>0) {
if (devname=="N/A") {
} else {
total_bytes += bytes_read
}
}
}
probe ioblock.request
{
if (rw == 0 && size > 0)
{
if (devname=="N/A") {
} else {
disk_bytes += size
}
}
}
# print VFS hits and misses every 5 second, plus the hit rate in %
probe timer.s(5) {
if (counter%15 == 0) {
printf ("\n%18s %18s %10s %10s\n",
"Cache Reads (KB)", "Disk Reads (KB)", "Miss Rate", "Hit Rate")
}
cache_bytes = total_bytes - disk_bytes
if (cache_bytes < 0)
cache_bytes = 0
counter++
hitrate = 10000 * cache_bytes / (cache_bytes+disk_bytes)
missrate = 10000 * disk_bytes / (cache_bytes+disk_bytes)
printf ("%18d %18d %6d.%02d%% %6d.%02d%%\n",
cache_bytes/1024, disk_bytes/1024,
missrate/100, missrate%100, hitrate/100, hitrate%100)
total_bytes = 0
disk_bytes = 0
}
semantic error: unable to find member 'bi_size' for struct bio (alternatives: bi_next bi_bdev bi_flags bi_rw bi_iter bi_phys_segments bi_seg_front_size bi_seg_back_size bi_remaining bi_end_io bi_private bi_ioc bi_css bi_integrity bi_vcnt bi_max_vecs bi_cnt bi_io_vec bi_pool bi_inline_vecs): operator '->' at /usr/share/systemtap/tapset/linux/ioblock.stp:113:20 source: size = $bio->bi_size ^ Pass 2: analysis failed. [man error::pass2]
您能帮忙吗?
/ proc / slabinfo是一个很好的开始,但是并不能完全为您提供所需的信息(不要被启用了多个内核和统计信息的系统的命中/未命中百分比所迷惑;这是其他一些东西)。据我所知,没有办法将特定信息从内核中提取出来,尽管编写一点代码来做并不是很困难。
编辑:http://www.kernel.org/doc/man-pages/online/pages/man5/slabinfo.5.html
现在有来自perf-tools软件包的cachestat实用程序。
作者还列出了人们使用的一些替代方案(可能更粗糙):
A)通过使用iostat(1)监视磁盘读取来研究页面高速缓存未命中率,并假设这些是高速缓存未命中,而不是O_DIRECT。无论如何,未命中率通常是比比率更重要的指标,因为未命中与应用程序痛苦成正比。也可以使用free(1)查看缓存大小。
B)删除页面缓存(回显1> / proc / sys / vm / drop_caches),并测量性能变差了多少!我喜欢使用否定实验,但这当然是了解缓存使用情况的一种痛苦方式。
C)使用sar(1)并研究次要和主要故障。我认为这不起作用(例如,常规I / O)。
D)使用cache-hit-rate.stp SystemTap脚本,该脚本在Internet搜索Linux页面缓存命中率中排名第二。它可以在VFS接口的堆栈中检测高速缓存访问,以便可以看到对任何文件系统或存储设备的读取。高速缓存未命中通过其磁盘I / O进行衡量。这也错过了一些工作负载类型(该页面的“课程”中提到了某些类型),并且呼叫比率是“费率”。
如果您对特定进程的IO命中率/未命中率感兴趣,则一种简单但非常有效的方法是读取/proc/<pid>/io
文件。
在这里,您会发现4个关键值:
rchar
:从应用程序角度来看的读取字节总数(即:从物理存储而不是从缓存满足的读取之间没有区别)wchar
:如上,但关于已写字节read_bytes
:真正从存储子系统读取的字节write_bytes
:实际写入存储子系统的字节假设一个流程具有以下值:
rchar: 1000000
read_bytes: 200000
读取缓存未命中率(以字节为单位)为100*200000/1000000 = 20%
,命中率为100-20 = 80%
但是,有一个陷阱:该rchar
值包括作为tty IO的东西,因此对于从管道大量读取/向管道进行大量写入/写入的进程,上述计算将出现偏差,从而报告命中率高于有效值。