Batasi ukuran cache buffer di Linux

25

Apakah ada cara untuk memberitahu kernel Linux untuk hanya menggunakan persentase memori tertentu untuk cache buffer? Saya tahu /proc/sys/vm/drop_cachesdapat digunakan untuk menghapus cache sementara, tetapi apakah ada pengaturan permanen yang mencegahnya tumbuh lebih dari misalnya 50% dari memori utama?

Alasan saya ingin melakukan ini, adalah bahwa saya memiliki server yang menjalankan OSD Ceph yang terus-menerus menyajikan data dari disk dan mengelola untuk menggunakan seluruh memori fisik sebagai buffer cache dalam beberapa jam. Pada saat yang sama, saya perlu menjalankan aplikasi yang akan mengalokasikan sejumlah besar (beberapa 10 GB) memori fisik. Bertentangan dengan kepercayaan populer (lihat saran yang diberikan pada hampir semua pertanyaan mengenai cache buffer), otomatis membebaskan memori dengan membuang entri cache bersih tidak instan: memulai aplikasi saya bisa memakan waktu hingga satu menit ketika cache buffer penuh ( *), sementara setelah membersihkan cache (menggunakan echo 3 > /proc/sys/vm/drop_caches) aplikasi yang sama dimulai hampir secara instan.

(*) Selama menit waktu startup ini, aplikasi salah dalam memori baru tetapi menghabiskan 100% waktunya di kernel, menurut Vtune dalam fungsi yang disebut pageblock_pfn_to_page. Fungsi ini tampaknya terkait dengan pemadatan memori yang diperlukan untuk menemukan halaman besar, yang membuat saya percaya bahwa sebenarnya fragmentasi adalah masalahnya.

Wim
sumber
1
Ada sesuatu yang disebut cache tiering. set pool ceph osd {cachepool} hit_set_count 1 set pool ceph osd {cachepool} hit_set_ periode 3600 set pool ceph osd mengatur {cachepool} target_max_bytes 1000000000000 sebagai contoh, lihat. docs.ceph.com/docs/master/rados/operations/cache-tiering
Michael D.
2
Karena masalah ini tampaknya hanya memengaruhi permulaan aplikasi yang membutuhkan banyak memori, mungkin Anda dapat memulai aplikasi melalui skrip yang membersihkan cache sebelum benar-benar memulainya. Mungkin ini akan memulainya lebih cepat sementara masih meninggalkan manajemen cache ke kernel saat mereka sedang berjalan.
Thawn

Jawaban:

14

Jika Anda tidak menginginkan batas absolut tetapi cukup menekan kernel untuk membersihkan buffer lebih cepat, Anda harus melihatnya vm.vfs_cache_pressure

Variabel ini mengontrol kecenderungan kernel untuk merebut kembali memori yang digunakan untuk caching cache VFS, dibandingkan pagecache dan swap. Meningkatkan nilai ini meningkatkan tingkat di mana cache VFS direklamasi.

Mulai dari 0 hingga 200. Pindahkan ke arah 200 untuk tekanan lebih tinggi. Nilai standarnya adalah 100. Anda juga dapat menganalisis penggunaan memori menggunakan slabtopperintah. Dalam kasus Anda, dentrydan *_inode_cachenilai harus tinggi.

Jika Anda menginginkan batas absolut, Anda harus melihat ke atas cgroups. Tempatkan server Ceph OSD di dalam cgroup dan batasi memori maksimum yang dapat digunakan dengan mengatur memory.limit_in_bytesparameter untuk cgroup.

memory.memsw.limit_in_bytesmenetapkan jumlah maksimum untuk jumlah memori dan penggunaan swap. Jika tidak ada unit yang ditentukan, nilai ditafsirkan sebagai byte. Namun, dimungkinkan untuk menggunakan sufiks untuk mewakili satuan yang lebih besar - k atau K untuk kilobyte, m atau M untuk Megabita, dan g atau G untuk Gigabita.

Referensi:

[1] - GlusterFS Linux Kernel Tuning

[2] - RHEL 6 Panduan Manajemen Sumber Daya

NOLFXceptMe
sumber
1
Kelompok dengan limit_in_bytesset tampaknya melakukannya. Terima kasih!
Wim
4
Saya pikir vfs_cache_pressurehanya membersihkan cache gigi dan inode, dan tidak ada hubungannya dengan buffer cache.
kawing-chiu
Peningkatan di vfs_cache_pressureatas 100dapat membantu jika Anda tidak memiliki RAM yang cukup untuk beban kerja Anda. Ini akan mengurangi penggunaan RAM tetapi akan menyebabkan kinerja I / O yang lebih buruk secara keseluruhan.
Mikko Rantalainen
3

Saya tidak tahu tentang A% tetapi, Anda dapat menetapkan batas waktu sehingga turun setelah x jumlah menit.

Pertama di terminal

sync && echo 3 | sudo tee /proc/sys/vm/drop_caches

Untuk menghapus cache saat ini.

Buat itu cron-job Tekan Alt-F2, ketik gksudo gedit /etc/crontab, Kemudian Tambahkan baris ini di dekat bagian bawah.

 */15 *    * * *   root    sync && echo 3 > /proc/sys/vm/drop_caches

Ini membersihkan setiap 15 menit. Anda dapat mengatur ke 1 atau 5 menit jika Anda benar-benar ingin dengan mengubah parameter pertama menjadi * atau * / 5 daripada * / 15

Untuk melihat RAM gratis Anda, kecuali cache:

free -m | sed -n -e '3p' | grep -Po "\d+$
DnrDevil
sumber
Saya merasa di sini sedikit redundansi. Sejauh yang saya tahu, itu 3 > drop_cachestermasuk perilakusync
andras.tim
1
@ andras.tim no - sync menulis halaman kotor ke disk, 3 untuk drop_caches hanya mengambil kembali / membebaskan memori yang digunakan oleh halaman bersih dan cache lainnya. Anda tidak harus menjalankan sinkronisasi tetapi jika Anda melakukannya, lebih banyak memori akan bersih daripada kotor dan lebih banyak memori akan dibebaskan ketika Anda menjatuhkan cache
Daniel S. Sterling
2

Saya pikir firasat Anda di akhir pertanyaan Anda ada di jalur yang benar. Saya menduga A, NUMA-sadar alokasi memori memigrasikan halaman antara CPU, atau B, lebih mungkin, kode defrag hugepages transparan berusaha menemukan daerah yang berdekatan dan selaras.

Hugepage dan hugepage transparan telah diidentifikasi untuk peningkatan kinerja yang ditandai pada beban kerja tertentu dan bertanggung jawab untuk menghabiskan banyak waktu CPU tanpa memberikan banyak manfaat.

Ini akan membantu untuk mengetahui kernel mana yang Anda jalankan, isi / proc / meminfo (atau setidaknya nilai HugePages_ *.), Dan, jika mungkin, lebih banyak dari vtune profiler callgraph yang merujuk pageblock_pfn_to_page ().

Juga, jika Anda menuruti tebakan saya, coba nonaktifkan defrag hugepage dengan:

gema 'tidak pernah'> / sys / kernel / mm / transparent_hugepage / defrag

(mungkin ini sebagai gantinya, tergantung pada kernel Anda :)

echo 'never'> / sys / kernel / mm / redhat_transparent_hugepage / defrag

Terakhir, apakah aplikasi ini menggunakan puluhan pertunjukan ram sesuatu yang Anda tulis? Bahasa apa?

Karena Anda menggunakan istilah, "kesalahan dalam halaman memori," Saya kira Anda cukup terbiasa dengan desain operasi dan memori virtual. Saya berjuang untuk membayangkan situasi / aplikasi yang akan menyalahkan begitu agresif sehingga tidak membaca banyak I / O - hampir selalu dari buffer cache yang Anda coba batasi.

(Jika Anda penasaran, lihat mmap (2) flag seperti MAP_ANONYMOUS dan MAP_POPULATE dan mincore (2) yang dapat digunakan untuk melihat halaman virtual mana yang sebenarnya memiliki halaman fisik yang dipetakan.)

Semoga berhasil!

etherfish
sumber
2

Jika Ceph OSD adalah satu proses terpisah, Anda bisa menggunakan cgroup untuk mengontrol sumber daya yang digunakan oleh proses:

Buat cgroup bernama like group1 dengan batas memori (50GB, misalnya, batas lain seperti CPU didukung, misalnya CPU juga disebutkan):

cgcreate -g memory,cpu:group1

cgset -r memory.limit_in_bytes=$((50*1024*1024*1024)) group1

Kemudian, jika aplikasi Anda sudah berjalan, bawa aplikasi ke dalam cgroup ini:

cgclassify -g memory,cpu:group1 $(pidof your_app_name)

Atau jalankan aplikasi Anda dalam cgroup ini:

cgexec -g memory,cpu:group1 your_app_name
Alexei Martianov
sumber
0

tuned adalah daemon tuning sistem adaptif dinamis yang menyetel pengaturan sistem secara dinamis tergantung pada penggunaan.

 $ man tuned

Lihat dokumentasi terkait, dan file konfigurasi.

 /etc/tuned
 /etc/tuned/*.conf
 /usr/share/doc/tuned-2.4.1
 /usr/share/doc/tuned-2.4.1/TIPS.txt

This parameter may be useful for you.

** Set flushing to once per 5 minutes
** echo "3000" > /proc/sys/vm/dirty_writeback_centisecs

Informasi tambahan

The sync perintah flushes buffer, yaitu, kekuatan semua data yang tidak tertulis yang akan ditulis ke disk, dan dapat digunakan ketika seseorang ingin untuk memastikan bahwa semuanya aman ditulis. Dalam sistem UNIX tradisional, ada program yang disebut pembaruan yang berjalan di latar belakang yang melakukan sinkronisasi setiap 30 detik, sehingga biasanya tidak perlu menggunakan sinkronisasi. Linux memiliki daemon tambahan, bdflush , yang melakukan sinkronisasi lebih tidak sempurna lebih sering untuk menghindari pembekuan mendadak karena I / O disk yang berat yang kadang-kadang menyebabkan sinkronisasi .

Di Linux, bdflush dimulai dengan pembaruan. Biasanya tidak ada alasan untuk mengkhawatirkannya, tetapi jika bdflush mati karena suatu alasan, kernel akan memperingatkan tentang hal ini, dan Anda harus memulainya dengan tangan ( / sbin / update ).

Ijaz Ahmad Khan
sumber
1
Bukankah ini hanya untuk entri yang kotor? Saya tidak berpikir itu masalah pada sistem saya karena semuanya bersih - penundaan tidak menulis kembali halaman yang kotor tetapi dalam defragmenting ruang yang tersisa dengan menghapus yang bersih.
Wim
Ya, ini untuk halaman kotor, saya pikir Anda juga dapat memperbaiki masalah kinerja lainnya dengan menyetel disetel ke mode dinamis.
Ijaz Ahmad Khan
"Sejak Linux 2.6, panggilan sistem [bdflush] sudah tidak digunakan lagi dan tidak melakukan apa-apa. Kemungkinan akan hilang sama sekali dalam rilis kernel di masa depan. Saat ini, tugas yang dilakukan oleh bdflush () ditangani oleh thread pdflush kernel." man7.org/linux/man-pages/man2/bdflush.2.html
sourcejedi