RAMの30%は「バッファ」です。それは何ですか?


12
$ 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の多いラップトップと比較しました。私のラップトップでは、「バッファ」の数値は「キャッシュ」よりも1桁小さい(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           

回答:


13
  1. 「バッファ」と他のキャッシュの違いは何ですか?
  2. なぜこの区別がそれほど顕著に見えるのですか?(考えられる歴史的理由)
  3. 何をしているBuffersために使用?
  4. なぜ私たちはBuffers、特に大きくなったり小さくなったりするのでしょうか?

1.「バッファ」と他のタイプのキャッシュの違いは何ですか?

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);

2.なぜこの区別がこれほど顕著に見られるのですか?(考えられる歴史的理由)

ページキャッシュは、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年にリリースされました。

3. Buffers用途は何ですか?

ブロックデバイスはファイルとして扱われるため、ページキャッシュもあります。これは「ファイルシステムのメタデータとrawブロックデバイスのキャッシュ」に使用されます。[4] しかし、Linuxの現在のバージョンでは、ファイルシステムはファイルの内容をコピーしないため、「二重キャッシュ」はありません。

Buffersページキャッシュの一部はLinuxのバッファキャッシュだと思います。一部の情報源はこの用語に同意しないかもしれませんが。

ファイルシステムが使用するバッファーキャッシュがあれば、その量は特定のファイルシステムの詳細に依存します。問題のシステムはext4を使用します。ext3 / ext4は、ジャーナル、ディレクトリコンテンツ、およびその他のメタデータにLinuxバッファキャッシュを使用します。

ext3、ext4、ocfs2などの特定のファイルシステムは、jbdまたはjbd2レイヤーを使用して物理ブロックジャーナリングを処理し、このレイヤーは基本的にバッファーキャッシュを使用します。

- 電子メールの記事によるテッドTSO、2013

Linuxカーネルバージョン2.4以前は、Linuxには個別のページキャッシュとバッファキャッシュがありました。2.4以降、ページキャッシュとバッファキャッシュは統合されておりBuffers、ページキャッシュでは表されないrawディスクブロックです。つまり、ファイルデータではありません。

...

ただし、カーネルはページではなくブロックの観点からブロックI / Oを実行する必要があるため、バッファキャッシュは残ります。ほとんどのブロックはファイルデータを表すため、ほとんどのバッファキャッシュはページキャッシュによって表されます。ただし、少量のブロックデータ(たとえば、メタデータや生のブロックI / O)はファイルでバックアップされないため、バッファキャッシュによってのみ表されます。

- 最後に2013年に更新されたRobert LoveによるQuoraの回答

両方のライターは、Linuxカーネルメモリ管理を扱ったLinux開発者です。最初のソースは、技術的な詳細についてより具体的です。2番目のソースはより一般的な要約であり、一部の仕様では矛盾しており、古くなっている可能性があります。

キャッシュがページにインデックス付けされている場合でも、ファイルシステムが部分的なページのメタデータ書き込みを実行する可能性があることは事実です。ユーザープロセスでさえ、少なくともブロックデバイスに対して、write()(とは対照的にmmap())使用時に部分ページ書き込みを実行できます。これは書き込みにのみ適用され、読み取りには適用されません。ページキャッシュを読み取ると、ページキャッシュは常にページ全体を読み取ります。

Linusは、ブロックサイズの書き込みを行うためにバッファキャッシュが不要であり、ブロックシステムではなく独自のファイルにページキャッシュがアタッチされている場合でも、ファイルシステムが部分ページメタデータの書き込みを行えることを認めました。彼はext2がこれを行うと言うのが正しいと確信しています。ジャーナリングシステムを備えたext3 / ext4はサポートしていません。この設計に至った問題が何であったかはあまり明確ではありません。彼が怒鳴っていた人々は説明にうんざりしていました。

ext4_readdir()は、Linusの発言を満たすために変更されていません。彼の望ましいアプローチが他のファイルシステムのreaddir()で使用されているのもわかりません。XFSはディレクトリにもバッファキャッシュを使用すると思います。bcachefsはreaddir()のページキャッシュをまったく使用しません。これは、btreeに独自のキャッシュを使用します。btrfsに何か欠けている可能性があります。

4. Buffers特に大きくなる、または小さくなることが特に予想されるのはなぜですか?

この場合、ファイルシステムのext4ジャーナルサイズは128Mであることがわかります。これが、1)バッファキャッシュが128Mをわずかに超えて安定する理由を説明しています。2)バッファキャッシュは、私のラップトップの大容量RAMに比例してスケーリングしません。

その他の考えられる原因については、freeからの出力のバッファー列とは何ですか?を参照してください によって報告される「バッファ」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のメールを見つけましたが、書き込みキャッシュを強調しいることに興味をそそられました。「ダーティ」で未書き込みのデータがシステムのRAMの30%に到達できたとしたら、それは驚くべきことです。 sudo atop10秒の間隔で、問題のシステムが一貫して1MBのみを書き込むことを示しています。関係するファイルシステムは、この速度の100倍以上に対応できます。(USB2ハードディスクドライブにあり、最大スループットは最大20MB / sです)。

blktrace(btrace -w 10 /dev/sda)を使用すると、読み取られるデータがほとんどないため、キャッシュされているIOは書き込みである必要があります。また、これmysqldはIOを実行する唯一のユーザー空間プロセスです。

書き込みを担当するサービス(myinga2からmysqlへの書き込み)を停止し、再確認しました。「バッファ」が20M未満に落ちるのを見ました-それについての説明はありません-そしてそこにとどまります。ライターを再起動すると、10秒ごとに「バッファ」が〜0.1Mずつ増加することが示されます。私はそれがこの速度を一貫して維持し、70M以上に上昇するのを観察しました。

実行echo 3 | sudo tee /proc/sys/vm/drop_cachesは、「バッファ」を再び4.5Mに下げるのに十分でした。これは、私のバッファの蓄積が「クリーンな」キャッシュであることを証明します。Linuxは必要に応じてすぐにドロップできます。このシステムは未書き込みのデータを蓄積してません。(drop_cachesライトバックを実行しないため、ダーティページを削除できません。最初にキャッシュを消去するテストを実行する場合は、syncコマンドを使用します)。

mysqlディレクトリ全体はわずか150Mです。蓄積するバッファはmysqlの書き込みからのメタデータブロックを表す必要がありますが、このデータには非常に多くのメタデータブロックがあると思うと驚きました。


3

のバージョンにfreeは正しいアイデアがあります。デフォルトでは、レポートにバッファとキャッシュを組み合わせます。これは基本的に同じものだからです。これらは両方とも、RAMに記憶しているコンピューター(その2次ストレージ:ディスクとSSD)であり、ディスクとSSDを読み取るときにすでに見ているものです。

オペレーティングシステムが、メモリが他の何かによってより適切に使用されていると感じた場合、メモリを解放できます。したがって、バッファとキャッシュについて心配する必要はありません。

ただし、DVDを鑑賞すると、バッファが上がり、他のバッファ/キャッシュコンテンツが削除される可能性があります。したがって、(問題を引き起こしている場合は)nocacheを使用してDVDプレーヤーを実行する必要があります。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.