Saya tidak khawatir tentang penggunaan RAM (karena saya sudah cukup) atau tentang kehilangan data jika terjadi shutdown yang tidak disengaja (karena daya saya didukung, sistem dapat diandalkan dan data tidak kritis). Tetapi saya melakukan banyak pemrosesan file dan dapat menggunakan beberapa peningkatan kinerja.
Itu sebabnya saya ingin mengatur sistem untuk menggunakan lebih banyak RAM untuk sistem file membaca dan menulis caching, untuk mengambil file secara agresif (mis. baca-depan sebagian besar sebaliknya) dan untuk menyiram buffer penulisan lebih jarang. Bagaimana mencapai ini (mungkin)?
Saya menggunakan sistem file ext3 dan ntfs (saya banyak menggunakan ntfs!) dengan XUbuntu 11.10 x86.
Jawaban yang Diterima:
Meningkatkan kinerja cache disk secara umum lebih dari sekadar meningkatkan ukuran cache sistem file kecuali keseluruhan sistem cocok dengan RAM dalam hal ini Anda harus menggunakan drive RAM (tmpfs
bagus karena memungkinkan jatuh kembali ke disk jika Anda memerlukan RAM dalam beberapa kasus) untuk penyimpanan runtime (dan mungkin skrip initrd untuk menyalin sistem dari penyimpanan ke drive RAM saat startup).
Anda tidak memberi tahu apakah perangkat penyimpanan Anda adalah SSD atau HDD. Inilah yang saya temukan bekerja untuk saya (dalam kasus saya sda
adalah HDD yang dipasang di /home
dan sdb
apakah SSD dipasang di /
).
Pertama, optimalkan bagian load-stuff-from-storage-to-cache:
Inilah pengaturan saya untuk HDD (pastikan AHCI+NCQ diaktifkan di BIOS jika Anda memiliki matikan):
echo cfq > /sys/block/sda/queue/scheduler
echo 10000 > /sys/block/sda/queue/iosched/fifo_expire_async
echo 250 > /sys/block/sda/queue/iosched/fifo_expire_sync
echo 80 > /sys/block/sda/queue/iosched/slice_async
echo 1 > /sys/block/sda/queue/iosched/low_latency
echo 6 > /sys/block/sda/queue/iosched/quantum
echo 5 > /sys/block/sda/queue/iosched/slice_async_rq
echo 3 > /sys/block/sda/queue/iosched/slice_idle
echo 100 > /sys/block/sda/queue/iosched/slice_sync
hdparm -q -M 254 /dev/sda
Perlu diperhatikan untuk kasus HDD tinggi fifo_expire_async
(biasanya menulis) dan slice_sync
yang panjang untuk memungkinkan satu proses mendapatkan throughput tinggi (set slice_sync
ke angka yang lebih rendah jika Anda menekan situasi di mana banyak proses menunggu beberapa data dari disk secara paralel). slice_idle
selalu merupakan kompromi untuk HDD tetapi mengaturnya di suatu tempat dalam kisaran 3-20 harus baik-baik saja tergantung pada penggunaan disk dan firmware disk. Saya lebih suka menargetkan nilai rendah tetapi mengaturnya terlalu rendah akan menghancurkan throughput Anda. quantum
pengaturan tampaknya banyak mempengaruhi throughput tetapi cobalah untuk menjaga ini serendah mungkin untuk menjaga latensi pada tingkat yang masuk akal. Menyetel quantum
terlalu rendah akan merusak throughput. Nilai dalam kisaran 3-8 tampaknya bekerja dengan baik dengan HDD. Latensi kasus terburuk untuk pembacaan adalah (quantum
* slice_sync
) + (slice_async_rq
* slice_async
) ms jika saya telah memahami perilaku kernel dengan benar. Async sebagian besar digunakan oleh penulisan dan karena Anda ingin menunda penulisan ke disk, atur keduanya slice_async_rq
dan slice_async
ke angka yang sangat rendah. Namun, menyetel slice_async_rq
nilai yang terlalu rendah dapat menghentikan pembacaan karena penulisan tidak dapat ditunda setelah pembacaan lagi. Konfigurasi saya akan mencoba untuk menulis data ke disk paling banyak setelah 10 detik setelah data dikirimkan ke kernel tetapi karena Anda dapat mentolerir hilangnya data saat kehilangan daya, atur juga fifo_expire_async
ke 3600000
untuk mengatakan bahwa 1 jam tidak apa-apa untuk penundaan ke disk. Simpan saja slice_async
rendah, karena jika tidak, Anda bisa mendapatkan latensi baca yang tinggi.
hdparm
perintah diperlukan untuk mencegah AAM mematikan sebagian besar kinerja yang diizinkan AHCI+NCQ. Jika disk Anda terlalu berisik, lewati ini.
Inilah pengaturan saya untuk SSD (seri Intel 320):
echo cfq > /sys/block/sdb/queue/scheduler
echo 1 > /sys/block/sdb/queue/iosched/back_seek_penalty
echo 10000 > /sys/block/sdb/queue/iosched/fifo_expire_async
echo 20 > /sys/block/sdb/queue/iosched/fifo_expire_sync
echo 1 > /sys/block/sdb/queue/iosched/low_latency
echo 6 > /sys/block/sdb/queue/iosched/quantum
echo 2 > /sys/block/sdb/queue/iosched/slice_async
echo 10 > /sys/block/sdb/queue/iosched/slice_async_rq
echo 1 > /sys/block/sdb/queue/iosched/slice_idle
echo 20 > /sys/block/sdb/queue/iosched/slice_sync
Di sini perlu diperhatikan nilai rendah untuk pengaturan irisan yang berbeda. Pengaturan paling penting untuk SSD adalah slice_idle
yang harus diatur ke 0-1. Menyetelnya ke nol memindahkan semua keputusan pemesanan ke NCQ asli sementara menyetelnya ke 1 memungkinkan kernel untuk memesan permintaan (tetapi jika NCQ aktif, perangkat keras mungkin mengesampingkan pemesanan kernel sebagian). Uji kedua nilai untuk melihat apakah Anda dapat melihat perbedaannya. Untuk seri Intel 320, tampaknya pengaturan slide_idle
ke memberikan throughput terbaik tetapi menyetelnya ke
1
memberikan latensi keseluruhan terbaik (terendah).
Untuk informasi lebih lanjut tentang merdu ini, lihat https://www.kernel.org/doc/Documentation/block/cfq-iosched.txt .
Pembaruan di tahun 2020 dan kernel versi 5.3 (cfq sudah mati):
modprobe bfq
for d in /sys/block/sd?
do
# HDD (tuned for Seagate SMR drive)
echo bfq > "$d/queue/scheduler"
echo 4 > "$d/queue/nr_requests"
echo 32000 > "$d/queue/iosched/back_seek_max"
echo 3 > "$d/queue/iosched/back_seek_penalty"
echo 80 > "$d/queue/iosched/fifo_expire_sync"
echo 1000 > "$d/queue/iosched/fifo_expire_async"
echo 5300 > "$d/queue/iosched/slice_idle_us"
echo 1 > "$d/queue/iosched/low_latency"
echo 200 > "$d/queue/iosched/timeout_sync"
echo 0 > "$d/queue/iosched/max_budget"
echo 1 > "$d/queue/iosched/strict_guarantees"
# additional tweaks for SSD (tuned for Samsung EVO 850):
if test $(cat "$d/queue/rotational") = "0"
then
echo 36 > "$d/queue/nr_requests"
echo 1 > "$d/queue/iosched/back_seek_penalty"
# slice_idle_us should be ~ 0.7/IOPS in µs
echo 16 > "$d/queue/iosched/slice_idle_us"
echo 10 > "$d/queue/iosched/fifo_expire_sync"
echo 250 > "$d/queue/iosched/fifo_expire_async"
echo 10 > "$d/queue/iosched/timeout_sync"
echo 0 > "$d/queue/iosched/strict_guarantees"
fi
done
Pengaturannya sangat mirip tetapi saya sekarang menggunakan bfq
bukannya cfq
karena yang terakhir tidak tersedia dengan kernel modern. Saya mencoba untuk menjaga nr_requests
serendah mungkin untuk mengizinkan bfq
untuk mengontrol penjadwalan lebih akurat. Setidaknya drive SSD Samsung tampaknya membutuhkan antrian yang cukup dalam untuk dapat berjalan dengan IOPS tinggi.
Saya menggunakan Ubuntu 18.04 dengan paket kernel linux-lowlatency-hwe-18.04-edge
yang memiliki bfq
hanya sebagai modul jadi saya perlu memuatnya sebelum dapat beralih ke modul itu.
Saya juga saat ini juga menggunakan zram
tapi saya hanya menggunakan 5% dari RAM untuk zram. Ini memungkinkan kernel Linux untuk menggunakan logika terkait swapping tanpa menyentuh disk. Namun, jika Anda memutuskan untuk menggunakan zero disk swap, pastikan aplikasi Anda tidak membocorkan RAM atau Anda membuang-buang uang.
Sekarang kita telah mengonfigurasi kernel untuk memuat hal-hal dari disk ke cache dengan kinerja yang masuk akal, saatnya untuk menyesuaikan perilaku cache:
Menurut tolok ukur yang telah saya lakukan, saya tidak akan repot-repot mengatur baca ke depan melalui blockdev
sama sekali. Pengaturan default kernel baik-baik saja.
Setel sistem agar lebih suka menukar data file daripada kode aplikasi (ini tidak masalah jika Anda memiliki cukup RAM untuk menyimpan keseluruhan sistem file dan semua kode aplikasi dan semua memori virtual yang dialokasikan oleh aplikasi dalam RAM). Ini mengurangi latensi untuk bertukar antara aplikasi yang berbeda melalui latensi untuk mengakses file besar dari satu aplikasi:
echo 15 > /proc/sys/vm/swappiness
Jika Anda lebih suka menyimpan aplikasi hampir selalu dalam RAM, Anda dapat menyetelnya ke 1. Jika Anda menyetel ini ke nol, kernel tidak akan bertukar sama sekali kecuali benar-benar diperlukan untuk menghindari OOM. Jika memori Anda terbatas dan bekerja dengan file besar (misalnya, pengeditan video HD), mungkin masuk akal untuk menyetelnya mendekati 100.
Saya saat ini (2017) lebih suka tidak memiliki swap sama sekali jika Anda memiliki RAM yang cukup. Tidak memiliki swap biasanya akan kehilangan 200-1000 MB RAM pada mesin desktop yang berjalan lama. Saya rela berkorban sebanyak itu untuk menghindari latensi skenario terburuk (menukar kode aplikasi saat RAM penuh). Dalam praktiknya, ini berarti saya lebih suka OOM Killer daripada bertukar. Jika Anda mengizinkan/perlu bertukar, Anda mungkin ingin meningkatkan /proc/sys/vm/watermark_scale_factor
, juga, untuk menghindari beberapa latensi. Saya akan menyarankan nilai antara 100 dan 500. Anda dapat mempertimbangkan pengaturan ini sebagai perdagangan penggunaan CPU untuk latensi swap yang lebih rendah. Standarnya adalah 10 dan kemungkinan maksimum adalah 1000. Nilai yang lebih tinggi seharusnya (menurut dokumentasi kernel) menghasilkan penggunaan CPU yang lebih tinggi untuk kswapd
proses dan menurunkan latensi swapping secara keseluruhan.
Selanjutnya, beri tahu kernel untuk lebih memilih menyimpan hierarki direktori dalam memori daripada konten file jika beberapa RAM perlu dibebaskan (sekali lagi, jika semuanya cocok dengan RAM, pengaturan ini tidak melakukan apa-apa):
echo 10 > /proc/sys/vm/vfs_cache_pressure
Menyetel vfs_cache_pressure
ke nilai rendah masuk akal karena dalam banyak kasus, kernel perlu mengetahui struktur direktori sebelum dapat menggunakan konten file dari cache dan menghapus cache direktori terlalu cepat akan membuat cache file di sebelah tidak berharga. Pertimbangkan untuk turun ke 1 dengan pengaturan ini jika Anda memiliki banyak file kecil (sistem saya memiliki sekitar 150K foto 10 megapiksel dan dihitung sebagai sistem "banyak file kecil"). Jangan pernah menyetelnya ke nol atau struktur direktori selalu disimpan dalam memori meskipun sistem kehabisan memori. Menyetel ini ke nilai besar hanya masuk akal jika Anda hanya memiliki beberapa file besar yang terus-menerus dibaca ulang (sekali lagi, pengeditan video HD tanpa RAM yang cukup akan menjadi contoh kasus). Dokumentasi kernel resmi mengatakan bahwa “meningkatkan vfs_cache_pressure secara signifikan melebihi 100 mungkin memiliki dampak kinerja yang negatif”.
Pengecualian: jika Anda memiliki jumlah file dan direktori yang sangat besar dan Anda jarang menyentuh/membaca/mencantumkan semua file, pengaturan vfs_cache_pressure
lebih tinggi dari 100 mungkin bijaksana. Ini hanya berlaku jika Anda tidak memiliki cukup RAM dan tidak dapat menyimpan seluruh struktur direktori dalam RAM dan masih memiliki cukup RAM untuk cache dan proses file normal (mis., server file seluruh perusahaan dengan banyak konten arsip). Jika Anda merasa perlu meningkatkan vfs_cache_pressure
di atas 100 Anda menjalankan tanpa cukup RAM. Meningkatkan vfs_cache_pressure
dapat membantu tetapi satu-satunya perbaikan nyata adalah mendapatkan lebih banyak RAM. Memiliki vfs_cache_pressure
disetel ke kinerja rata-rata pengorbanan angka tinggi untuk mendapatkan kinerja yang lebih stabil secara keseluruhan (yaitu, Anda dapat menghindari perilaku kasus terburuk yang sangat buruk tetapi harus menghadapi kinerja keseluruhan yang lebih buruk).
Terakhir, beri tahu kernel untuk menggunakan hingga 99% RAM sebagai cache untuk penulisan dan instruksikan kernel untuk menggunakan hingga 50% RAM sebelum memperlambat proses penulisan (default untuk dirty_background_ratio
adalah 10
). Peringatan:Saya pribadi tidak akan melakukan ini tetapi Anda mengklaim memiliki cukup RAM dan bersedia kehilangan data.
echo 99 > /proc/sys/vm/dirty_ratio
echo 50 > /proc/sys/vm/dirty_background_ratio
Dan beri tahu bahwa penundaan tulis 1 jam tidak masalah bahkan untuk memulai menulis sesuatu di disk (sekali lagi, saya tidak akan melakukan ini):
echo 360000 > /proc/sys/vm/dirty_expire_centisecs
echo 360000 > /proc/sys/vm/dirty_writeback_centisecs
Untuk informasi lebih lanjut tentang merdu ini, lihat https://www.kernel.org/doc/Documentation/sysctl/vm.txt
Jika Anda memasukkan semuanya ke /etc/rc.local
dan sertakan yang berikut di bagian akhir, semuanya akan berada di cache sesegera mungkin setelah boot (hanya lakukan ini jika sistem file Anda benar-benar cocok dengan RAM):
(nice find / -type f -and -not -path '/sys/*' -and -not -path '/proc/*' -print0 2>/dev/null | nice ionice -c 3 wc -l --files0-from - > /dev/null)&
Atau alternatif yang sedikit lebih sederhana yang mungkin bekerja lebih baik (hanya cache /home
dan /usr
, lakukan ini hanya jika /home
. Anda dan /usr
pas banget di RAM):
(nice find /home /usr -type f -print0 | nice ionice -c 3 wc -l --files0-from - > /dev/null)&