解決策 1:
独自の SystemTap スクリプトを開発できます。次の 2 つのサブシステムを説明する必要があります:
- VFS:これは、バッファ キャッシュの前のすべての I/O 要求 (つまり、絶対にすべての I/O 要求) を表します。 「vfs.read」、「vfs.write」、および「kernel.function("vfs_*")」プローブを確認します。監視するブロック デバイスをそれぞれのメジャー番号とマイナー番号で除外する必要があります。
- ブロック:これは、I/O スケジューラ (I/O 要求のマージと並べ替えも行う) の前にブロック デバイスに送信されたすべての I/O 要求を表します。ここで、バッファ キャッシュによってどのリクエストが失われたかがわかります。 「ioblock.request」プローブを確認してください。
SystemTap の開発には習得に時間がかかります。中程度の開発者で Linux の知識があれば、3 ~ 4 日で完了するはずです。はい、学習には時間がかかりますが、結果には非常に満足できるでしょう。SystemTap を使用すると、Linux カーネルのほぼすべての場所に (安全に) プローブを配置できます。
カーネルは、カーネル モジュールのロードとアンロードをサポートしている必要があることに注意してください。現在、ほとんどのストックカーネルがこれをサポートしています。カーネルのデバッグ シンボルもインストールする必要があります。私の Ubuntu システムでは、Ubuntu カーネル開発チームが私のためにコンパイルした数百 MB の .deb ファイルをダウンロードするのと同じくらい簡単でした。これについては、SystemtapOnUbuntu Wiki ページなどで説明されています。
追記SystemTap のアプローチは、他に解決策がない場合にのみ採用してください。これは、習得しなければならないまったく新しいフレームワークであり、時間とお金がかかり、時にはフラストレーションがたまるからです。
解決策 2:
私は先に進み、このための stap スクリプトを書きました。 systemtap wiki に 1 つありますが、正しくないようです。基本的なテストでは、これはかなり正確に見えますが、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
}
解決策 3:
/proc/slabinfo は良い出発点ですが、探している情報がまったく得られません (複数のコアと統計が有効になっているシステムでのヒット/ミスのパーセンテージに惑わされないでください。これらは別のものです)。私の知る限り、その特定の情報をカーネルから引き出す方法はありませんが、コードを少し書くのはそれほど難しいことではありません.
編集:http://www.kernel.org/doc/man-pages/online/pages/man5/slabinfo.5.html
解決策 4:
現在、perf-tools パッケージの cachestat ユーティリティがあります。
著者は、人々が使用するいくつかの (おそらくより粗雑な) 代替手段もリストしています:
<ブロック引用>A) iostat(1) を使用してディスクの読み取りを監視し、ページ キャッシュ ミス率を調査します。これらはキャッシュ ミスであり、たとえば O_DIRECT ではないと想定します。ミスはアプリケーションの痛みに比例するため、通常、ミス率は比率よりも重要な指標です。また、free(1) を使用してキャッシュ サイズを確認してください。
B) ページ キャッシュをドロップし (echo 1> /proc/sys/vm/drop_caches)、パフォーマンスがどの程度低下するかを測定します。私は否定的な実験を使用するのが大好きですが、これはもちろん、キャッシュの使用状況に光を当てるための苦痛な方法です.
C) sar(1) を使用して、マイナーおよびメジャー フォールトを調べます。これは機能しないと思います (通常の I/O など)。
D) cache-hit-rate.stp SystemTap スクリプトを使用します。これは、Linux ページ キャッシュ ヒット率のインターネット検索で第 2 位です。 VFS インターフェースのスタックの上位にあるキャッシュ アクセスをインストルメント化するため、任意のファイル システムまたはストレージ デバイスへの読み取りを確認できます。キャッシュ ミスは、ディスク I/O を介して測定されます。これはまた、いくつかのワークロード タイプを見逃しており (そのページの「レッスン」で言及されているものもあります)、比率を「レート」と呼んでいます。