Server web VPS saya berjalan pada CentOS 5.4 (kernel Linux 2.6.16.33-xenU) secara tidak teratur (seperti sebulan sekali memberi atau mengambil beberapa minggu) menjadi tidak responsif karena menendang oom-killer. Pemantauan server menunjukkan bahwa itu tidak biasanya kehabisan memori, hanya sesekali.
Saya telah membaca beberapa blog yang mengarah ke halaman ini yang membahas konfigurasi kernel untuk mengelola overcommit dengan lebih baik menggunakan pengaturan sysctl berikut:
vm.overcommit_memory = 2
vm.overcommit_ratio = 80
Pemahaman saya tentang ini (yang mungkin salah, tetapi saya tidak dapat menemukan definisi kanonik untuk menjelaskan) adalah bahwa ini mencegah memori alokasi-kernel lebih dari swap + 80% dari memori fisik.
Namun, saya juga telah membaca beberapa sumber lain yang menyarankan bahwa pengaturan ini bukan ide yang baik - meskipun kritik dari pendekatan ini tampaknya mengatakan "jangan melakukan hal-hal yang merusak sistem Anda, daripada mencoba kludge ini" dengan asumsi bahwa sebab-akibat selalu diketahui.
Jadi pertanyaan saya adalah, apa pro dan kontra dari pendekatan ini , dalam konteks server web Apache2 hosting sekitar 10 situs lalu lintas rendah? Dalam kasus khusus saya, server web memiliki RAM 512Mb, dengan ruang swap 1024Mb. Ini tampaknya cukup untuk sebagian besar waktu.
/proc/<PID>/oom_score_adj
untuk tujuan ini. Misalnya, jika Anda menetapkan oom_score_adj ke -1000 untuk sshd, pembunuh oom tidak akan pernah menargetkan sshd ketika ingin membunuh sesuatu. Menghentikan pembunuh total sama sekali bukan ide yang baik karena program Anda tidak akan dapat menyimpan memori, dan mereka akan tetap mati.Bagian 9.6 "Komitmen berlebihan dan OOM" dalam dokumen yang menyebutkan @dunxd secara khusus menggambarkan bahaya dari mengizinkan komitmen berlebihan. Namun, itu
80
tampak menarik bagi saya juga, jadi saya melakukan beberapa tes.Apa yang saya temukan adalah bahwa
overcommit_ratio
mempengaruhi total RAM yang tersedia untuk SEMUA proses. Proses root tampaknya tidak diperlakukan berbeda dari proses pengguna normal.Mengatur rasio ke
100
atau kurang harus memberikan semantik klasik di mana nilai kembali darimalloc/sbrk
dapat diandalkan. Pengaturan rasio lebih rendah daripada100
mungkin cara untuk memesan lebih banyak RAM untuk kegiatan non-proses seperti caching dan sebagainya.Jadi, di komputer saya dengan 24 GiB RAM, dengan swap dinonaktifkan, 9 GiB digunakan, dengan
top
ditampilkanBerikut adalah beberapa
overcommit_ratio
pengaturan dan berapa banyak RAM yang bisa diambil oleh program ram-konsumen saya (menyentuh setiap halaman) - dalam setiap kasus program keluar dengan bersih begitumalloc
gagal.Menjalankan beberapa sekaligus, bahkan dengan beberapa sebagai pengguna root, tidak mengubah jumlah total yang mereka konsumsi bersama. Sangat menarik bahwa itu tidak dapat mengkonsumsi 3+ GiB terakhir atau lebih; yang
free
tidak menjatuhkan jauh di bawah apa yang ditampilkan di sini:Eksperimen itu berantakan - apa pun yang menggunakan malloc pada saat ini semua RAM yang digunakan cenderung macet, karena banyak programmer yang mengerikan untuk memeriksa kegagalan malloc di C, beberapa perpustakaan koleksi populer mengabaikannya sepenuhnya, dan C ++ dan berbagai bahasa lainnya bahkan lebih buruk.
Sebagian besar implementasi awal RAM imajiner yang saya lihat adalah untuk menangani kasus yang sangat spesifik, di mana satu proses besar - katakanlah 51% + memori yang tersedia - diperlukan
fork()
untukexec()
beberapa program pendukung, biasanya yang jauh, jauh lebih kecil. OS dengan semantik copy-on-write akan memungkinkanfork()
, tetapi dengan ketentuan bahwa jika proses bercabang benar-benar mencoba untuk memodifikasi terlalu banyak halaman memori (masing-masing kemudian harus dipakai sebagai halaman baru yang independen dari proses besar awal) itu akan berakhir terbunuh. Proses induk hanya dalam bahaya jika mengalokasikan lebih banyak memori, dan dapat menangani kehabisan, dalam beberapa kasus hanya dengan menunggu sedikit proses lain mati, dan kemudian melanjutkan. Proses anak biasanya hanya mengganti sendiri dengan program (biasanya lebih kecil) viaexec()
dan kemudian bebas dari ketentuan.Konsep overcommit Linux adalah pendekatan ekstrem untuk memungkinkan
fork()
terjadinya dan juga proses tunggal secara keseluruhan. Kematian OOM-pembunuh-disebabkan terjadi asynchronous, bahkan untuk program yang melakukan alokasi memori menangani secara bertanggung jawab. Saya pribadi benci overcommit seluruh sistem secara umum dan oom-killer pada khususnya - itu mendorong pendekatan setan-hati untuk manajemen memori yang menginfeksi perpustakaan dan melalui mereka setiap aplikasi yang menggunakannya.Saya sarankan untuk mengatur rasio ke 100, dan memiliki partisi swap juga yang umumnya hanya akan berakhir digunakan oleh proses besar - yang sering hanya menggunakan sebagian kecil dari bagian diri mereka yang dimasukkan ke dalam swap, dan dengan demikian melindungi sebagian besar proses dari kesalahan pembunuh OOM. Ini harus menjaga server web Anda aman dari kematian acak, dan jika itu ditulis untuk menangani secara
malloc
bertanggung jawab, bahkan aman dari membunuh sendiri (tetapi jangan bertaruh pada yang terakhir).Itu berarti saya menggunakan ini
/etc/sysctl.d/10-no-overcommit.conf
sumber