GNU/Linux >> Linux の 問題 >  >> Linux

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

<オール>
  • 「バッファ」と他のタイプのキャッシュの違いは何ですか?
  • なぜこの違いが際立っているのですか?キャッシュされたファイル コンテンツについて話すときに「バッファ キャッシュ」と言う人がいるのはなぜですか?
  • Buffers とは
  • 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 レイヤーを使用して物理ブロックのジャーナリングを処理します。このレイヤーは基本的にバッファー キャッシュを使用します。

    -- Ted Tso によるメール記事、2013 年

    <ブロック引用>

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

    ...

    ただし、カーネルはページではなくブロック単位でブロック 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 です。したがって、これが理由を説明しています。 2) バッファ キャッシュは、ラップトップの RAM の量に比例してスケーリングしません。

    その他の考えられる原因については、free からの出力の buffers 列とは何ですか? を参照してください。 free によって報告される「バッファ」に注意してください 実際には Buffers の組み合わせです 再利用可能なカーネル スラブ メモリ。

    ジャーナル書き込みがバッファ キャッシュを使用することを確認するために、Nice Fast 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/s)。

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

    書き込み(mysqlへのicinga2書き込み)を担当するサービスを停止し、再チェックしました。 「バッファ」が20M未満に落ちるのを見ました-それについての説明はありません-そしてそこにとどまります。ライターを再度再起動すると、「バッファ」が 10 秒間隔ごとに最大 0.1M 増加することが示されます。このレートを一貫して維持し、70M 以上に戻っていることがわかりました。

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

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


    free のバージョン 正しい考えを持っています。デフォルトでは、レポートでバッファとキャッシュを組み合わせます。これは、基本的に同じものだからです。これらは両方とも、ディスクと SSD を読み取るときに既に見たものを RAM (より高速なセカンダリ ストレージ:ディスクと SSD) に記憶しているコンピュータです。

    オペレーティング システムは、メモリを別のものに使用したほうがよいと判断した場合、メモリを解放できます。したがって、バッファとキャッシュについて心配する必要はありません。

    ただし、DVD を視聴すると、バッファが増加し、他のバッファ/キャッシュ コンテンツが追い出される可能性があります。したがって、nocache を使用して DVD プレーヤーを実行する必要がある場合があります (問題が発生している場合)。 ).


    Linux
    1. perf キャッシュ イベントの意味は何ですか?

    2. .cache は何をしますか?膨大なディスク容量を消費します

    3. 自宅で作成できる最も単純な Linux 対応ボードは何ですか?

    1. free からの出力の buffers 列は何ですか?

    2. ページキャッシュに 100% ページインされたファイルが別のプロセスによって変更されるとどうなるか

    3. Linux 上のファイルを RAM にキャッシュ/プリロードする

    1. Linuxでメモリバッファとキャッシュを削除する方法

    2. マニュアルページの数字はどういう意味ですか?

    3. free の出力におけるバッファ/キャッシュ ラインの意味