Lompat ke konten
17 menit bacamateri 32 dari 96

Rancang key cache

Key cache menentukan siapa boleh melihat apa. Masukkan versi, locale, izin, dan tenant ke key, atau kamu akan menyajikan data orang lain.

Ditinjau 26 Oktober 2026

Pertanyaan

Informasi apa yang harus ada di key supaya dua pembaca berbeda tidak pernah berbagi satu entri?

Setelah baca ini, kamu bisa menurunkan key dari semua masukan yang mengubah respons, dan memeriksa apakah key itu bocor antar tenant atau antar izin.

Prasyarat dan contoh

Kamu sudah memilih apa yang mau di-cache (M06.01) dan paham otorisasi serta isolasi tenant di level API (M03). Kamu tahu bahwa sebuah respons adalah fungsi dari beberapa masukan, bukan hanya URL.

Contoh nyata: layanan harga B2B. GET /harga?sku=A100 mengembalikan Rp 120.000 untuk pelanggan umum, Rp 96.000 untuk tenant grosir, dan teks "Harga" atau "Price" menurut bahasa. Developer menulis key harga:A100. Begitu satu pelanggan grosir membuka halaman, cache menyimpan harga grosir dan semua pelanggan umum berikutnya melihat Rp 96.000 selama TTL.

Tidak ada error, tidak ada log, dan semua tes lulus kalau tesnya hanya mencoba satu pengguna.

Mekanisme

Aturannya: key harus memuat setiap masukan yang bisa mengubah respons. Cara menurunkannya adalah daftar, bukan firasat.

  1. Tulis fungsi respons. respons = f(sku, tenant, tier, locale, mata uang, versi skema). Baca kodenya: setiap if pada pengguna, header, atau konfigurasi adalah kandidat.
  2. Pisahkan yang membuat variasi dari yang tidak. User-Agent jarang mengubah respons, jadi jangan masukkan ke key (hit ratio runtuh). Accept-Language yang dinormalisasi menjadi id atau en memang mengubah respons.
  3. Normalkan. sku=a100 dan sku=A100 harus jadi key yang sama kalau aplikasi memperlakukan keduanya sama. Urutkan query string. Kalau tidak, satu data tersimpan dua kali.
  4. Tambahkan versi. Awalan v3 pada key membuat deploy yang mengubah bentuk respons tidak membaca entri versi lama. Mengganti versi sama dengan membuang seluruh cache tanpa perintah hapus.
harga:v3:t=grosir42:tier=gold:loc=id:cur=IDR:sku=A100

Batas tenant dan izin. Kalau respons bergantung pada siapa yang bertanya, ada dua pilihan:

  • masukkan identitas atau kelompok izin ke key, atau
  • jangan cache lapisan itu, dan cache hanya bagian yang sama untuk semua orang.

Pilihan kedua sering lebih aman. Cache detail produk (sama untuk semua), lalu hitung harga per pengguna di atasnya. Jumlah entri kecil dan tidak ada risiko bocor.

Kardinalitas. Tiap dimensi mengalikan jumlah entri. 10.000 SKU × 3 tier × 2 locale × 2 mata uang = 120.000 entri, bukan 10.000. Dimensi yang nilainya hampir tidak terbatas (ID pengguna) mengubah cache jadi penyimpanan per pengguna dengan hit ratio mendekati nol kalau tiap pengguna jarang mengulang.

Saat rancangan ini gagal

  • Dimensi terlewat. Kamu menambahkan fitur mata uang bulan depan tapi tidak memperbarui key. Pelanggan Singapura melihat rupiah. Cara menangkap: setiap perubahan yang menambah masukan ke respons juga menaikkan versi key.
  • Key terlalu rinci. Memasukkan timestamp atau request ID membuat hit ratio 0%. Cache tetap berjalan, tapi cuma menambah latensi.
  • Key dari input mentah. Pengguna yang bisa mengisi bagian key bisa membanjiri cache dengan jutaan key unik (sku=<acak>), memakan memori dan menggusur entri berguna. Validasi input sebelum jadi key.
  • Tabrakan antar fitur. Dua modul memakai user:42 untuk hal berbeda. Pakai awalan namespace per fitur.
  • Respons dengan header Set-Cookie. Cache CDN yang menyimpan respons bercookie mengirim sesi satu pengguna ke pengguna lain. Jangan cache respons yang membawa data sesi.

Contoh tandingan: tim memasukkan userId ke key semua endpoint "supaya aman". Tidak ada yang bocor, tapi 80.000 pengguna aktif × 40 endpoint = 3,2 juta entri dengan hit ratio 12%. Cache menambah biaya tanpa mengurangi beban. Yang tepat adalah memisahkan bagian yang sama untuk semua orang dari bagian per pengguna.

Latihan

Endpoint GET /api/katalog?kategori=sepatu&hal=2 mengembalikan katalog. Responsnya bergantung pada tenant (tiap toko punya katalog sendiri), locale (id atau en), apakah pemanggil staf (staf melihat produk draf), dan versi format respons saat ini (v5).

  1. Tulis key-nya.
  2. Sebut satu masukan yang sengaja tidak kamu masukkan, dan alasannya.
  3. Hitung jumlah entri maksimum untuk 500 tenant, 40 kategori, 25 halaman.
Lihat pembahasan
katalog:v5:t=<tenantId>:loc=<id|en>:staf=<0|1>:kat=<kategoriNormal>:hal=<n>

Dua masukan yang tidak ikut: User-Agent (tidak mengubah isi) dan ID pengguna (hanya staf=0/1 yang mengubah isi, jadi kelompok izinnya cukup). Kategori dan halaman dinormalkan (huruf kecil, hal diparse jadi angka) supaya Sepatu dan sepatu tidak menjadi dua entri.

Jumlah maksimum: 500 tenant × 2 locale × 2 (staf atau bukan) × 40 kategori × 25 halaman = 2.000.000 entri. Itu batas atas. Pada praktiknya kebanyakan tenant tidak punya semua kategori sehingga angkanya lebih kecil, tapi pakai batas atas saat menghitung memori (M06.04).

Terkait

Catatan

  • Asumsi: respons deterministik terhadap masukan yang kamu daftar, dan cache menyimpan hasil serialisasi penuh.
  • Yang tidak dibahas: enkripsi nilai di cache dan kebijakan retensi data pribadi.
  • Angka kardinalitas adalah batas atas hitung-hitungan, bukan ukuran hasil pengamatan.
  • Terakhir ditinjau: 26 Oktober 2026.

Isi · System Design