Kebutuhan Nonfungsional

Skalabilitas, ketersediaan, latensi, biaya, dan kebenaran sebagai sasaran yang harus dinyatakan secara terukur.

Daftar isi

Topik ini memetakan kebutuhan nonfungsional yang paling sering menentukan arah desain, yaitu skalabilitas, ketersediaan, latensi, biaya, dan kebenaran, lalu menunjukkan cara mengekspresikan setiap kebutuhan itu sebagai angka yang dapat diverifikasi. Setelah membacanya, sasaran seperti ketersediaan 99,9% atau latensi persentil ke-95 di bawah 200 ms dapat dinyatakan dan diuji, bukan sekadar dijanjikan. Angka pada contoh sengaja dipilih bulat agar setiap klaim dapat dihitung ulang dengan cepat.

Kebutuhan fungsional dan nonfungsional#

Kebutuhan fungsional menyatakan apa yang harus dilakukan sistem, misalnya menyimpan catatan sensor suhu dan menampilkannya kembali. Kebutuhan nonfungsional tidak menambah fitur, melainkan menyatakan seberapa baik sistem melakukannya: berapa banyak pengguna yang ditahan sekaligus, seberapa sering sistem tersedia, seberapa cepat respons tiba, berapa biayanya, dan seberapa benar data yang dikembalikan. Kelima sifat itulah yang dibahas satu per satu pada topik ini.

Contohnya mudah dilihat pada layanan pencatatan sensor suhu. Fitur mencatat dan menampilkan data merupakan kebutuhan fungsional, sedangkan pernyataan bahwa sistem harus tetap mencatat ketika trafik naik sepuluh kali lipat merupakan kebutuhan nonfungsional. Pernyataan jenis kedua inilah yang menentukan apakah satu server cukup atau basis data perlu direplikasi.

Perbedaan keduanya penting karena konsekuensi arsitekturnya berbeda. Fitur biasanya ditambahkan tanpa mengubah bentuk sistem, sedangkan sifat nonfungsional menentukan komponen yang digunakan: kebutuhan menyimpan data bertahun-tahun mendorong pemilihan penyimpanan yang berbeda, kebutuhan respons di bawah 100 ms mendorong penempatan cache, dan kebutuhan melayani jutaan pengguna mendorong pemecahan menjadi banyak server. Karena itu kebutuhan nonfungsional dikumpulkan lebih dahulu, sebelum arsitektur digambar.

Menyatakan sasaran sebagai angka#

Sifat yang tidak diberi angka tidak dapat diuji. Klaim seperti sistem yang cepat atau andal menyisakan ruang tafsir yang berujung pada perdebatan, sedangkan pernyataan berangka menetapkan garis yang sama untuk insinyur, manajer, dan pengguna. Dunia operasi menyebut indikator kinerja layanan sebagai service level indicator (SLI), dan targetnya sebagai service level objective (SLO).

Tabel berikut memberi contoh pernyataan sasaran untuk kelima kebutuhan yang dibahas topik ini. Setiap baris memuat metrik, sasarannya, dan cara pengukurannya, karena angka tanpa cara pengukuran tidak lebih berguna daripada angka yang tidak ada.

MetrikPernyataan sasaranCara mengukur
Latensi95% permintaan selesai dalam 200 mspersentil p95 dari durasi permintaan, diukur dari sisi klien
Ketersediaan99,9% permintaan berhasil dalam satu bulanrasio permintaan berhasil terhadap seluruh permintaan
Throughput500 permintaan per detik tanpa degradasipengujian beban dan metrik trafik pada production
Biayapaling banyak 0,01 dolar AS per 1.000 permintaantagihan infrastruktur dibagi jumlah permintaan
Kebenaransaldo yang ditampilkan tertinggal paling lama 5 detikselisih waktu antara perubahan data dan tampilannya

Praktik operasi yang diadopsi secara luas menyarankan empat sinyal yang diukur sejak awal, yaitu latensi, trafik, tingkat error, dan saturasi, sebagaimana dirangkum pada buku Site Reliability Engineering terbitan Google. Tabel sebelumnya menambahkan biaya dan kebenaran karena keduanya sering menentukan keputusan arsitektur meskipun jarang masuk daftar sinyal emas. Yang terpenting adalah polanya: setiap baris menyebut metrik, target, dan cara pengukuran, sehingga langsung dapat diuji.

Ketersediaan dan angka sembilan#

Ketersediaan (availability) dinyatakan sebagai rasio permintaan yang dilayani dengan baik terhadap seluruh permintaan, biasanya dalam persen. Permintaan yang dianggap berhasil perlu didefinisikan lebih dahulu, misalnya permintaan yang mengembalikan respons dalam batas waktu tertentu. Dalam bentuk rumus:

ketersediaan=permintaan yang dilayani dengan baikseluruh permintaan×100% \text{ketersediaan} = \frac{\text{permintaan yang dilayani dengan baik}}{\text{seluruh permintaan}} \times 100\%

Angka 99% biasa disebut dua sembilan, 99,9% tiga sembilan, dan seterusnya. Selisih antarangka terlihat kecil, tetapi konsekuensinya terukur dalam menit waktu henti per bulan. Berkas berikut mengonversi beberapa target ketersediaan menjadi batas waktu henti bulanan, dengan satu bulan dihitung 30 hari.

python downtime-ketersediaan.py
# Konversi target ketersediaan menjadi batas waktu henti per bulan.
# Satu bulan dihitung 30 hari agar angkanya mudah diperiksa ulang.

TOTAL_MENIT = 30 * 24 * 60  # 43.200 menit

for angka_sembilan in (2, 3, 4, 5):
    ketersediaan = 1 - 10 ** (-angka_sembilan)
    waktu_henti = 10 ** (-angka_sembilan) * TOTAL_MENIT
    print(f"{ketersediaan:.{angka_sembilan}f}  ->  {waktu_henti:6.1f} menit per bulan")
text Keluaran
0.99  ->   432.0 menit per bulan
0.999  ->    43.2 menit per bulan
0.9999  ->     4.3 menit per bulan
0.99999  ->     0.4 menit per bulan

Pada tiga sembilan, anggaran waktu henti hanya 43,2 menit per bulan, dan pada empat sembilan tinggal 4,3 menit. Angka inilah yang dalam praktik SRE disebut anggaran error (error budget), yaitu sisa ketahanan yang boleh digunakan untuk rilis dan eksperimen sebelum perubahan baru dihentikan. Target dipilih dari konsekuensi bisnis ketika layanan turun, bukan dari jumlah sembilan yang paling banyak, karena setiap sembilan tambahan menaikkan biaya operasi dengan cepat.

Latensi dan persentil#

Latensi adalah durasi dari permintaan dikirim sampai respons diterima. Melaporkan latensi sebagai rata-rata menyembunyikan permintaan yang paling lambat, padahal pengalaman terburuk itulah yang paling diingat pengguna. Karena itu latensi dilaporkan sebagai persentil (percentile), misalnya p95 yang berarti 95% permintaan selesai lebih cepat dari nilai itu, dan p99 untuk 99% permintaan.

Berkas berikut menghitung rata-rata dan tiga persentil dari dua puluh hasil pengukuran contoh dengan metode nearest-rank yang cukup untuk keperluan estimasi.

python persentil-latensi.py
import math

# Latensi 20 permintaan contoh, terukur dalam milidetik.
LATENSI = [12, 14, 15, 15, 16, 17, 18, 19, 20, 21,
           22, 23, 25, 27, 31, 38, 46, 57, 74, 210]

def persentil(data, p):
    # metode nearest-rank: indeks = ceil(p/100 * n), dikurangi satu
    data_urut = sorted(data)
    indeks = math.ceil(p / 100 * len(data_urut)) - 1
    return data_urut[indeks]

rata_rata = sum(LATENSI) / len(LATENSI)
print(f"Rata-rata : {rata_rata:.1f} ms")
print(f"p50       : {persentil(LATENSI, 50)} ms")
print(f"p95       : {persentil(LATENSI, 95)} ms")
print(f"p99       : {persentil(LATENSI, 99)} ms")
text Keluaran
Rata-rata : 36.0 ms
p50       : 21 ms
p95       : 74 ms
p99       : 210 ms

Rata-ratanya 36 ms, tetapi p99 mencapai 210 ms, hampir enam kali rata-rata. Sebagian besar permintaan selesai di bawah 21 ms, sehingga pengalaman umum terasa cepat, sedangkan satu dari seratus permintaan menunggu selama sepuluh kali lipat nilai p50. Perilaku ini disebut latensi ekor (tail latency) dan menjadi alasan persentil, bukan rata-rata, yang digunakan sebagai sasaran layanan.

Biaya dan kebenaran#

Biaya adalah sifat yang paling sering terlupakan pada tahap desain, padahal setiap komponen menimbulkan tagihan yang berulang. Cara paling berguna menyatakannya adalah biaya per satuan kerja, misalnya biaya per juta permintaan atau biaya per terabyte per bulan. Dengan bentuk itu, dampak setiap keputusan desain dapat dibandingkan secara langsung, misalnya harga cache dibandingkan dengan penghematan panggilan basis data yang ditimbulkannya.

Kebenaran menyatakan seberapa dekat data yang diterima pengguna dengan kondisi terkini. Sistem yang sederhana mampu mengembalikan data yang selalu mutakhir, tetapi jaminan mutakhir pada skala besar berarti mengorbankan ketersediaan dan latensi. Banyak desain memilih kebenaran longgar yang tetap dinyatakan sebagai angka, misalnya tampilan saldo boleh tertinggal paling lama lima detik dari kondisi sebenarnya. Angka semacam ini menetapkan jendela konsistensi yang dapat diuji dengan pengukuran.

Kelima kebutuhan saling menekan. Menambah ketersediaan biasanya menaikkan biaya, memperketat kebenaran menaikkan latensi, dan memperbesar kapasitas untuk trafik puncak membiarkan sebagian server menganggur pada kondisi normal. Tugas desain bukan memaksimalkan semuanya, melainkan memilih kombinasi yang memenuhi sasaran dengan biaya yang masih masuk akal.

Kesalahan umum#

Kesalahan berikut paling sering ditemui ketika kebutuhan nonfungsional mulai dituliskan, baik pada dokumen desain maupun pada percakapan perencanaan kapasitas.

  1. Menetapkan sasaran tanpa cara pengukuran. Pernyataan seperti “respons yang cepat” tidak bisa diverifikasi, sehingga penilaian kembali ke selera. Perbaikannya, pasangkan setiap sifat dengan metrik, target, dan alat ukurnya sebelum desain dimulai. Alat ukurnya boleh sederhana, asalkan dibaca dengan cara yang sama oleh semua pihak.
  2. Memilih target sembilan yang paling tinggi tanpa melihat konsekuensi. Setiap sembilan tambahan menaikkan biaya dan kerumitan operasi secara tidak proporsional. Perbaikannya, mulai dari konsekuensi bisnis saat layanan turun, lalu pilih angka sembilan yang menutup konsekuensi itu.
  3. Mengukur hanya dari sisi server. Server melaporkan permintaan selesai dengan cepat, padahal pengguna menunggu jaringan dan perangkat yang lambat. Angka dari server pun biasanya hanya mencakup waktu pemrosesan, bukan perjalanan jaringan. Perbaikannya, ukur latensi dari sisi klien agar angkanya mencerminkan pengalaman pengguna, sesuai anjuran praktik SRE.

Ringkasan#

  • Kebutuhan nonfungsional menyatakan seberapa baik sistem bekerja dan pengaruhnya pada arsitektur lebih kuat daripada fitur.
  • Sasaran yang layak ditulis dalam bentuk SLI dan SLO, yaitu metrik berangka beserta cara pengukurannya.
  • Ketersediaan dikonversi menjadi anggaran waktu henti per bulan, dan setiap sembilan tambahan menaikkan biaya dengan cepat.
  • Latensi dilaporkan sebagai persentil karena rata-rata menyembunyikan ekor distribusi, sementara biaya dinyatakan per satuan kerja dan kebenaran dinyatakan sebagai jendela konsistensi yang terukur.

Referensi#