CPU dijadwalkan, memori dipetakan — dan di ujung rantai itu menunggu perangkat paling lambat di sistem: penyimpanan. Pada harddisk mekanis, berpindah antar posisi data (seek) berbiaya milidetik yang setara ribuan siklus CPU, sehingga urutan operasi baca-tulis menentukan nasib latensi seluruh sistem. Kernel menempatkan wasit di antara antrean proses dan antrean perangkat: I/O scheduler, yang menyusun ulang, menggabungkan, dan memprioritaskan permintaan I/O sebelum dikirim ke disk. Pada chapter ini kita menyurvei scheduler yang tersedia di /sys, memilih yang sesuai jenis perangkat, lalu memprioritaskan proses lewat ionice.
Masalah: Antrean di Ujung Disk #
Ambil skenario klasik server ber-harddisk: backup raksasa sedang menyalin jutaan file sambil dua belas user menunggu editor mereka membuka dokumen kecil. Tanpa wasit, kedua beban itu masuk ke disk dalam urutan kedatangan — kepala disk bolak-balik antara sektor backup dan sektor dokumen, dan editor yang seharusnya selesai 5 milidetik menunggu 50. Dua trik menjadi senjata utama scheduler. Pertama, merging: dua permintaan yang menyangkut sektor bersebelahan digabung menjadi satu. Kedua, sorting: permintaan diurutkan mengikuti posisi sektor sehingga kepala disk bergerak satu arah yang efisien. Pada perangkat modern urutannya berubah lagi — SSD dan NVMe tidak punya kepala mekanis, sehingga biaya “melompat” nyaris nol dan pengurutan malah menambah jeda yang tidak perlu.
Tiga Scheduler yang Sering Kita Temui #
Kernel modern membawa beberapa scheduler, dan tiap block device memilih salah satunya secara terpisah:
| Scheduler | Karakter | Cocok untuk |
|---|---|---|
none | tidak mengurutkan, langsung terus | NVMe dan perangkat cepat lain |
mq-deadline | memberi tenggat tiap permintaan agar tidak kelaparan | SSD — pilihan bawaan banyak distro |
bfq | membagi bandwidth adil per proses, mengutamakan interaktif | HDD dan desktop |
kyber | menyetel latensi target baca/tulis, ringan | NVMe/SSD berbeban tinggi |
Pilihan aktif per perangkat terbaca dari sysfs — mari kita intip milik lingkungan latihan ini:
for d in /sys/block/*; do
printf '%-8s %-30s rotational=%s\n' \
"$(basename "$d")" \
"$(cat "$d/queue/scheduler")" \
"$(cat "$d/queue/rotational")"
doneOutput yang Dihasilkan:
pmem0 none rotational=0
vda [mq-deadline] kyber bfq none rotational=1
zram0 none rotational=0Cara membaca output di atas:
/sys/block/*: satu direktori per block device — di lingkungan ini adapmem0,vda, danzram0; di komputer Anda daftarnya mengikuti perangkat yang terpasang.queue/scheduler: daftar scheduler yang tersedia, dengan yang aktif ditandai tanda kurung siku —vdasedang memakaimq-deadline.queue/rotational: penanda apakah perangkat berputar (1) atau tidak (0);zram0(RAM terkompresi) danpmem0memilihnonekarena keduanya bukan disk sungguhan.
Mengganti Scheduler untuk Sebuah Perangkat #
Penggantian dilakukan dengan menulis ke file yang sama kita baca tadi: echo bfq | sudo tee /sys/block/sda/queue/scheduler mengganti scheduler sda saat itu juga, tanpa reboot dan tanpa mengganggu antrean yang sedang berjalan. Perubahannya tidak bertahan melewati reboot — cara membuatnya permanen justru memakai mekanisme yang akan kita bahas di chapter berikutnya: sebuah udev rule yang bereaksi saat perangkat terdeteksi. Untuk disk data yang sibuk, anggapan terbaiknya sederhana: HDD satu-satunya di sistem memakai bfq agar beban backup tidak menggagalkan sesi interaktif, sementara SSD cukup dengan mq-deadline.
Prioritas I/O dengan ionice #
Scheduler juga menerima keinginan dari user space. Perintah ionice(1)
menempelkan kelas dan prioritas pada proses:
| Kelas | Nama | Perilaku |
|---|---|---|
| 1 | real-time | dilayani lebih dulu — butuh CAP_SYS_ADMIN |
| 2 | best-effort | bawaan semua proses, prioritas 0–7 |
| 3 | idle | hanya kalau tidak ada antrean lain |
Berikut dua kelas yang bisa kita coba tanpa root; argumen -p 0 meminta ionice membaca prioritas prosesnya sendiri:
ionice -c 2 -n 7 ionice -p 0
ionice -c 3 ionice -p 0Output yang Dihasilkan:
best-effort: prio 7
idlePerintah pertama membungkus proses dengan kelas best-effort prioritas 7 (paling sopan di antara yang bukan idle), dan perintah kedua menurunkannya ke idle. Bandingkan dengan kelas pertama yang menuntut privilege:
ionice -c 1 -n 4 true 2>&1Output yang Dihasilkan:
ionice: ioprio_set failed: Operation not permittedKernel menolak karena kelas real-time membutuhkan CAP_SYS_ADMIN — persis pemeriksaan capability yang kita bedah di chapter capabilities
. Batasan pentingnya: prioritas ionice dihormati penuh oleh bfq, disadari sebagian oleh mq-deadline, dan diabaikan none — di NVMe tanpa antrean, tidak ada yang perlu diprioritaskan. Untuk pembatasan yang lebih tegas per kelompok proses, mekanisme io controller pada cgroups
menetapkan kuota bandwidth, bukan sekadar urutan antrean.
Membaca Efek Scheduler dari /proc/diskstats #
Hasil kerja scheduler terlihat di /proc/diskstats, yang mencatat antara lain jumlah operasi baca/tulis yang selesai dan berapa yang berhasil digabung. Snapshot berikut (fixture) membandingkan tiga perangkat dengan beban berbeda:
cat > diskstats.txt <<'FIX'
# maj min nama baca_selesai baca_merge tulis_selesai tulis_merge
259 0 nvme0n1 1248032 481772 903112 610238
8 0 sda 2104320 3122031 1408210 1613478
252 0 zram0 88120 0 127341 0
FIX
awk 'NR > 1 {
baca = $4 + $5
tulis = $6 + $7
printf "%-8s baca: %7d op, %3d%% termerge tulis: %7d op, %3d%% termerge\n", \
$3, baca, $5 * 100 / baca, tulis, $7 * 100 / tulis
}' diskstats.txtOutput yang Dihasilkan:
nvme0n1 baca: 1729804 op, 27% termerge tulis: 1513350 op, 40% termerge
sda baca: 5226351 op, 59% termerge tulis: 3021688 op, 53% termerge
zram0 baca: 88120 op, 0% termerge tulis: 127341 op, 0% termergeBedah perhitungannya:
baca = $4 + $5: total operasi baca adalah jumlah yang selesai ditambah yang berhasil digabung — merge menyerap permintaan sehingga tidak dihitung dua kali sebagai operasi disk.$5 * 100 / baca: persentase permintaan baca yang dihemat scheduler lewat penggabungan.- Pola hasilnya:
sda(HDD) menunjukkan lebih dari separuh permintaannya termerge — tanda scheduler rajin mengurutkan demi menghemat seek;nvme0n1lebih rendah karena tidak ada kepala yang perlu dihemat;zram0nol persen karena perangkat RAM memakai schedulernone.
Desain antreannya dijelaskan lebih lanjut di dokumentasi I/O priority dan dokumentasi BFQ kernel.
Perhatikan benang merah chapter ini: agar setelan scheduler bertahan melewati reboot, kita menunggu momen perangkat muncul di sistem dan bereaksi saat itu juga. Momen kemunculan itu sendiri adalah sebuah event yang bisa kita tangkap dengan aturan — topik chapter udev rules berikutnya.