$ free -h
total used free shared buff/cache available
Mem: 501M 146M 19M 9.7M 335M 331M
Swap: 1.0G 85M 938M
$ free -w -h
total used free shared buffers cache available
Mem: 501M 146M 19M 9.7M 155M 180M 331M
Swap: 1.0G 85M 938M
free
の出力で「バッファ」を説明または説明するにはどうすればよいですか?
このシステムには(既知の)問題はありません。 「バッファ」が「キャッシュ」(155M対180M)とほぼ同じ高さであることを知って驚いたり、興味を引いたりしました。 「キャッシュ」はファイルコンテンツのページキャッシュを表し、「キャッシュ/バッファ」の最も重要な部分である傾向があると思いました。 「バッファ」が何のためにあるのか私はあまりわかりません。
たとえば、これをRAMの多いラップトップと比較しました。私のラップトップでは、「バッファ」の数値は「キャッシュ」(200M対4G)よりも桁違いに小さくなっています。 「バッファー」とは何かについて適切に理解していれば、小規模なシステムでバッファーがこれほど大きな割合で増加する理由を尋ねることができます。
man proc
(私は陽気に古くなった「大」の定義を無視します):
バッファ%lu
非常に大きくならないはずのrawディスクブロック用の比較的一時的なストレージ(20MB程度)。
キャッシュされた%lu
ディスクから読み込まれたファイルのメモリ内キャッシュ(ページキャッシュ)。 SwapCachedは含まれません。
$ free -V
free from procps-ng 3.3.12
$ uname -r
4.9.0-6-marvell
$ systemd-detect-virt
none
$ cat /proc/meminfo
MemTotal: 513976 kB
MemFree: 20100 kB
MemAvailable: 339304 kB
Buffers: 159220 kB
Cached: 155536 kB
SwapCached: 2420 kB
Active: 215044 kB
Inactive: 216760 kB
Active(anon): 56556 kB
Inactive(anon): 73280 kB
Active(file): 158488 kB
Inactive(file): 143480 kB
Unevictable: 10760 kB
Mlocked: 10760 kB
HighTotal: 0 kB
HighFree: 0 kB
LowTotal: 513976 kB
LowFree: 20100 kB
SwapTotal: 1048572 kB
SwapFree: 960532 kB
Dirty: 240 kB
Writeback: 0 kB
AnonPages: 126912 kB
Mapped: 40312 kB
Shmem: 9916 kB
Slab: 37580 kB
SReclaimable: 29036 kB
SUnreclaim: 8544 kB
KernelStack: 1472 kB
PageTables: 3108 kB
NFS_Unstable: 0 kB
Bounce: 0 kB
WritebackTmp: 0 kB
CommitLimit: 1305560 kB
Committed_AS: 1155244 kB
VmallocTotal: 507904 kB
VmallocUsed: 0 kB
VmallocChunk: 0 kB
$ Sudo slabtop --once
Active / Total Objects (% used) : 186139 / 212611 (87.5%)
Active / Total Slabs (% used) : 9115 / 9115 (100.0%)
Active / Total Caches (% used) : 66 / 92 (71.7%)
Active / Total Size (% used) : 31838.34K / 35031.49K (90.9%)
Minimum / Average / Maximum Object : 0.02K / 0.16K / 4096.00K
OBJS ACTIVE USE OBJ SIZE SLABS OBJ/SLAB CACHE SIZE NAME
59968 57222 0% 0.06K 937 64 3748K buffer_head
29010 21923 0% 0.13K 967 30 3868K dentry
24306 23842 0% 0.58K 4051 6 16204K ext4_inode_cache
22072 20576 0% 0.03K 178 124 712K kmalloc-32
10290 9756 0% 0.09K 245 42 980K kmalloc-96
9152 4582 0% 0.06K 143 64 572K kmalloc-node
9027 8914 0% 0.08K 177 51 708K kernfs_node_cache
7007 3830 0% 0.30K 539 13 2156K radix_tree_node
5952 4466 0% 0.03K 48 124 192K jbd2_revoke_record_s
5889 5870 0% 0.30K 453 13 1812K inode_cache
5705 4479 0% 0.02K 35 163 140K file_lock_ctx
3844 3464 0% 0.03K 31 124 124K anon_vma
3280 3032 0% 0.25K 205 16 820K kmalloc-256
2730 2720 0% 0.10K 70 39 280K btrfs_trans_handle
2025 1749 0% 0.16K 81 25 324K filp
1952 1844 0% 0.12K 61 32 244K kmalloc-128
1826 532 0% 0.05K 22 83 88K trace_event_file
1392 1384 0% 0.33K 116 12 464K proc_inode_cache
1067 1050 0% 0.34K 97 11 388K shmem_inode_cache
987 768 0% 0.19K 47 21 188K kmalloc-192
848 757 0% 0.50K 106 8 424K kmalloc-512
450 448 0% 0.38K 45 10 180K ubifs_inode_slab
297 200 0% 0.04K 3 99 12K eventpoll_pwq
288 288 100% 1.00K 72 4 288K kmalloc-1024
288 288 100% 0.22K 16 18 64K mnt_cache
287 283 0% 1.05K 41 7 328K idr_layer_cache
240 8 0% 0.02K 1 240 4K fscrypt_info
Buffers
は何に使用されますか?Buffers
が特に大きいか小さいと予想されるのはなぜですか?Buffers
は、ブロックデバイスに使用されるページキャッシュの量を報告します。カーネルは、Cached
を報告するときに、意図的にこの量を残りのページキャッシュから差し引く必要があります。
meminfo_proc_show() を参照してください:
_cached = global_node_page_state(NR_FILE_PAGES) -
total_swapcache_pages() - i.bufferram;
...
show_val_kb(m, "MemTotal: ", i.totalram);
show_val_kb(m, "MemFree: ", i.freeram);
show_val_kb(m, "MemAvailable: ", available);
show_val_kb(m, "Buffers: ", i.bufferram);
show_val_kb(m, "Cached: ", cached);
_
ページキャッシュはMMUページサイズ、通常は最小4096バイト)の単位で機能します。これはmmap()
、つまりメモリマップファイルアクセスに不可欠です。[1] [2]独立したプロセス間でロードされたプログラム/ライブラリコードのページを共有し、個別のページをオンデマンドでロードできるようにします(他にスペースが必要で、最近使用されていないページのアンロードにも使用できます)。
[1] メモリマップI/O -GNU Cライブラリマニュアル。
[2] mmap
-ウィキペディア。
初期のUNIXにはディスクブロックの「バッファキャッシュ」があり、mmap()はありませんでした。どうやらmmap()が最初に追加されたとき、彼らは単にページキャッシュをバッファキャッシュの上にボルトで固定しました。これは、聞こえるほど厄介です。最終的に、UNIXベースのOSはバッファキャッシュを取り除きました。したがって、すべてのファイルキャッシュはページ単位になります。ページは、ディスク上の場所ではなく、(ファイル、オフセット)によって検索されます。これは「統一バッファキャッシュ」と呼ばれていましたが、これはおそらく「バッファキャッシュ」に慣れ親しんでいたためです。[3]
[3] UBC:NetBSD用の効率的な統合I/Oおよびメモリキャッシングサブシステム
「Linuxが追加する興味深いひねりの1つは、ページがディスクに格納されているデバイスブロック番号が、_buffer_head
_構造体のリストの形式でページとともにキャッシュされることです。変更されたページがディスクに書き戻される場合、I/O要求をすぐにデバイスドライバーに送信できます。間接ブロックを読み取ってページのデータを書き込む場所を決定する必要はありません。」[3]
Linux 2.2では、書き込みには使用されるが読み取りには使用されない個別の「バッファキャッシュ」がありました。 「ページキャッシュは、データを書き戻すためにバッファキャッシュを使用し、データの追加のコピーが必要であり、一部の書き込み負荷に対してメモリ要件を2倍にしました」(?)。[4]詳細についてはあまり気にしないでください。しかし、この歴史がLinuxがBuffers
の使用状況を個別に報告する理由の1つになるでしょう。
[4] Linux 2.4のメモリ管理におけるページの置き換え 、Rik van Riel。
対照的に、Linux 2.4以降では、追加のコピーは存在しません。 「システムはディスクIOページキャッシュページと直接やり取りします。] [4] Linux 2.4は2001年にリリースされました。
Buffers
は何に使用されますか?ブロックデバイスはファイルとして扱われるため、ページキャッシュがあります。これは「ファイルシステムメタデータとrawブロックデバイスのキャッシュ」に使用されます。[4]しかし、Linuxの現在のバージョンでは、ファイルシステムはファイルの内容をコピーしないため、「二重キャッシュ」はありません。
ページキャッシュのBuffers
の部分はLinuxバッファキャッシュであると思います。一部のソースはこの用語に同意しない場合があります。
ファイルシステムが使用するバッファキャッシュの量は、特定のファイルシステムの詳細によって異なります。問題のシステムはext4を使用しています。 ext3/ext4は、ジャーナル、ディレクトリコンテンツ、その他のメタデータにLinuxバッファキャッシュを使用します。
Ext3、ext4、ocfs2などの特定のファイルシステムは、jbdまたはjbd2レイヤーを使用して物理ブロックジャーナリングを処理し、このレイヤーは基本的にバッファーキャッシュを使用します。
Linuxカーネルバージョン2.4以前は、Linuxには個別のページキャッシュとバッファキャッシュがありました。 2.4以降、ページキャッシュとバッファキャッシュは統合され、
Buffers
は、ページキャッシュに表示されない生のディスクブロックです。つまり、ファイルデータではありません。...
ただし、カーネルはページではなくブロックの観点からブロックI/Oを実行する必要があるため、バッファキャッシュは残ります。ほとんどのブロックはファイルデータを表すため、ほとんどのバッファキャッシュはページキャッシュによって表されます。ただし、少量のブロックデータ(メタデータやrawブロックI/Oなど)はファイルでバックアップされないため、バッファーキャッシュのみで表されます。
- Quoraのペアの回答 by Robert Love 、最終更新2013。
どちらのライターも、Linuxカーネルメモリ管理に携わってきたLinux開発者です。最初のソースは、技術的な詳細についてより具体的です。 2番目の情報源は、より一般的な要約であり、一部の仕様では矛盾している可能性があります。
キャッシュがページ内で索引付けされている場合でも、ファイルシステムが部分的なページのメタデータ書き込みを実行する可能性があることは事実です。ユーザープロセスでも、write()
を使用すると、少なくともブロックデバイスに対して(mmap()
とは対照的に)、部分ページ書き込みを実行できます。これは書き込みにのみ適用され、読み取りには適用されません。ページキャッシュを読み取る場合、ページキャッシュは常にページ全体を読み取ります。
Linusは、ブロックサイズの書き込みを行うためにバッファキャッシュが必要ないこと、およびファイルシステムがページキャッシュを独自にアタッチしていても部分的なページメタデータの書き込みを実行できることを好む ブロックデバイスの代わりにファイル。私は彼がext2がこれをしていると言うのは正しいと確信しています。ジャーナリングシステムを備えたext3/ext4はサポートしていません。この設計につながった問題が何であるかはあまり明確ではありません。彼が怒っていた人々は説明するのに飽きた。
ext4_readdir()は、Linusの発言を満たすために変更されていません。彼の望ましいアプローチが他のファイルシステムのreaddir()で使用されているのもわかりません。 XFSはディレクトリにもバッファキャッシュを使用すると思います。 bcachefsはreaddir()のページキャッシュをまったく使用しません。 btreeには独自のキャッシュを使用します。 btrfsで何かが欠けている可能性があります。
Buffers
が特に大きくなる、または小さくなることが予想されるのはなぜですか?この場合、ファイルシステムの ext4ジャーナルサイズ は128Mです。これが、1)バッファキャッシュが128Mをわずかに超えて安定する理由を説明しています。 2)バッファキャッシュは、ラップトップのRAM)の量に比例してスケーリングしません。
その他の考えられる原因については、 を参照してください。freeからの出力のbuffers列とは何ですか?free
によって報告される「バッファ」は、実際にはBuffers
と再利用可能なスラブメモリの組み合わせです。
ジャーナルの書き込みがバッファーキャッシュを使用していることを確認するために、ニースでファイルシステムを高速にシミュレートしましたRAM(tmpfs))、さまざまなジャーナルサイズの最大バッファー使用量を比較しました。
_# dd if=/dev/zero of=/tmp/t bs=1M count=1000
...
# mkfs.ext4 /tmp/t -J size=256
...
# LANG=C dumpe2fs /tmp/t | grep '^Journal size'
dumpe2fs 1.43.5 (04-Aug-2017)
Journal size: 256M
# mount /tmp/t /mnt
# cd /mnt
# free -w -m
total used free shared buffers cache available
Mem: 7855 2521 4321 285 66 947 5105
Swap: 7995 0 7995
# for i in $(seq 40000); do dd if=/dev/zero of=t bs=1k count=1 conv=sync status=none; sync t; sync -f t; done
# free -w -m
total used free shared buffers cache available
Mem: 7855 2523 3872 551 237 1223 4835
Swap: 7995 0 7995
_
_# dd if=/dev/zero of=/tmp/t bs=1M count=1000
...
# mkfs.ext4 /tmp/t -J size=16
...
# LANG=C dumpe2fs /tmp/t | grep '^Journal size'
dumpe2fs 1.43.5 (04-Aug-2017)
Journal size: 16M
# mount /tmp/t /mnt
# cd /mnt
# free -w -m
total used free shared buffers cache available
Mem: 7855 2507 4337 285 66 943 5118
Swap: 7995 0 7995
# for i in $(seq 40000); do dd if=/dev/zero of=t bs=1k count=1 conv=sync status=none; sync t; sync -f t; done
# free -w -m
total used free shared buffers cache available
Mem: 7855 2509 4290 315 77 977 5086
Swap: 7995 0 7995
_
私は最初にTed Tsoの電子メールを見つけ、それがwriteキャッシングを強調していることに興味をそそられました。 「ダーティ」、未書き込みデータが私のシステムでRAMの30%に到達できた場合、それは驚くべきことでしょう。 。_Sudo atop
_は、問題のシステムが10秒の間隔で一貫して1MBのみを書き込むことを示しています。関係するファイルシステムは、このレートの100倍以上に対応できます(USB2ハードディスクドライブ上にあり、最大スループット〜20MB /秒)。
Blktrace(_btrace -w 10 /dev/sda
_)を使用すると、読み取られるデータがほとんどないため、キャッシュされているIOは書き込みである必要があります。また、mysqld
は、IOを実行する唯一のuserspaceプロセスです。
書き込みを担当しているサービス(icinga2がmysqlに書き込む)を停止し、再確認しました。 「バッファ」が20M未満に下がるのを見ました-それについての説明はありません-そのままです。ライターを再起動すると、「バッファ」が10秒間隔で約0.1Mずつ上昇することが示されます。私はそれがこの速度を一貫して維持し、70M以上に上昇するのを観察しました。
_echo 3 | Sudo tee /proc/sys/vm/drop_caches
_を実行すると、「バッファ」を再び4.5Mに下げるのに十分でした。これは、私のバッファの蓄積が「クリーンな」キャッシュであることを証明しています。Linuxは必要なときにすぐにドロップできます。このシステムは書き込まれていないデータを蓄積していません。 (_drop_caches
_はライトバックを実行しないため、ダーティページを削除できません。最初にキャッシュをクリーンアップするテストを実行する場合は、sync
コマンドを使用します)。
Mysqlディレクトリ全体はわずか150Mです。蓄積するバッファはmysqlの書き込みからのメタデータブロックを表す必要がありますが、このデータには非常に多くのメタデータブロックがあると思うと驚きました。
あなたのバージョンのfree
は正しい考えを持っています。デフォルトでは、レポートにバッファとキャッシュを組み合わせます。これは基本的に同じものだからです。これらは両方とも、RAM(その二次記憶装置:ディスクとSSDがより高速))で記憶しているコンピューターであり、ディスクとSSDを読み取ったときにすでに見たことです。
オペレーティングシステムがメモリが他の何かによってよりよく使用されていると感じた場合は、メモリを解放できます。したがって、バッファとキャッシュについて心配する必要はありません。
ただし、DVDを鑑賞すると、バッファが上がり、他のバッファ/キャッシュコンテンツを追い出す可能性があります。したがって、nocacheを使用してDVDプレーヤーを実行することができます(それが問題の原因である場合)。