Kadang penghematan infrastruktur terbesar datang dari baris yang paling membosankan: layout sebuah struct. Tanggal 18 September 2026, tim Cloudflare menerbitkan post-mortem optimasi di blog mereka berjudul "Saving another 100TB of RAM with math (and Rust)". Angkanya bukan typo. Dua perubahan kecil pada implementasi consistent hashing di satu layanan berbasis Pingora memangkas penggunaan RAM mereka lebih dari 100TB secara global,ditambah penghematan 100TB yang sebelumnya dilakukan tim DNS. Ini cerita teknisnya, dan kenapa setiap engineer yang menyentuh Rust atau manajemen memori harus membacanya.
TL;DR
- Cloudflare memangkas penggunaan RAM lebih dari 100TB secara global melalui dua perubahan pada implementasi consistent hashing di layanan berbasis Pingora.
- Perbaikan pertama memadatkan struct Point dari 8 byte menjadi 6 byte dengan mengganti indeks 32-bit menjadi u16 dan menyimpan data sebagai array byte, hemat 25 persen per titik.
- Perbaikan kedua memangkas jumlah hash per server sebesar 90 persen setelah derivasi rumus menunjukkan bahwa 90.000 dari 100.000 titik terakhir hanya mengurangi error sekitar 0,7 persen.
- Pada ruang hash 32-bit, probabilitas tabrakan antar titik meroket karena birthday paradox, sehingga error justru naik pada rentang 10.000 sampai 100.000 titik per server di simulasi data center dengan 2048 server.
- Semua perubahan tersedia di crate pingora-ketama, menyusul penghematan 100TB lain yang sebelumnya dilakukan tim DNS.
Posting aslinya ditulis Kevin Guthrie, Mariia Iurchenko, Zaidoon Abd Al Hadi, dan Ivan Babrou, ada di blog.cloudflare.com. Semua perubahan yang diceritakan sudah tersedia di crate pingora-ketama.
Konteks: Consistent Hashing Itu Apa dan Kenapa Makan RAM
Cloudflare memakai consistent hashing untuk merutekan request yang bisa di-cache ke server berdasarkan URL, sehingga satu file cukup disimpan satu kali per data center dan letaknya selalu bisa dicari secara stabil. Model mentalnya: ruang hash (di sini 32-bit) dibentangkan jadi garis angka, tiap server menempatkan sejumlah titik di sepanjang garis itu, dan sebuah request jatuh ke titik terdekat searah jarum jam.
Kualitas distribusi bergantung pada banyaknya titik per server. Makin banyak titik, makin merata bagiannya. Di sinilah tagihan RAM datang: setiap titik adalah satu entri di memori, dan entri itu dikalikan titik per server, dikalikan jumlah server, dikalikan semua cluster yang menjalankan struktur ini. Scale mengubah byte kecil menjadi petabyte.
Perbaikan 1: Struct yang Membengkak oleh Aturan Alignment
Representasi awal sebuah titik di layanan itu begini:
struct Point {
hash: u32,
index: u32,
}
Delapan byte per titik: empat untuk hash (tidak bisa dihindari), empat sebagai indeks ke array server. Insight pertama, dari Zaidoon: indeks 32-bit itu berlebihan. Pusat data tidak mungkin mengoordinasi lebih dari 2 pangkat 16, sekitar 65 ribu server, sekaligus. Tipe u16 lebih dari cukup.
Tapi mengganti field kedua menjadi u16, secara naif, tidak menghemat sepeser pun. Aturan alignment Rust menuntut ukuran struct menjadi kelipatan field paling aligned-nya. Field terbesar, hash, empat byte, jadi struct tetap harus berukuran kelipatan empat: delapan byte, dengan byte yang terbuang sebagai padding. Kelas yang sama, pemborosan yang sama, tanpa perubahan apa pun.
Dua jalan keluar yang dibahas post tersebut: atribut #[repr(packed)], yang kontroversial karena alasan-alasan bagus (referensi ke field unaligned bisa jadi undefined behavior di platform tertentu), atau pendekatan yang kurang glamor tapi aman: menyimpannya sebagai array byte mentah dengan getter.
struct Point([u8; 6]);
impl Point {
fn hash(&self) -> u32 {
u32::from_ne_bytes(self.0[0..4].try_into().unwrap())
}
fn index(&self) -> u16 {
u16::from_ne_bytes(self.0[4..6].try_into().unwrap())
}
}
Delapan byte jadi enam. Hemat 25 persen dari struktur titiknya, hanya dari kompresi data, tanpa mengubah algoritma apa pun. Di atas kertas tidak dramatis; di atas ratusan miliar titik, sangat dramatis.
Perbaikan 2: Matematika yang Menghukum "Sekalian Banyakin Titik Aja"
Bagian yang membuat judul "with math" bukan clickbait. Distribusi titik per server punya deviasi standar; makin banyak hash per server, makin rata bagiannya, tapi dengan kurva yang sangat kejam. Tim-nya menurunkan rumus eksak (derivasinya diposting terpisah, bukan sekadar approximation dari textbook) untuk kasus k hash per server, lalu melihatnya lewat koefisien variasi.
Kesimpulan angka yang mereka publish: dengan basis 160 titik per satuan bobot penyimpanan, sebuah server berbobot 625 bisa memegang 100.000 titik. Dari chart koefisien variasi, 90.000 titik terakhir dari 100.000 itu hanya membeli pengurangan error sekitar 0,7 persen. Nyaris gratis? Tunggu, ada twist yang lebih kejam.
Model kontinu itu mengasumsikan ruang hash tak terbatas. Praktiknya, hash-nya 32-bit, dan begitu jumlah titik per server membesar, probabilitas tabrakan antar titik meroket mengikuti birthday paradox. Tabrakan berarti sebagian titik tidak ikut mendistribusikan beban, error-nya acak dan tidak hilang meski titiknya ditambah. Di simulasi untuk data center dengan 2048 server, error justru naik di rentang 10.000 sampai 100.000 titik per server.
Soal yang selama ini dianggap fitur ("makin banyak titik makin aman") ternyata sebagian besar sampah memori. Dengan bekal matematika itu, Cloudflare memangkas jumlah hash per server sebesar 90 persen tanpa degradasi error yang terukur. Ring-ring hash besar yang kini tidak terpakai didecommissioned selamanya.
Yang Paling Berisiko: Migrasi Tanpa Melelehkan Origin
Judul seksi blog-nya: "Migrating without melting origins". Ganti komposisi titik berarti mengubah sebagian jalur routing, dan traffic yang pindah itu berarti cache yang sudah hangat menjadi dingin di tujuan baru. Cache-cold dalam skala besar berarti fetch ulang ke origin server, lonjakan beban, dan potensi kegagalan berantai. Rilis struktur baru yang lebih hemat harus dilakukan bertahap dan terkontrol, fase di mana disiplin ops lebih menentukan daripada cleverness kode. Mereka tidak menjabarkan angkanya di bagian yang dikutip publik, tapi framing seksinya jujur: menghemat RAM itu bagian mudah; memindahkan peta routing produksi adalah bagian berbahaya.
Tiga Pelajaran untuk Diambil
- Audit layout memori sebelum scale-out. Empat byte padding per entri terasa gratis sampai dikalikan ratusan miliar entri. Pola yang sama berlaku untuk index database, format kolom di data lake, dan metadata di mana pun: tanya dulu berapa byte, baru berapa baris.
- Kurangi, jangan tambah. Insting engineers saat error sedikit naik adalah menambah buffer, retry, atau titik hash. Data menunjukkan kurva diminishing return yang ekstrem di struktur ini. Sebelum menambah resource, ukur dulu kontribusi marginalnya.
- Birthday paradox meraja di ruang hash terbatas. Tiap desain yang menempelkan banyak entri ke ruang 32-bit punya plafon yang tidak bisa dinaiki dengan menambah entri.
💬 Komentar (0)
Belum ada komentar. Jadilah yang pertama! 💬