- Apa cara tercepat untuk mendapatkan kembali kendali atas sistem Linux yang telah menjadi tidak responsif atau sangat lamban karena bertukar yang berlebihan?
Sudah dijawab di atas dengan Alt-SysRq-F
- Adakah cara yang efektif untuk mencegah swapping terjadi di tempat pertama, misalnya dengan membatasi jumlah memori proses yang diizinkan untuk mencoba mengalokasikan?
Saya menjawab bagian ke-2 ini. Ya, ulimit
masih berfungsi cukup baik untuk membatasi satu proses. Kamu bisa:
- menetapkan batas lunak untuk suatu proses yang Anda tahu kemungkinan akan lepas kendali
- menetapkan batas keras untuk semua proses jika Anda ingin asuransi tambahan
Juga, sebagaimana disebutkan secara singkat:
Anda dapat menggunakan CGroups untuk membatasi penggunaan sumber daya dan mencegah masalah seperti itu
Memang, cgroup menawarkan kontrol yang lebih maju, tetapi saat ini lebih rumit untuk dikonfigurasi menurut pendapat saya.
Ulimit sekolah tua
Sekali off
Inilah contoh sederhana:
$ bash
$ ulimit -S -v $((1*2**20))
$ r2(){r2 $@$@;};r2 r2
bash: xmalloc: .././subst.c:3550: cannot allocate 134217729 bytes (946343936 bytes allocated)
Itu:
- Menetapkan batas lunak penggunaan memori keseluruhan 1GB (ulimit mengasumsikan batas dalam satuan kB)
- Menjalankan panggilan fungsi bash rekursif
r2(){ r2 $@$@;};r2 r2
yang akan secara eksponensial mengunyah CPU dan RAM dengan menggandakan dirinya secara tak terbatas sambil meminta memori tumpukan.
Seperti yang Anda lihat, itu terhenti ketika mencoba untuk meminta lebih dari 1GB.
Catatan, -v
beroperasi pada alokasi memori virtual (total, yaitu fisik + swap).
Perlindungan permanen
Untuk membatasi alokasi memori virtual, as
adalah setara dengan -v
untuk limits.conf
.
Saya melakukan hal berikut untuk melindungi dari proses pelanggaran tunggal:
- Tetapkan batas ruang alamat keras untuk semua proses.
address space limit = <physical memory> - 256MB
.
- Oleh karena itu, tidak ada proses tunggal dengan penggunaan memori serakah atau loop aktif dan kebocoran memori dapat mengkonsumsi SEMUA memori fisik.
- Ruang kepala 256MB ada untuk pemrosesan penting dengan ssh atau konsol.
Satu liner:
$ sudo bash -c "echo -e \"*\thard\tas\t$(($(grep -E 'MemTotal' /proc/meminfo | grep -oP '(?<=\s)\d+(?=\skB$)') - 256*2**10))\" > /etc/security/limits.d/mem.conf"
Untuk memvalidasi, ini menghasilkan yang berikut (misalnya pada sistem 16GB):
$ cat /etc/security/limits.d/mem.conf
* hard as 16135196
$ ulimit -H -v
161351960
Catatan:
- Hanya memitigasi terhadap satu proses tunggal yang berlebihan dengan penggunaan memori.
- Tidak akan mencegah beban kerja multi-proses dengan tekanan memori yang besar yang menyebabkan meronta-ronta (cgroup kemudian jawabannya).
- Jangan gunakan
rss
opsi dalam membatasi.conf. Ini tidak dihormati oleh kernel yang lebih baru.
- Itu konservatif.
- Secara teori, suatu proses dapat secara spekulatif meminta banyak memori tetapi hanya secara aktif menggunakan subset (set kerja yang lebih kecil / penggunaan memori penduduk).
- Batas keras di atas akan menyebabkan proses tersebut dibatalkan (bahkan jika mereka mungkin telah berjalan dengan baik mengingat Linux memungkinkan ruang alamat memori virtual menjadi terlalu padat).
CGroup yang lebih baru
Menawarkan lebih banyak kontrol, tetapi saat ini lebih kompleks untuk digunakan:
- Memperbaiki penawaran ulimit.
memory.max_usage_in_bytes
dapat menghitung dan membatasi memori fisik secara terpisah.
- Sedangkan
ulimit -m
dan / atau rss
dalam limits.conf
dimaksudkan untuk menawarkan fungsionalitas yang serupa, tetapi itu tidak berfungsi sejak kernel Linux 2.4.30!
- Perlu mengaktifkan beberapa bendera kernel cgroup di bootloader:
cgroup_enable=memory swapaccount=1
.
- Ini tidak terjadi secara default dengan Ubuntu 16.04.
- Mungkin karena beberapa implikasi kinerja overhead akuntansi tambahan.
- hal-hal cgroup / systemd relatif baru dan mengubah sedikit, sehingga fluks hulu menyiratkan vendor distro Linux belum membuatnya mudah digunakan. Antara 14.04LTS dan 16.04LTS, tooling ruang pengguna untuk menggunakan cgroup telah berubah.
cgm
sekarang tampaknya menjadi alat userspace yang didukung secara resmi.
- file unit systemd tampaknya belum memiliki standar "vendor / distro" yang telah ditentukan sebelumnya untuk memprioritaskan layanan penting seperti ssh.
Misalnya untuk memeriksa pengaturan saat ini:
$ echo $(($(cat /sys/fs/cgroup/memory/memory.max_usage_in_bytes) / 2**20)) MB
11389 MB
$ cat /sys/fs/cgroup/memory/memory.stat
...
Misalnya untuk membatasi memori satu proses:
$ cgm create memory mem_1G
$ cgm setvalue memory mem_1G memory.limit_in_bytes $((1*2**30))
$ cgm setvalue memory mem_1G memory.memsw.limit_in_bytes $((1*2**30))
$ bash
$ cgm movepid memory mem_1G $$
$ r2(){ r2 $@$@;};r2 r2
Killed
Untuk melihatnya beraksi mengunyah RAM sebagai proses latar belakang dan kemudian terbunuh:
$ bash -c 'cgm movepid memory mem_1G $$; r2(){ r2 $@$@;};r2 r2' & while [ -e /proc/$! ]; do ps -p $! -o pcpu,pmem,rss h; sleep 1; done
[1] 3201
0.0 0.0 2876
102 0.2 44056
103 0.5 85024
103 1.0 166944
...
98.9 5.6 920552
99.1 4.3 718196
[1]+ Killed bash -c 'cgm movepid memory mem_1G $$; r2(){ r2 $@$@;};r2 r2'
Perhatikan pertumbuhan permintaan memori yang eksponensial (kekuatan 2).
Di masa depan, mari kita berharap untuk melihat "distro / vendor" pra-konfigurasi prioritas dan batasan cgroup (melalui unit systemd) untuk hal-hal penting seperti SSH dan tumpukan grafis, sehingga mereka tidak pernah kehabisan memori.