30% RAM adalah "buffer". Apa itu?

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

Bagaimana saya bisa menggambarkan atau menjelaskan "buffer" di output dari free?

Saya tidak memiliki masalah (yang diketahui) dengan sistem ini. Saya hanya terkejut dan penasaran melihat bahwa "buffer" hampir setinggi "cache" (155M vs 180M). Saya pikir "cache" mewakili cache halaman dari konten file, dan cenderung menjadi bagian paling penting dari "cache / buffer". Saya kurang jelas untuk apa "buffer".

Sebagai contoh saya membandingkan ini dengan laptop saya, yang memiliki lebih banyak RAM. Di laptop saya angka "buffer" adalah urutan besarnya lebih kecil dari "cache" (200M vs 4G). Jika saya memiliki pemahaman yang tepat tentang apa "buffer" itu, maka saya bisa mulai bertanya mengapa buffer dapat tumbuh sedemikian besar pada sistem yang lebih kecil.

man proc (Saya mengabaikan definisi usang "besar"):

Buffer% lu

Penyimpanan relatif sementara untuk blok disk mentah yang seharusnya tidak menjadi sangat besar (20MB atau lebih).

Tembolok% lu

Cache di dalam memori untuk file yang dibaca dari disk (cache halaman). Tidak termasuk 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           
sourcejedi
sumber
3
linuxatemyram.com berguna untuk dibaca
Basile Starynkevitch

Jawaban:

13
  1. Apa perbedaan antara "buffer", dan cache lainnya?
  2. Mengapa kita melihat perbedaan ini begitu mencolok? (Kemungkinan alasan historis)
  3. Untuk apa Buffers?
  4. Mengapa kita berharap Bufferssecara khusus menjadi lebih besar atau lebih kecil?

1. Apa perbedaan antara "buffer", dan jenis cache lainnya?

Buffersmelaporkan jumlah cache halaman yang digunakan untuk perangkat blok. Kernel harus dengan sengaja mengurangi jumlah ini dari sisa halaman cache ketika melaporkan Cached.

Lihat 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. Mengapa kita melihat perbedaan ini begitu mencolok? (Kemungkinan alasan historis)

Cache halaman berfungsi dalam satuan ukuran halaman MMU, biasanya minimal 4096 byte. Ini penting untuk mmap(), yaitu akses file yang dipetakan memori. [1] [2] Ini digunakan untuk berbagi halaman kode program / pustaka yang dimuat antara proses independen, dan memungkinkan memuat halaman individual sesuai permintaan. (Juga untuk membongkar halaman saat ada hal lain yang membutuhkan ruang, dan belum digunakan baru-baru ini).

[1] Memori-dipetakan I / O - Manual Perpustakaan C GNU.
[2] mmap- Wikipedia.

UNIX awal memiliki "buffer cache" dari blok disk, dan tidak memiliki mmap (). Rupanya ketika mmap () pertama kali ditambahkan, mereka hanya mengunci halaman cache di atas cache buffer. Ini berantakan seperti kedengarannya. Akhirnya, OS berbasis UNIX menyingkirkan cache buffer. Jadi sekarang semua file cache dalam satuan halaman. Halaman dilihat oleh (file, offset), bukan oleh lokasi pada disk. Ini disebut "cache buffer yang disatukan", mungkin karena orang lebih akrab dengan "cache buffer". [3]

[3] UBC: Subsistem I / O dan Memori Terpadu yang Efisien untuk NetBSD

"Satu sentuhan menarik yang ditambahkan Linux adalah nomor blok perangkat tempat halaman disimpan dalam disk di-cache dengan halaman dalam bentuk daftar buffer_headstruktur. Ketika halaman yang dimodifikasi akan ditulis kembali ke disk, I / O permintaan dapat dikirim ke driver perangkat segera, tanpa perlu membaca blok tidak langsung untuk menentukan di mana data halaman harus ditulis. "[3]

Di Linux 2.2 ada "buffer cache" terpisah yang digunakan untuk menulis, tetapi tidak untuk dibaca. "Halaman cache menggunakan cache buffer untuk menulis kembali datanya, membutuhkan salinan data tambahan, dan menggandakan persyaratan memori untuk beberapa beban tulis" (?). [4] Jangan terlalu khawatir tentang detailnya, tetapi sejarah ini akan menjadi salah satu alasan mengapa Linux melaporkan Bufferspenggunaan secara terpisah.

[4] Penggantian halaman dalam manajemen memori Linux 2.4 , Rik van Riel.

Sebaliknya, di Linux 2.4 dan di atasnya, salinan tambahan tidak ada. "Sistem melakukan IO disk secara langsung ke dan dari halaman cache halaman." [4] Linux 2.4 dirilis pada tahun 2001.

3. Untuk apa Buffersdigunakan?

Perangkat blok diperlakukan sebagai file, dan juga memiliki cache halaman. Ini digunakan "untuk metadata sistem file dan caching perangkat blok mentah". [4] Tetapi dalam versi Linux saat ini, sistem file tidak menyalin isi file melalui itu, sehingga tidak ada "caching ganda".

Saya menganggap Buffersbagian dari cache halaman sebagai cache buffer Linux. Meskipun beberapa sumber mungkin tidak setuju dengan terminologi ini.

Berapa banyak buffer cache yang digunakan sistem file, jika ada, tergantung pada detail sistem file tertentu. Sistem dalam pertanyaan menggunakan ext4. ext3 / ext4 menggunakan cache buffer Linux untuk jurnal, untuk isi direktori, dan beberapa metadata lainnya.

Sistem file tertentu, termasuk ext3, ext4, dan ocfs2, menggunakan lapisan jbd atau jbd2 untuk menangani penjurnalan blok fisik mereka, dan lapisan ini pada dasarnya menggunakan cache buffer.

- Artikel email oleh Ted Tso , 2013

Sebelum kernel Linux versi 2.4, Linux memiliki cache halaman dan buffer yang terpisah. Sejak 2.4, cache halaman dan buffer disatukan dan Buffersblok disk mentah tidak terwakili dalam cache halaman — yaitu, bukan file data.

...

Cache penyangga tetap, karena kernel masih perlu melakukan blok I / O dalam hal blok, bukan halaman. Karena sebagian besar blok mewakili data file, sebagian besar cache cache diwakili oleh cache halaman. Tetapi sejumlah kecil data blok tidak didukung file — metadata dan blok I / O mentah misalnya — dan dengan demikian hanya diwakili oleh cache buffer.

- Sepasang jawaban Quora oleh Robert Love , terakhir diperbarui 2013.

Kedua penulis adalah pengembang Linux yang telah bekerja dengan manajemen memori kernel Linux. Sumber pertama lebih spesifik tentang detail teknis. Sumber kedua adalah ringkasan yang lebih umum, yang mungkin kontradiktif dan ketinggalan zaman dalam beberapa hal spesifik.

Memang benar bahwa sistem file dapat melakukan penulisan sebagian halaman metadata, meskipun cache diindeks dalam halaman. Bahkan proses pengguna dapat melakukan penulisan sebagian halaman ketika mereka menggunakan write()(sebagai lawan dari mmap()), setidaknya langsung ke perangkat blok. Ini hanya berlaku untuk menulis, bukan membaca. Saat Anda membaca cache halaman, cache halaman selalu membaca halaman penuh.

Linus suka mengatakan bahwa cache buffer tidak diperlukan untuk melakukan penulisan berukuran blok, dan sistem file dapat melakukan penulisan sebagian halaman metadata bahkan dengan cache halaman yang dilampirkan ke file mereka sendiri alih-alih perangkat blok. Saya yakin dia benar untuk mengatakan bahwa ext2 melakukan ini. ext3 / ext4 dengan sistem penjurnalannya tidak. Kurang jelas apa masalah yang menyebabkan desain ini. Orang-orang yang ia ucapkan jemu-jemu bosan menjelaskan.

ext4_readdir () belum diubah untuk memenuhi kata-kata kasar Linus. Saya tidak melihat pendekatan yang diinginkan digunakan dalam readdir () dari sistem file lain juga. Saya pikir XFS menggunakan cache buffer untuk direktori juga. bcachef tidak menggunakan cache halaman untuk readdir () sama sekali; ia menggunakan cache sendiri untuk btrees. Saya mungkin kehilangan sesuatu di btrfs.

4. Mengapa kita berharap Bufferssecara khusus menjadi lebih besar atau lebih kecil?

Dalam hal ini ternyata ukuran jurnal ext4 untuk sistem file saya adalah 128M. Jadi ini menjelaskan mengapa 1) cache buffer saya dapat stabil pada sedikit di atas 128M; 2) buffer cache tidak skala secara proporsional dengan jumlah RAM yang lebih besar di laptop saya.

Untuk beberapa kemungkinan penyebab lainnya, lihat Apa kolom buffer dalam output dari gratis? Perhatikan bahwa "buffer" yang dilaporkan oleh freesebenarnya adalah kombinasi dari Buffersdan memori slab yang dapat direklamasi.


Untuk memverifikasi bahwa penulisan jurnal menggunakan cache buffer, saya mensimulasikan sistem file dalam RAM cepat bagus (tmpfs), dan membandingkan penggunaan buffer maksimum untuk ukuran jurnal yang berbeda.

# 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

Sejarah jawaban ini: Bagaimana saya bisa melihat jurnal

Saya telah menemukan email Ted Tso terlebih dahulu, dan tertarik bahwa itu menekankan caching menulis . Saya akan terkejut jika "kotor", data tidak tertulis dapat mencapai 30% RAM pada sistem saya. sudo atopmenunjukkan bahwa selama interval 10 detik, sistem yang bersangkutan secara konsisten menulis hanya 1MB. Sistem file yang bersangkutan akan mampu mengimbangi lebih dari 100 kali kecepatan ini. (Ada di hard disk drive USB2, throughput maks ~ 20MB / s).

Menggunakan blktrace ( btrace -w 10 /dev/sda) menegaskan bahwa IO yang sedang di-cache harus ditulis, karena hampir tidak ada data yang sedang dibaca. Juga itu mysqldadalah satu-satunya proses userspace yang melakukan IO.

Saya menghentikan layanan yang bertanggung jawab untuk menulis (icinga2 menulis ke mysql) dan memeriksa ulang. Saya melihat "buffer" jatuh di bawah 20 juta - Saya tidak punya penjelasan untuk itu - dan tinggal di sana. Restart penulis lagi menunjukkan "buffer" naik ~ 0,1M untuk setiap interval 10 detik. Saya mengamatinya mempertahankan tingkat ini secara konsisten, naik kembali ke 70 juta ke atas.

Menjalankan echo 3 | sudo tee /proc/sys/vm/drop_cachessudah cukup untuk menurunkan "buffer" lagi, menjadi 4,5M. Ini membuktikan bahwa akumulasi buffer saya adalah cache "bersih", yang dapat segera dijatuhkan Linux saat diperlukan. Sistem ini tidak mengakumulasi data tidak tertulis . ( drop_cachestidak melakukan writeback dan karenanya tidak dapat menjatuhkan halaman kotor. Jika Anda ingin menjalankan tes yang membersihkan cache terlebih dahulu, Anda akan menggunakan syncperintah).

Seluruh direktori mysql hanya 150M. Buffer yang diakumulasikan harus mewakili blok metadata dari mysql menulis, tetapi mengejutkan saya untuk berpikir akan ada begitu banyak blok metadata untuk data ini.

sourcejedi
sumber
3

Versi Anda freememiliki ide yang tepat. Secara default, ini menggabungkan buffer dan cache dalam laporannya. Ini karena mereka pada dasarnya adalah hal yang sama. Keduanya adalah komputer yang mengingat dalam RAM (Penyimpanan sekunder yang lebih cepat: Disk dan SSD), apa yang telah dilihatnya saat membaca Disk dan SSD.

Jika sistem operasi merasa bahwa memori lebih baik digunakan oleh sesuatu yang lain maka dapat membebaskannya. Karena itu jangan khawatir tentang buffer dan cache.

Namun menonton DVD dapat menyebabkan buffer naik, dan mengusir konten buffer / cache lainnya. Karena itu Anda dapat menggunakan nocache untuk menjalankan pemutar DVD ( jika menyebabkan masalah ).

ctrl-alt-delor
sumber