Bagaimana cara menggunakan ruang swap hanya untuk keadaan darurat?

41

Saya memiliki laptop Debian (Buster) dengan 8 GB RAM dan 16GB swap. Saya menjalankan tugas yang berjalan sangat lama. Ini berarti laptop saya telah dibiarkan selama enam hari terakhir sementara itu terus berputar.

Saat melakukan ini, saya secara berkala perlu menggunakan laptop saya sebagai laptop. Ini seharusnya tidak menjadi masalah; tugas jangka panjangnya adalah I / O terikat, mengerjakan hal-hal pada hard disk USB dan tidak memakan banyak RAM (<200 MB) atau CPU (<4%).

Masalahnya adalah ketika saya kembali ke laptop saya setelah beberapa jam, itu akan sangat lambat dan bisa memakan waktu 30 menit untuk kembali normal. Ini sangat buruk sehingga crash-monitor menandai aplikasi mereka masing-masing telah dibekukan (terutama jendela browser) dan semuanya mulai salah crash.

Melihat pada monitor sistem, dari 2,5 GB yang digunakan sekitar setengah akan dialihkan ke swap. Saya telah mengkonfirmasi ini adalah masalahnya dengan menghapus ruang swap ( swapoff /dev/sda8). Jika saya meninggalkannya tanpa ruang swap, ia hidup kembali hampir secara instan bahkan setelah 24 jam. Dengan swap, bisa dibilang batu bata selama lima menit pertama hanya tersisa enam jam. Saya telah mengkonfirmasi bahwa penggunaan memori tidak pernah melebihi 3 GB bahkan saat saya pergi.

Saya telah mencoba mengurangi swappiness ( lihat juga: Wikipedia ) menjadi nilai-nilai 10dan 0, tetapi masalahnya masih berlanjut. Tampaknya setelah satu hari tidak aktif kernel percaya seluruh GUI tidak lagi diperlukan dan menghapusnya dari RAM (menukar ke disk). Tugas jangka panjang adalah membaca melalui pohon file yang luas dan membaca setiap file. Jadi mungkin kernel bingung dengan berpikir bahwa caching akan membantu. Tetapi pada satu sapuan USB HD 2 TB dengan ~ 1 miliar nama file, RAM GB tambahan tidak akan banyak membantu kinerja. Ini adalah laptop murah dengan hard drive yang lambat. Ini tidak bisa memuat data kembali ke RAM dengan cukup cepat.

Bagaimana saya bisa memberitahu Linux untuk hanya menggunakan ruang swap dalam keadaan darurat? Saya tidak ingin menjalankan tanpa swap. Jika sesuatu yang tidak terduga terjadi, dan OS tiba-tiba membutuhkan beberapa GB tambahan maka saya tidak ingin tugas terbunuh dan lebih suka mulai menggunakan swap. Tetapi saat ini, jika saya membiarkan swap diaktifkan, laptop saya tidak dapat digunakan saat saya membutuhkannya.

Definisi tepat dari "darurat" mungkin menjadi masalah untuk diperdebatkan. Tetapi untuk memperjelas apa yang saya maksud: Keadaan darurat akan berada di tempat sistem dibiarkan tanpa opsi lain selain menukar atau mematikan proses.


Apa itu darurat? - Apakah Anda benar-benar harus bertanya? ... Saya harap Anda tidak pernah menemukan diri Anda di gedung yang terbakar!

Tidak mungkin bagi saya untuk mendefinisikan segala sesuatu yang mungkin merupakan keadaan darurat dalam pertanyaan ini. Tapi misalnya, keadaan darurat mungkin ketika kernel sangat didorong untuk memori yang telah mulai membunuh proses dengan Pembunuh OOM . Suatu keadaan darurat BUKAN ketika kernel berpikir itu dapat meningkatkan kinerja dengan menggunakan swap.


Sunting Akhir: Saya telah menerima jawaban yang sesuai dengan apa yang saya minta di tingkat sistem operasi. Pembaca masa depan juga harus mencatat jawaban yang menawarkan solusi tingkat aplikasi.

Philip Couling
sumber
11
Tentukan "darurat" dan katakan sesuatu tentang bagaimana ini berbeda dari situasi biasa ketika swap akan digunakan.
Kusalananda
4
Saya ingin tahu apakah Anda ingin mendefinisikan tipe khusus "kejadian darurat" di luar batas yang akan memungkinkan kernel untuk menggunakan swap, tetapi swap itu kalau tidak tidak akan digunakan. AFAIK mengeluarkan memori adalah sesuatu yang lambat dan hanya pernah dilakukan "dalam keadaan darurat", dan "swappiness" adalah satu-satunya hal yang dapat Anda gunakan untuk menyesuaikan perilaku ini dengan (tapi saya bukan pengguna Linux).
Kusalananda
2
Tidak itu tidak benar. Ini tidak hanya dilakukan dalam keadaan darurat. Paling tidak saya pikir pertanyaan saya membuatnya jelas saya hanya menggunakan 3GB dari 8GB ... Itu bukan keadaan darurat tapi kernelnya tetap bertukar. Saya sarankan Anda membaca tentang topik swappiness dan sekitarnya. Ada sedikit diskusi tentang berbagai alasan untuk bertukar. Masuk akal saya meminta konsep yang tidak ada di kernel, tetapi alasan saya untuk memintanya cukup masuk akal ..
Philip Couling
4
Saya mengenali saran selalu "tidak pernah berjalan tanpa swap". Tetapi ukuran memori telah keluar dari kecepatan baca / tulis hard drive (HDD bukan SSD) yang berarti bahwa swap semakin merupakan ide yang buruk. Rasanya seperti ada yang percaya 8GB RAM + 8GB swap akan keluar melakukan 16GB RAM + 0 swap. Jika memang benar maka ada sesuatu yang sangat salah dengan kernel Linux.
Philip Couling
7
@ Pilip Couling: Tidak, intinya adalah bahwa 16 GB RAM + 16 GB swap akan mengungguli 16 GB dan 0 swap - terutama ketika kode Anda membutuhkan 17 GB memori :-)
jamesqf

Jawaban:

11

Memiliki pertukaran yang sangat besar saat ini seringkali merupakan ide yang buruk. Pada saat OS bertukar hanya beberapa GB memori untuk bertukar, sistem Anda sudah merangkak mati (seperti apa yang Anda lihat)

Lebih baik digunakan zramdengan partisi swap cadangan kecil . Banyak OS seperti ChromeOS, Android dan berbagai distro Linux telah mengaktifkan zram secara default selama bertahun-tahun, terutama untuk sistem dengan RAM lebih sedikit. Ini jauh lebih cepat daripada menukar HDD dan Anda dapat dengan jelas merasakan respons sistem dalam hal ini. Kurang begitu pada SSD, tetapi menurut hasil benchmark di sini masih tampak lebih cepat bahkan dengan algoritma lzo default. Anda dapat mengubah ke lz4 untuk kinerja yang lebih baik dengan rasio kompresi yang sedikit lebih sedikit. Kecepatan decoding-nya hampir 5 kali lebih cepat daripada lzo berdasarkan tolok ukur resmi

Ada juga zswapmeskipun saya belum pernah menggunakannya. Mungkin patut dicoba dan bandingkan mana yang lebih baik untuk usecases Anda

Setelah itu saran lain adalah untuk mengurangi prioritas proses yang terikat IO dan mungkin meninggalkan terminal berjalan pada prioritas yang lebih tinggi sehingga Anda dapat menjalankan perintah di atasnya segera bahkan ketika sistem berada pada beban tinggi

Bacaan lebih lanjut

phuclv
sumber
Hanya agar saya mengerti, Anda mengatakan bahwa saya dapat membuat zramperangkat blok, menggunakannya sebagai swap, dengan swap prioritas yang lebih rendah sebagai partisi HDD?
Philip Couling
@ PhilipCouling jika Anda menggunakan HDD maka ya, pasti Anda harus menggunakan zram atau solusi serupa. Prioritas swap harus lebih rendah dari zram, sehingga Linux mencoba menggunakan zram terlebih dahulu, dan kemudian akan mempertimbangkan swap. Jika Anda menggunakan Ubuntu maka paket zram-config sudah menangani pengaturan prioritas untuk Anda
phuclv
3
Saya menerima jawaban ini karena tampaknya melakukan persis apa yang saya minta. Jika saya masih memiliki 16GB swap saya diaktifkan pada prioritas yang dikurangi, maka kernel hanya akan menggunakannya ketika zswap telah habis. IE: "dalam keadaan darurat". Catatan pada debian-buster ini sangat mudah untuk diatur, cukup dengan menginstal zram-tools.
Philip Couling
25

Salah satu perbaikannya adalah untuk memastikan pengontrol cgroup memori diaktifkan (saya pikir itu secara default di kernel bahkan setengah baru-baru ini, jika tidak Anda akan perlu menambahkan cgroup_enable=memoryke baris perintah kernel). Kemudian, Anda dapat menjalankan tugas intensif I / O dalam grup dengan batas memori, yang juga membatasi jumlah cache yang dapat dikonsumsi.

Jika Anda menggunakan systemd, Anda dapat mengatur +MemoryAccounting=yesdan salah satu MemoryHigh/ MemoryMaxatau MemoryLimit(tergantung pada jika Anda menggunakan cgroup v1 atau v2) di unit, atau irisan yang mengandungnya. Jika ini adalah slice, Anda dapat menggunakan systemd-rununtuk menjalankan program di slice.

Contoh lengkap dari salah satu sistem saya untuk menjalankan Firefox dengan batas memori. Catatan ini menggunakan cgroups v2 dan diatur sebagai pengguna saya, bukan root (salah satu kelebihan v2 daripada v1 adalah bahwa mendelegasikan ini ke non-root aman, jadi systemd melakukannya).

$ systemctl --user cat mozilla.slice 
# /home/anthony/.config/systemd/user/mozilla.slice
[Unit]
Description=Slice for Mozilla apps
Before=slices.target

[Slice]
MemoryAccounting=yes
MemoryHigh=5G
MemoryMax=6G

$ systemd-run --user --slice mozilla.slice --scope -- /usr/bin/firefox &
$ systemd-run --user --slice mozilla.slice --scope -- /usr/bin/thunderbird &

Saya menemukan untuk mendapatkan pengguna yang berfungsi saya harus menggunakan slice. Sistem satu berfungsi hanya dengan meletakkan opsi di file layanan (atau menggunakan systemctl set-propertypada layanan).

Berikut ini adalah contoh layanan (menggunakan cgroup v1), perhatikan dua baris terakhir. Ini adalah bagian dari instance sistem (pid = 1).

[Unit]
Description=mount S3QL filesystem
Requires=network-online.target
After=network-online.target

[Install]
WantedBy=multi-user.target

[Service]
Type=forking
User=s3ql-user
Group=s3ql-user
LimitNOFILE=20000
ExecStartPre=+/bin/sh -c 'printf "S3QL_CACHE_SIZE=%%i\n" $(stat -c "%%a*%%S*.90/1024" -f /srv/s3ql-cache/ | bc) > /run/local-s3ql-env'
ExecStartPre=/usr/bin/fsck.s3ql  --cachedir /srv/s3ql-cache/fs1 --authfile /etc/s3ql-authinfo  --log none «REDACTED»
EnvironmentFile=-/run/local-s3ql-env
ExecStart=/usr/bin/mount.s3ql --keep-cache --cachedir /srv/s3ql-cache/fs1 --authfile /etc/s3ql-authinfo --cachesize ${S3QL_CACHE_SIZE} --threads 4
ExecStop=/usr/bin/umount.s3ql /mnt/S3QL/
TimeoutStopSec=2m
MemoryAccounting=yes
MemoryLimit=1G

Dokumentasi dalam systemd.resource-control(5).

derobert
sumber
1
Tidak bisakah Anda melakukan sesuatu yang sebanding dan portabel hanya dengan menggunakan ulimit?
Old Pro
1
@ OldPro tidak juga. Pertama, tidak ada AFAIK ulimit pada total penggunaan memori termasuk cache halaman (yang merupakan penggunaan yang menjadi berlebihan di sini). Kedua, ulimit untuk memori adalah per-proses, cgroups bekerja bahkan jika fork yang sudah berjalan lama bercabang.
derobert
Saya pikir alasan akuntansi memori diaktifkan secara default pada sistem yang lebih baru adalah karena perubahan dalam systemdversi 238 .
sourcejedi
1
@sourcejedi itu relatif baru. Ketika memory controller pertama kali diperkenalkan, hanya dengan menyediakannya (bahkan tidak digunakan) memiliki biaya kinerja yang cukup besar sehingga beberapa distro setidaknya menonaktifkannya secara default dan Anda harus melewati argumen baris perintah kernel untuk mengaktifkannya. Masalah kinerja diperbaiki, sehingga berubah, dan baru-baru ini systemd mengaktifkannya juga secara default.
derobert
14

Tampaknya setelah satu hari tidak aktif kernel percaya seluruh GUI tidak lagi diperlukan dan menghapusnya dari RAM (menukar ke disk).

Kernel melakukan The Right Thing ™ memercayainya. Mengapa ia menyimpan 1 memori yang tidak terpakai dalam RAM dan karenanya membuangnya alih-alih menggunakannya sebagai cache atau sesuatu?

Saya tidak berpikir kernel Linux adalah gratifikasi atau antisipasi mengganti halaman, jadi jika itu yang dilakukan adalah untuk menyimpan sesuatu yang lain di RAM, sehingga meningkatkan kinerja tugas Anda yang berjalan lama, atau setidaknya dengan tujuan ini.

Jika Anda tahu kapan Anda harus menggunakan kembali laptop Anda di muka, Anda dapat menggunakan atperintah (atau crontab) untuk menjadwalkan pembersihan swap ( swapoff -a;swapon -a).

Karena membersihkan swap mungkin berlebihan, dan bahkan memicu pembunuh OOM jika karena alasan tertentu, tidak semuanya cocok dengan RAM, Anda mungkin hanya "membuka" 2 semua yang terkait dengan aplikasi yang sedang berjalan yang ingin Anda hidupkan kembali.

Salah satu cara untuk melakukannya adalah dengan melampirkan debugger seperti gdbke setiap proses yang terpengaruh dan memicu pembuatan dump inti:

# gdb -p <pid>
...
generate-core-dump /dev/null
...
quit

Saat Anda menulis, aplikasi jangka panjang Anda tidak menggunakan kembali data yang dibacanya setelah lulus awal, jadi Anda berada dalam kasus tertentu di mana caching jangka panjang tidak berguna. Maka melewati cache dengan menggunakan I / O langsung seperti yang disarankan oleh Will Crawford harus menjadi solusi yang baik.

Sebagai alternatif, Anda mungkin hanya perlu membersihkan cache file dengan menggema 1atau 3ke file /proc/sys/vm/drop_cachessemu sebelum OS berpikir itu ide yang baik untuk menukar aplikasi dan lingkungan GUI Anda.

Lihat Bagaimana Anda mengosongkan buffer dan cache pada sistem Linux? untuk detail.

1 Tidak digunakan dalam arti: tidak lagi digunakan secara aktif sejak periode waktu yang signifikan, memori masih relevan bagi pemiliknya.
2 Masukkan kembali halaman RAM yang disimpan di area swap.

Jlliagre
sumber
2
Terima kasih atas pemikiran tentang kemungkinan penyebabnya. Saya telah menambahkan sedikit pertanyaan karena mungkin relevan. Saya bertanya-tanya apakah ada cara untuk menurunkan prioritas caching terhadap memori aplikasi sendiri.
Philip Couling
5
"Saya tidak berpikir kernel Linux adalah gratifikasi atau antisipasi mengganti halaman jadi jika itu melakukannya, itu harus menyimpan sesuatu yang lain pada RAM, sehingga meningkatkan kinerja." - Saya pikir kata-kata ini agak ambigu. Kernel pasti akan menulis halaman untuk ditukar, kapan pun ada kesempatan (mis. Ada sedikit I / O disk). Namun, itu tidak akan menghapusnya dari RAM. Dengan begitu, Anda memiliki yang terbaik dari kedua dunia: jika Anda dengan cepat membutuhkan halaman itu lagi, mereka sudah ada di RAM, dan tidak ada yang bisa dilakukan. Jika keadaan darurat (seperti kata OP) muncul, Anda hanya perlu membebaskan halaman-halaman dalam RAM, karena
Jörg W Mittag
3
... mereka sudah dalam swap. Dan itulah tepatnya mengapa Anda tidak ingin menggunakan swap "hanya dalam keadaan darurat", karena selama keadaan darurat, sistem sudah dalam tekanan dan hal terakhir yang Anda inginkan adalah menambahkan sejumlah besar disk I / O ke sana.
Jörg W Mittag
2
Hal yang menyebabkannya untuk ditukar kemungkinan adalah proses yang berjalan lama: mengakses file pada disk. File-file dalam memori akan lebih baru digunakan daripada memori GUI.
jpmc26
3
@ JörgWMittag Apakah Anda memiliki bukti kernel Linux, ketika penggunaan I / O rendah, terlebih dahulu menulis halaman ke area swap "berjaga-jaga", yaitu tanpa membebaskan mereka dari RAM?
jlliagre
10

Apakah proses Anda menjalankan sesuatu yang Anda buat sendiri?

Jika demikian, mungkin perlu mengubah kode Anda untuk membuka file menggunakan O_DIRECTflag, yang mengutip halaman manual -

Cobalah untuk meminimalkan efek cache I / O ke dan dari file ini. Secara umum ini akan menurunkan kinerja, tetapi berguna dalam situasi khusus, seperti ketika aplikasi melakukan caching mereka sendiri. File I / O dilakukan langsung ke / dari buffer ruang pengguna. Bendera O_DIRECT sendiri berupaya untuk mentransfer data secara serempak, tetapi tidak memberikan jaminan bendera O_SYNC bahwa data dan metadata yang diperlukan ditransfer. Untuk menjamin I / O sinkron, O_SYNC harus digunakan selain O_DIRECT. Lihat CATATAN di bawah untuk diskusi lebih lanjut.

Will Crawford
sumber
1
Lain yang serupa (tapi mungkin lebih mudah, karena saya cukup yakin O_DIRECT memiliki batasan penyelarasan dan Anda akan mematikan kinerja jika bacaan Anda tidak besar) disarankan untuk memberitahu kernel Anda tidak akan memerlukan data itu lagi, menyiramnya dari cache halaman. (di telepon atau akan memberikan tautan, maaf)
derobert
1
@derobert Pertama, nocacheperintahnya adalah peretasan yang nyaman untuk melakukan ini. (Menggunakan LD_PRELOAD untuk membajak beberapa panggilan libc).
sourcejedi
6

Inilah ide, yang belum saya coba sendiri (dan saya minta maaf saya tidak punya waktu sekarang untuk bereksperimen dengan ini).

Misalkan Anda membuat VM kecil dengan hanya memori 512MB untuk proses latar belakang Anda, saya tidak yakin apakah Anda ingin ini memiliki swap, panggilan Anda, dan matikan swap pada sistem host Anda.

X Tian
sumber
3

Hapus swap atau kurangi sekitar 20% ( dapat bervariasi dengan sistem ) karena baru-baru ini OS tidak menggunakan swap lagi dengan cara yang sama seperti yang mereka lakukan dalam beberapa tahun yang lalu. Mungkin menjawab beberapa pertanyaan Anda:

-> redhat.com resmi

beberapa info Red Hat di bawah,

Di masa lalu, beberapa vendor aplikasi merekomendasikan swap dengan ukuran yang sama dengan RAM, atau bahkan dua kali RAM. Sekarang mari kita bayangkan sistem yang disebutkan di atas dengan 2GB RAM dan 2GB swap. Database pada sistem secara tidak sengaja dikonfigurasi untuk sistem dengan 5GB RAM. Setelah memori fisik habis, swap akan digunakan. Karena swap disk jauh lebih lambat daripada RAM, kinerjanya turun, dan terjadi thrashing. Pada titik ini, bahkan masuk ke sistem mungkin menjadi tidak mungkin. Ketika semakin banyak memori yang ditulis, akhirnya kedua memori fisik dan swap benar-benar habis dan pembunuh OOM menendang, membunuh satu atau lebih proses. Dalam kasus kami, cukup banyak swap tersedia, sehingga waktu kinerja yang buruk lama.

dan

https://wiki.debian.org/Swap

bagian dari tautan Debian di atas,

Informasi dan pertimbangan terkait dengan jumlah swap yang digunakan:

"Jumlah ruang swap yang disarankan secara tradisional adalah dua kali lipat jumlah memori sistem. Ini telah berubah dari waktu ke waktu menjadi satu setengah kali memori sistem, kedua jawaban itu merupakan data dasar yang layak tetapi menjadi jawaban yang kurang bermanfaat untuk pertanyaan seiring berjalannya waktu. Ada banyak variabel tentang sistem Anda dan penggunaan yang dimaksudkan yang akan menentukan pertukaran sistem yang tersedia yang ingin Anda miliki. "

Anda dapat mencoba:

"Cara terbaik untuk menonaktifkan swap di linux"


Catatan pribadi:


Karena saya sudah 6 GB RAM dan di semua OS Linux saya baru-baru ini. Saya belum pernah melihat indikasi penggunaan Swap. Saya menentukannya, saya harus mematikannya baik untuk ruang (beberapa gigabyte lebih) dan karena itu kadang-kadang memperlambat sistem saya.

Tyþë-Ø
sumber
1
Di masa lalu, beberapa vendor aplikasi merekomendasikan swap dengan ukuran yang sama dengan RAM, atau bahkan dua kali RAM. Saya merasa jauh lebih tua melihat itu, entah bagaimana ... Meskipun saya masih memiliki salah satu HDD di penghalang ~ 528MB dan juga 2,5GB, entah bagaimana kutipan itu - yah itu sesuatu dari dulu sekali ... Kutipan yang menarik dan mungkin menjelaskan mengapa saya melihat masalah serupa beberapa tahun yang lalu. Saya percaya saya menggunakan sysctl untuk memperbaikinya tetapi saya tidak ingat persis apa pengaturannya jika itu sudah malam.
Pryftan