Lompat ke konten
18 menit bacamateri 71 dari 96

Perkirakan distribusi

Histogram, quantile sketch yang bisa digabung, reservoir sampling, dan kenapa rata-rata dari p99 per server selalu menyesatkan.

Ditinjau 26 Oktober 2026

Pertanyaan

Bagaimana melaporkan p99 latensi dari banyak server tanpa menyimpan setiap pengukuran, dan tanpa salah menggabungkannya?

Setelah baca ini, kamu bisa menjelaskan kenapa p99 tidak boleh dirata-ratakan, memilih antara histogram, quantile sketch, dan sampling, dan menyebut galat masing-masing.

Prasyarat dan contoh

Kamu sudah memakai persentil sebagai target di M01.04 dan memahami struktur yang bisa digabung dari M12.04.

Contoh: 20 server melaporkan p99 latensi tiap menit, dan dasbor menampilkan rata-ratanya. Rata-rata itu bukan p99 siapa pun. Itu angka tanpa arti statistik.

Ambil dua server saja. Server A melayani 900 request dengan p99 100 ms. Server B melayani 100 request dan sedang bermasalah: semuanya sekitar 2.000 ms, jadi p99-nya 2.000 ms. Rata-rata berbobot dari kedua p99 adalah 0,9 × 100 + 0,1 × 2.000 = 290 ms. Tapi dari 1.000 request, 100 atau 10% lambat sampai 2 detik. p99 gabungan sebenarnya sekitar 2.000 ms. Dasbor bilang 290 ms, kenyataannya hampir 7 kali lebih buruk.

Mekanisme

Persentil tidak bisa disusun dari persentil. Yang bisa digabung adalah bentuk distribusinya, lalu persentil dibaca dari hasil gabungan.

Histogram dengan bucket tetap. Tentukan batas bucket (misalnya 1, 2, 5, 10, 20, 50, 100, 200, 500, 1.000, 2.000 ms) dan hitung berapa pengukuran jatuh di tiap bucket. Penggabungan sama dengan menjumlahkan counter per bucket. Persentil dibaca dari jumlah kumulatif, dengan galat sebesar lebar bucket di sekitar titik itu. Kalau bucket di sekitar 100 ms berukuran 100-200, p99 yang dilaporkan bisa meleset puluhan milidetik. Pilih bucket yang rapat di tempat target kamu berada.

Quantile sketch (t-digest, DDSketch, KLL). Merangkum distribusi dalam memori kecil dengan jaminan galat. DDSketch menjamin galat relatif: dengan 1% relatif, p99 sebenarnya 500 ms dilaporkan antara 495 dan 505 ms, berapa pun skalanya. Sketch dengan parameter sama bisa digabung, hasilnya mempertahankan jaminan yang sama. t-digest akurat di ekor, tapi jaminan galatnya lebih longgar dan hasil gabungan bisa bergantung pada urutan.

Reservoir sampling. Menyimpan sampel seragam berukuran tetap k dari aliran yang panjangnya tidak diketahui: simpan k item pertama, lalu item ke-i (untuk i > k) menggantikan satu slot acak dengan probabilitas k/i. Hasilnya, setiap item punya peluang k/N ada di sampel. Cocok untuk melihat contoh kasus atau memperkirakan median. Buruk untuk ekor: dengan k = 1.000, p99,9 hanya ditentukan oleh sekitar 1 titik data, dan galatnya besar.

Rata-rata yang benar tetap bisa dihitung dari jumlah dan banyaknya, yang keduanya bisa dijumlahkan. Jadi rata-rata aman digabung, p99 tidak, dan karena itulah banyak sistem metrik menyimpan histogram plus jumlah dan banyak.

Saat rancangan ini gagal

  • Bucket yang salah tempat. Bucket terakhir "di atas 10 detik" menampung semua timeout. Persentil di bucket itu tidak punya batas atas, dan dasbor tidak bisa membedakan 11 detik dari 5 menit.
  • Menggabung sketch dengan akurasi berbeda. Satu pihak memakai 1% relatif, pihak lain 5%. Hasil gabungan hanya sebaik yang terburuk, dan sebagian implementasi menolak atau mengakibatkan hasil salah diam-diam.
  • Sampel untuk ekor. Tim memakai reservoir 1.000 titik untuk p99,9 lalu heran angkanya loncat-loncat tiap menit. Itu bukan bug. Itu sampel terlalu kecil untuk pertanyaannya.
  • Persentil dari persentil waktu. Merata-ratakan p99 per menit menjadi p99 per jam sama salahnya dengan merata-ratakan lintas server. Gabungkan histogram menit, lalu baca p99 jam.
  • Menghitung dari persentase kecil. p99 dari 50 request per menit ditentukan oleh satu request. Jangan jadikan alarm dari angka yang volumenya sekecil itu.

Latihan

Tiga wilayah melaporkan histogram latensi per menit dengan bucket: ≤100 ms, ≤500 ms, ≤1.000 ms,

1.000 ms.

| Wilayah | ≤100 | ≤500 | ≤1.000 | >1.000 | | ------- | ---- | ----- | ------ | ------ | | A | 800 | 150 | 40 | 10 | | B | 4.500| 400 | 80 | 20 | | C | 90 | 5 | 3 | 2 |

  1. Gabungkan histogram dan cari bucket yang memuat p99.
  2. Sebutkan galat pembacaan itu.
  3. Apa yang salah kalau p99 dihitung per wilayah lalu dirata-ratakan?
Lihat pembahasan
  1. Jumlah per bucket: ≤100 = 5.390, ≤500 = 555, ≤1.000 = 123, >1.000 = 32. Total 6.100. p99 berada di urutan ke-6.039 (0,99 × 6.100). Kumulatif: 5.390 (≤100), 5.945 (≤500), 6.068 (≤1.000). Urutan 6.039 jatuh di bucket ≤1.000 ms (di atas 500).
  2. Galat sebesar lebar bucket: p99 sebenarnya antara 500 dan 1.000 ms, jadi kamu bisa meleset sampai 500 ms. Bucket tambahan antara 500 dan 1.000 akan mempersempitnya. Bucket terakhir (>1.000, 32 request) tidak punya batas atas, jadi kalau target p99 di bawah 1 detik, kamu hanya bisa bilang lolos atau tidak.
  3. p99 wilayah C dihitung dari 100 request saja dan p99 wilayah A dari 1.000, tapi rata-rata sederhana memperlakukan keduanya sama. Tanpa bobot volume, wilayah kecil ikut menentukan angka. Bahkan dengan bobot, rata-rata p99 tidak sama dengan p99 gabungan, seperti contoh 290 ms versus 2.000 ms di atas.

Terkait

Catatan

  • Asumsi: pengukuran independen dan sketch dipakai dengan parameter yang sama di semua node.
  • Yang nggak dibahas: sliding window quantile, dan pembobotan sampel (weighted reservoir).
  • Angka contoh 290 ms versus 2.000 ms adalah ilustrasi dengan data yang sengaja dibuat sederhana.
  • Terakhir ditinjau: 26 Oktober 2026.

Isi · System Design