Pertanyaannya hampir selalu sama: semalam situs butuh dua puluh detik untuk menjawab, dan menjelang pagi semuanya pulih dengan sendirinya. Tidak ada lagi yang bisa dilihat — top menjawab untuk detik yang sedang berjalan, sementara yang ditanyakan adalah pukul tiga dini hari. Berikut ini arti sebenarnya dari angka-angka beban, mana saja yang harus dibaca berpasangan, dan mengapa satu kali pengukuran lebih sering menyesatkan daripada menolong.
Load average: tiga angka dan satu salah paham yang umum
uptime
cat /proc/loadavg
nproc
Ketiga angka itu adalah rata-rata satu, lima, dan lima belas menit. Angka-angka itu tidak dibandingkan dengan nol, melainkan dengan jumlah inti yang dilaporkan nproc. Nilai 8 pada mesin berinti delapan adalah beban penuh tetapi sehat: pekerjaannya persis sebanyak yang sanggup diselesaikan server. Nilai 2 pada VPS berinti satu adalah antrean dua kali lebih panjang daripada kapasitasnya, dan setiap permintaan menunggu gilirannya.
Perbandingan ketiga angka satu sama lain menunjukkan arah. Nilai satu menit yang jelas di atas nilai lima belas menit berarti beban sedang naik saat ini juga. Sebaliknya berarti puncaknya sudah lewat dan yang terlihat hanyalah ekornya.
Sekarang salah paham yang paling merusak pembacaan angka-angka ini. Di Linux, load average bukan «penggunaan prosesor». Berbeda dari sistem Unix lain, Linux menghitung ke dalamnya bukan hanya proses yang berjalan atau siap berjalan, melainkan juga yang berada dalam keadaan D — tidur tak terinterupsi. Artinya, yang sedang menunggu disk atau sistem berkas jaringan. Dari situlah muncul server dengan beban 12 sementara prosesornya nyaris menganggur: pekerjaan tidak maju, semuanya berdiri di antrean.
Prosesor atau disk
Memisahkan kedua kasus itu adalah hal pertama yang layak dilakukan:
vmstat 1 5
iostat -x 1 3
Pada keluaran vmstat ada tiga kolom yang penting. r adalah berapa banyak proses yang mengantre untuk prosesor, b berapa yang terblokir menunggu masukan dan keluaran, sedangkan wa adalah bagian waktu ketika prosesor menganggur sambil menunggu disk. wa yang bertahan di atas 10–15 % dengan us dan sy yang kecil berarti server tertahan oleh disk: menambah inti tidak ada gunanya, yang ada pun sudah bebas.
Proses mana yang sedang menunggu bisa didaftar satu per satu:
ps -eo state,pid,comm,wchan:30 | awk '$1 ~ /^D/'
Sebuah contoh dari praktik kami sendiri. Dengan konfigurasi bawaan, Suricata menulis sekitar tiga puluh jenis peristiwa dan tidak menyiapkan rotasi apa pun untuknya — pada server yang berjalan, itu menghasilkan 15 GB log dalam dua hari. Bebannya saat itu tidak tampak sebagai prosesor yang sibuk melainkan justru sebagai I/O wait: sistem menulis tanpa henti dan segala hal lain mengantre di belakangnya. Obatnya bukan paket yang lebih besar, melainkan daftar jenis peristiwa yang lebih pendek dan rotasi yang disiapkan.
Kasus kebalikannya, murni soal prosesor dan jauh kurang kentara. Sebuah halaman web memanggil apt dengan pengguna tempat PHP-FPM berjalan. Root menyimpan tembolok biner di /var/cache/apt/pkgcache.bin — pada host dengan belasan repositori ukurannya 70 MB — dan memetakannya ke memori tanpa biaya. Pengguna biasa tidak boleh menulis ke direktori itu dan membangun ulang temboloknya pada setiap pemanggilan. Diukur pada mesin yang sama persis: 0,01 detik waktu prosesor sebagai root berbanding 4,2 detik sebagai pengguna tanpa hak istimewa. Perintah yang sama, selisih empat ratus kali, dikalikan setiap kali halaman dibuka.
Kesimpulan dari kedua kasus itu sama: beban diukur, bukan ditebak. Mengukur waktu setiap perintah yang dicurigai satu per satu memakan setengah jam dan biasanya menunjuk ke tempat lain daripada asal kecurigaan semula.
Memori: free tidak menunjukkan apa yang tampaknya ditunjukkan
free -h
Kolom used sendirian mengatakan sangat sedikit, dan kolom free justru menyesatkan: Linux menyerahkan memori yang tidak terpakai kepada tembolok halaman dan mengembalikannya kepada aplikasi pada permintaan pertama. Kolom yang perlu dibaca adalah available — berapa banyak yang bisa dipakai tanpa masuk ke swap. buff/cache yang besar bukan masalah, melainkan tanda sistem bekerja sebagaimana mestinya.
Pada swap yang penting bukan nilai saat ini melainkan bentuknya. Naik lalu kembali ke nol: ada puncak singkat. Naik sekali dan menetap di sana: puncaknya sudah terjadi, halaman-halaman terdepak dan tidak ada yang mengembalikannya — server tampak tenang meski pada satu saat memorinya sempat kurang. Apakah pertukaran sedang berlangsung saat ini terlihat pada kolom si dan so di vmstat; nilai bukan nol di sana adalah bentuk kelambatan yang paling terasa bagi pengguna.
Kalau selama penurunan malam ada proses yang begitu saja lenyap, penjelasannya biasanya di sini:
journalctl -k --since yesterday | grep -i "out of memory"
dmesg -T | grep -i "killed process"
Baris semacam Out of memory: Killed process 1234 (mysqld) menutup persoalan lebih baik daripada grafik mana pun: basis data tidak «tumbang sendiri», kernel menghentikannya karena memori habis.
Siapa yang melakukannya
ps aux --sort=-%cpu | head -10
ps aux --sort=-%mem | head -10
Satu catatan: %CPU pada ps adalah rata-rata sepanjang hidup proses, sehingga lonjakan singkat hilang dalam daftar itu. Untuk lonjakan itu diperlukan top atau pidstat 1 5, yang mengukur dalam suatu selang.
Kapan beban menjadi persoalan keamanan
Prosesor 100 % yang rata sepanjang malam, disertai proses bernama tak bermakna dengan direktori kerja di /tmp atau /dev/shm, adalah gambaran klasik seorang penambang, bukan gambaran situs yang bertumbuh. Lonjakan lalu lintas masuk bersamaan dengan meningkatnya penulisan ke log adalah serangan kata sandi yang sedang berlangsung. Volume log yang tiba-tiba melompat biasanya adalah badai peringatan palsu dari suatu penyaring.
Perkakas perlindungan itu sendiri adalah kategori tersendiri. Pada salah satu server kami, beban bertahan sekitar tiga tanpa seorang pengunjung pun, dan di puncak ps menurut waktu prosesor terkumpul bukan situs dan bukan basis data yang berdiri, melainkan CrowdSec, fail2ban, Falco, dan Suricata. Itu bukan kerusakan dan bukan alasan untuk mematikannya, tetapi harga perlindungan layak diketahui dalam angka: pada VPS kecil harga itu terasa.
Untuk apa mengamati
Semua yang di atas menjawab pertanyaan «apa yang terjadi sekarang». Pertanyaan pagi hari — apa yang terjadi pukul tiga dini hari — tidak tercakup oleh perintah-perintah ini: tentang malam yang telah lewat tidak ada data jika tidak ada yang mencatatnya. Dan mendirikan Prometheus dengan Grafana demi satu VPS saja patut diragukan, sebab tumpukan yang mengamati berakhir lebih berat daripada server yang diamati.
Cukup satu baris di basis data setiap lima menit dan satu halaman yang menggambar dua puluh empat jam terakhir darinya: load average, penggunaan prosesor dan I/O wait secara terpisah, memori dan swap, pembacaan dan penulisan disk, tingkat keterisian partisi, inode, deskriptor berkas, koneksi. Pada satu sumbu waktu, pasangan-pasangan itu terbaca dengan mata telanjang: wa tinggi dengan prosesor yang tenang, swap yang tidak pernah kembali ke nol, deskriptor yang mendekati batas — galat too many open files yang akan datang menjadi terlihat berjam-jam sebelum terjadi. Seperti apa semuanya bila dirangkai jadi satu, halaman demo di bawah ini memperlihatkannya.