3.15 Caching dan pengiriman konten
Tinjauan dan motivasi
Cache adalah salinan data yang disimpan di tempat yang lebih cepat atau lebih dekat daripada aslinya, sehingga Anda dapat menjawab permintaan tanpa mengerjakan lagi seluruh pekerjaan yang mahal. Hampir setiap sistem yang terasa cepat, cepat karena caching. Kueri basis data yang akan memakan 40 milidetik kembali dalam kurang dari satu ketika hasilnya sudah ada di memori. Gambar yang akan menyeberangi samudra disajikan dari mesin di kota yang sama. Caching adalah teknik kinerja berpengungkit tertinggi yang Anda punya, dan juga yang paling mungkin menghadiahi Anda bug halus yang menjengkelkan.
Bab ini mendalami strategi caching. Bab 3.4 (arsitektur data dan penyimpanan) memperkenalkan cache dan content delivery network sebagai satu perhatian penyimpanan di antara banyak lainnya, dan bab 3.13 (jaringan dan konektivitas) membahas jalur jaringan yang mereka tumpangi. Di sini Anda mendapat keputusan-keputusannya: di mana menempatkan cache, bagaimana memberinya kunci, kapan meng-invalidasinya, bagaimana melindunginya di bawah beban, dan bagaimana bernalar tentang kebasian yang Anda tukar dengan kecepatan. Caching menyentuh rekayasa kinerja (bab 2.16), skalabilitas dan ketahanan (bab 3.5), kenyataan kegagalan parsial sistem terdistribusi (bab 3.3), dan, karena cache yang teracuni dapat menyajikan serangan kepada ribuan pengguna, keamanan aplikasi (bab 4.2).
Motivasinya bermuara pada tiga tuas. Caching memangkas latensi, sehingga pengguna menunggu lebih sedikit. Ia memangkas beban, sehingga origin Anda melayani lebih banyak lalu lintas pada perangkat keras yang sama. Dan ia memangkas biaya, karena permintaan yang dijawab di tepi tidak pernah menyentuh basis data, komputasi, atau tagihan egress Anda. Bagi tim besar, strategi caching bersama adalah beda antara platform yang berskala dapat diprediksi dan platform di mana setiap layanan menciptakan ulang invalidasi dan salah melakukannya. Dalam sistem enterprise dan pemerintah, di mana lalu lintas melonjak pada tenggat pengajuan dan hari peluncuran, cache yang dirancang baik sering kali yang berdiri antara portal yang berfungsi dan kegagalan publik.
Prinsip utama
- Lakukan caching untuk memangkas latensi, beban, dan biaya, dan ketahui mana yang sedang Anda beli.
- Tempatkan cache pada lapisan hierarki yang tepat, paling dekat dengan tempat ia paling membantu.
- Perlakukan invalidasi sebagai bagian tersulit; rancang kunci dan masa hidup sebelum Anda melakukan caching.
- Lindungi cache di bawah beban dengan penggabungan permintaan, jitter, dan pertahanan stampede.
- Pilih pola tulis dengan sengaja: konsistensi dan kecepatan saling tarik.
- Ukur hit rate, kebasian, dan beban origin; cache yang tak terukur adalah liabilitas.
- Perlakukan konten ter-cache sebagai permukaan serangan; cache yang teracuni menyajikan kepada semua orang.
Rekomendasi
Pahami hierarki cache
Caching bukan satu hal di satu tempat. Ia hierarki salinan, masing-masing lebih dekat ke pengguna daripada yang sebelumnya, dan Anda merancang melintasi seluruhnya. Terdekat dengan pengguna adalah cache klien: cache HTTP peramban, penyimpanan lokal aplikasi seluler, cache memori dalam proses. Berikutnya content delivery network (CDN), armada server yang tersebar di seluruh dunia yang menyimpan salinan konten Anda di tepi jaringan, dekat pengguna. Di belakangnya ada cache reverse proxy atau gateway, cache bersama di depan server Anda. Lalu cache aplikasi: penyimpanan key-value cepat seperti data grid dalam memori yang menyimpan hasil terhitung, sesi, dan fragmen yang dirender. Terakhir cache kueri dan buffer basis data sendiri, yang menjaga halaman panas di memori agar disk lebih jarang disentuh.
Setiap lapisan melayani tugas berbeda: cache klien menghilangkan permintaan sepenuhnya, CDN menyerap lalu lintas baca global, reverse proxy melindungi origin Anda dari pekerjaan identik berulang, cache aplikasi menghemat komputasi ulang, dan cache basis data menjaga penyimpanan tetap responsif. Permintaan yang meleset di setiap lapisan dan mencapai basis data adalah jalur paling lambat dan paling mahal yang Anda punya, sehingga inti hierarki adalah menjawab sejauh ke atas dan ke luar yang dapat Anda lakukan dengan aman. Rancang sebagai sistem, karena fragmen ter-cache di lapisan aplikasi dan salinan CDN basi di atasnya dapat berselisih dengan cara yang membingungkan pengguna.
Perlakukan invalidasi sebagai masalah sulit
Ada lelucon lama bahwa dua masalah tersulit dalam ilmu komputer adalah penamaan, invalidasi cache, dan galat off-by-one. Lelucon itu bertahan karena invalidasi memang sulit: cache adalah salinan, dan begitu aslinya berubah, setiap salinan berpotensi menjadi dusta. Anda punya tiga strategi luas. Kedaluwarsa berbasis waktu dengan time to live (TTL), durasi entri tetap valid sebelum dianggap basi, adalah yang paling sederhana: Anda menerima kebasian terbatas dan membiarkan entri menua. Invalidasi eksplisit membersihkan atau memperbarui entri ketika data dasarnya berubah, yang presisi tetapi mengharuskan Anda mengetahui setiap tempat salinan hidup. Invalidasi berbasis peristiwa membuat cache berlangganan peristiwa perubahan agar menyegarkan diri sendiri, yang berskala lebih baik lintas banyak cache tetapi menambah dependensi pesan.
Kebanyakan sistem nyata memadukan ini: TTL pendek untuk data yang sering berubah dan menoleransi kebasian beberapa detik, TTL lebih panjang ditambah pembersihan eksplisit untuk data yang jarang berubah tetapi harus benar ketika berubah, dan kunci cache berversi untuk konten yang tak berubah begitu diterbitkan. Trik kunci berversi layak diinternalisasi: alih-alih meng-invalidasi, Anda mengubah kunci. Stylesheet yang disajikan sebagai app.v187.css tidak pernah perlu dibersihkan, karena versi baru adalah kunci baru dan yang lama sekadar berhenti diminta. Setiap kali Anda dapat mengubah masalah invalidasi menjadi masalah penamaan, lakukanlah.
Rancang kunci cache dan TTL dengan sengaja
Cache hanya sebaik kuncinya. Kunci cache adalah pengidentifikasi tempat nilai disimpan dan dicari, dan salah membuatnya menyebabkan dua kegagalan berlawanan. Terlalu kasar, dan Anda menyajikan data satu pengguna kepada pengguna lain: halaman personal yang di-cache di bawah URL yang mengabaikan identitas pengguna adalah kebocoran data. Terlalu halus, dan hit rate Anda runtuh karena tak ada dua permintaan yang berbagi kunci. Putuskan dengan sengaja apa yang termasuk dalam kunci: identitas sumber daya ditambah apa pun yang secara sah memvariasikan respons (bahasa, mata uang, kelas perangkat) dan tidak ada yang lain. Normalisasi kunci agar perbedaan sepele seperti urutan parameter kueri tidak memecah cache.
TTL layak mendapat pemikiran yang sama. TTL adalah janji tentang kebasian maksimum yang akan Anda sajikan, jadi tetapkan dari toleransi nyata data, bukan angka bulat yang ditebak seseorang: ticker saham menoleransi detik, katalog produk menit, regulasi terbit jam atau kunci berversi tanpa kedaluwarsa sama sekali. Tambahkan sebaran acak kecil, disebut jitter, agar kumpulan entri yang ditulis bersamaan tidak semuanya kedaluwarsa pada detik yang sama dan men-stampede origin. Tuliskan pilihan ini, karena TTL tanpa alasan adalah angka yang akan ditakuti diubah insinyur berikutnya.
Lindungi dari stampede dan gabungkan permintaan
Ketika entri ter-cache populer kedaluwarsa, setiap permintaan yang menginginkannya meleset sekaligus dan menyerbu origin bersama. Inilah cache stampede, juga disebut thundering herd, dan ia dapat menjatuhkan basis data yang justru dilindungi cache. Bangun pertahanannya sekali dan pakai ulang di mana-mana. Penggabungan permintaan (single-flight) membiarkan hanya permintaan pertama untuk kunci yang hilang menghitung ulang nilainya sementara yang lain menunggu hasilnya, sehingga seribu kemelesetan serentak menyebabkan satu panggilan origin. Komputasi ulang awal probabilistik menyegarkan entri panas secara acak sedikit sebelum kedaluwarsa, sehingga satu permintaan latar belakang memperbaruinya sebelum keramaian melihat kemelesetan. Kebijakan stale-while-revalidate menyajikan salinan yang sedikit basi seketika dan menyegarkannya secara asinkron, sehingga pengguna tidak pernah menunggu pada kemelesetan sama sekali.
Pola ini paling penting persis ketika Anda paling membutuhkan cache, di bawah beban puncak, jadi validasi pada skala realistis: pertahanan yang berfungsi dengan sepuluh pengguna masih bisa gagal pada sepuluh ribu. Padukan dengan pola ketahanan bab 3.5, terutama timeout dan circuit breaker, agar ketika origin benar-benar lambat lapisan cache Anda melindunginya alih-alih menumpuk. Tujuannya cache yang berperilaku terbaik di bawah tekanan, bukan yang memperkuat lonjakan menjadi pemadaman.
Pilih pola tulis dengan sengaja
Cara Anda menangani penulisan menentukan seberapa segar cache Anda tetap dan seberapa banyak yang Anda pertaruhkan saat gagal. Ada empat pola umum. Dalam cache-aside (lazy loading), aplikasi memeriksa cache, dan saat meleset membaca origin, mengisi cache, dan mengembalikan nilai; penulisan pergi ke origin dan meng-invalidasi entri. Ia bawaan dengan alasan baik: sederhana, dan cache hanya menyimpan apa yang diminta. Dalam write-through, setiap penulisan pergi ke cache dan origin bersama, sehingga cache selalu mutakhir, dengan biaya latensi tulis dan meng-cache data yang mungkin tak pernah dibaca. Dalam write-back (write-behind), penulisan mengenai cache lebih dulu dan di-flush ke origin secara asinkron, membuat penulisan cepat tetapi berisiko hilang jika cache mati sebelum flush. Dalam write-around, penulisan langsung ke origin dan melewati cache, menghindari churn dari data banyak-tulis yang jarang dibaca, dengan biaya kemelesetan pembacaan pertama yang pasti.
Pilih per beban kerja, bukan sekali untuk seluruh sistem. Katalog banyak-baca cocok dengan cache-aside atau write-through. Log atau aliran metrik banyak-tulis cocok dengan write-around, agar cache tidak ter-churn oleh data yang tak dibaca ulang siapa pun. Write-back cocok untuk penulisan throughput tinggi di mana risiko kehilangan kecil yang dipahami dapat diterima dan ketahanan ditangani di tempat lain. Nyatakan pola untuk setiap cache secara eksplisit, karena pembaca yang mengasumsikan cache-aside padahal kode melakukan write-back akan salah menilai kesegaran maupun perilaku kegagalan.
Cocokkan kebijakan eviksi dengan pola akses Anda
Cache punya ukuran tetap, jadi ketika penuh, sesuatu harus pergi. Kebijakan eviksi memutuskan apa. Least recently used (LRU) mengeluarkan entri yang tak tersentuh paling lama, bertaruh bahwa pemakaian terbaru memprediksi pemakaian mendatang, dan ia bawaan yang masuk akal. Least frequently used (LFU) mengeluarkan entri dengan hit paling sedikit, yang cocok untuk himpunan panas yang stabil di mana beberapa item selalu populer tetapi dapat menggenggam entri yang pernah panas dan tak pernah beradaptasi. Varian seperti segmented LRU dan kebijakan adaptif memadukan keterbaruan dan frekuensi; first-in-first-out dan kedaluwarsa berbasis waktu sederhana lebih murah tetapi lebih tumpul.
Cocokkan kebijakan dengan cara data Anda diakses: LFU atau kebijakan sadar-frekuensi untuk himpunan panas kecil yang jarang bergeser, LRU di tempat popularitas bergerak seiring waktu seperti berita atau konten tren. Apa pun yang Anda pilih, ukur cache agar himpunan panas muat, karena cache yang terlalu kecil menampung himpunan kerja akan thrashing, mengeluarkan entri tepat sebelum dibutuhkan lagi. Awasi tingkat eviksi sebagai metrik kelas satu, karena lonjakan mendadak biasanya berarti cache terlalu kecil atau ledakan kunci memecahnya.
Gunakan semantik caching HTTP dengan benar
Web punya model caching yang matang dan terstandar yang dibangun ke dalam HTTP, dan memakainya dengan baik memberi Anda caching klien dan CDN gratis. Header Cache-Control adalah permukaan kendali: max-age menetapkan masa kesegaran, public dan private mengatakan apakah cache bersama boleh menyimpan respons, no-store melarang caching, dan stale-while-revalidate mengizinkan menyajikan salinan basi sambil menyegarkan. Validasi memungkinkan cache memeriksa kesegaran dengan murah tanpa mengambil ulang badan. ETag (entity tag) adalah pengidentifikasi versi buram yang dilampirkan server pada respons; klien mengirimnya kembali dalam header If-None-Match, dan server membalas 304 Not Modified tanpa badan jika tidak ada yang berubah. Last-Modified dengan If-Modified-Since melakukan hal sama memakai stempel waktu.
Disiplin praktisnya adalah eksplisit. Tetapkan Cache-Control pada setiap respons alih-alih membiarkan cache menebak dengan heuristik. Tandai respons privat per pengguna sebagai private atau no-store agar proksi bersama tidak pernah menyimpannya, kesalahan umum dan berbahaya. Gunakan URL berversi dengan max-age panjang dan direktif immutable untuk aset statis, dan validasi dengan ETag untuk konten yang berubah tak terduga. Mendapatkan header ini dengan benar mengubah seluruh tingkat klien dan CDN menjadi cache berbasis standar yang benar yang tidak perlu Anda bangun.
Dorong kerja ke tepi dengan CDN dan komputasi tepi
CDN dimulai sebagai cara meng-cache berkas statis dekat pengguna, dan ia masih melakukannya dengan luar biasa: gambar, skrip, video, dan unduhan disajikan dari lokasi tepi beberapa milidetik jauhnya alih-alih origin yang jauh. CDN modern melangkah lebih jauh. Mereka meng-cache konten dinamis dan personal dengan kunci berbutir halus, mengakhiri TLS di tepi, menyerap lonjakan lalu lintas dan serangan distributed denial-of-service, dan makin sering menjalankan kode Anda. Komputasi tepi mengeksekusi logika di lokasi tepi itu sendiri, sehingga Anda dapat mempersonalisasi respons, memeriksa otorisasi, atau merakit fragmen halaman tanpa round trip ke wilayah pusat.
Bersandarlah pada ini untuk pembacaan yang mendominasi kebanyakan sistem. Taruh aset statis di balik CDN dengan URL berversi berumur panjang, cache respons API di tepi di tempat kesegaran mengizinkan (dikunci dengan hati-hati agar personalisasi tidak bocor), dan pakai komputasi tepi untuk logika ringan yang peka latensi dekat pengguna. Pertukarannya jangkauan versus kendali: tepi cepat dan dekat tetapi jauh dari data Anda dan lebih sulit di-debug, jadi jaga apa pun yang membutuhkan konsistensi kuat atau status berwenang yang segar di origin dan biarkan tepi menangani lalu lintas baca luas yang dapat di-cache.
Perlakukan cache sebagai permukaan serangan
Cache menyajikan respons tersimpan yang sama kepada banyak pengguna, yang menjadikannya target. Cache poisoning adalah serangan di mana permintaan dirancang agar cache menyimpan respons berbahaya atau dikendalikan penyerang lalu menyajikannya kepada semua yang mengikuti. Ia biasanya mengeksploitasi masukan tak berkunci: header yang dipantulkan aplikasi ke respons tetapi diabaikan cache saat membangun kunci. Serangan web cache deception yang terkait menipu cache untuk menyimpan respons privat korban di bawah URL publik. Keduanya kegagalan pengunciaan dan memercayai masukan, dibahas lebih luas di bab 4.2.
Bertahanlah dengan sengaja. Sertakan dalam kunci cache setiap masukan yang dapat mengubah respons, dan tolak memantulkan header tak berkunci ke badan ter-cache. Jangan pernah membiarkan cache bersama menyimpan respons terautentikasi per pengguna di bawah kunci bersama. Normalisasi dan validasi path serta parameter permintaan sebelum caching. Setel Vary dengan benar agar cache mempartisi respons menurut header yang benar-benar penting, seperti pengkodean konten atau bahasa. Karena satu entri teracuni merugikan setiap pengguna hilir, perlakukan konfigurasi cache sebagai kode peka-keamanan dan tinjau sebagaimana mestinya.
Buat perilaku cache dapat diobservasi
Anda tidak dapat mengelola cache yang tidak dapat Anda lihat. Metrik utamanya hit rate: pecahan permintaan yang dilayani dari cache alih-alih origin. Hit rate yang diam-diam turun dari 95 ke 70 persen dapat melipatgandakan beban origin beberapa kali dan mendahului pemadaman, dan Anda hanya akan menangkapnya dini jika mengawasinya. Instrumentasikan setiap lapisan secara terpisah, karena hit rate CDN yang sehat dapat menyembunyikan hit rate cache aplikasi yang runtuh di bawahnya. Ini wajah khusus-caching dari praktik observabilitas di bab 9.2.
Lacak lebih dari hit: tingkat eviksi dan tekanan memori untuk menangkap ukuran yang kurang, latensi pada setiap lapisan untuk memastikan cache benar-benar lebih cepat, laju permintaan origin untuk melihat seberapa banyak beban yang diserap cache, dan kebasian (seberapa tua entri yang disajikan) untuk memastikan Anda menghormati janji kesegaran. Beri peringatan pada rasio yang memprediksi masalah, terutama hit rate yang turun atau tingkat eviksi yang naik, agar Anda mengetahui cache yang merosot dari dasbor alih-alih dari pengguna. Cache yang teramati adalah aset yang dapat Anda setel; yang tak teramati adalah dependensi tersembunyi yang menunggu mengejutkan Anda.
Trade-off: kelebihan dan kekurangan
Caching membeli kecepatan dan skala dengan mata uang kesegaran dan kompleksitas. Setiap cache adalah taruhan bahwa basi-tapi-cepat mengalahkan segar-tapi-lambat untuk data tertentu ini, dan seninya menempatkan taruhan itu secara sadar alih-alih secara bawaan. Tabel di bawah merangkum pilihan utama.
| Pilihan | Kelebihan | Kekurangan |
|---|---|---|
| Cache-aside | Sederhana; hanya meng-cache apa yang dibaca | Pembacaan pertama selalu meleset; risiko kebasian singkat setelah penulisan |
| Write-through | Cache selalu mutakhir saat menulis | Penulisan lebih lambat; meng-cache data yang mungkin tak pernah dibaca |
| Write-back | Penulisan sangat cepat; menyerap lonjakan | Risiko kehilangan data jika cache gagal sebelum flush |
| Write-around | Menghindari churn cache oleh data banyak-tulis | Kemelesetan pasti pada pembacaan pertama |
| TTL pendek | Kebasian terbatas dan kecil | Hit rate lebih rendah; lebih banyak beban origin |
| TTL panjang / kunci berversi | Hit rate tinggi; beban origin rendah | Kebasian kecuali di-invalidasi; butuh kunci yang disiplin |
| CDN dan tepi | Latensi rendah global; menyerap lonjakan | Jauh dari data; lebih sulit di-debug dan di-invalidasi |
| Eviksi LRU | Beradaptasi dengan popularitas yang bergeser | Dapat mengeluarkan himpunan panas stabil di bawah beban banyak-pindai |
| Eviksi LFU | Melindungi himpunan panas stabil | Lambat beradaptasi; menggenggam entri yang dulu panas |
Ketegangan yang berulang adalah konsistensi versus kinerja. Cache dengan TTL panjang dan hit rate tinggi cepat dan murah dan dapat menyajikan data basi; cache dengan TTL pendek dan invalidasi agresif segar dan benar dan membuat origin bekerja lebih keras. Tidak ada jawaban benar universal, hanya jawaban benar per bagian data, ditetapkan oleh toleransi nyatanya terhadap kebasian. Ketegangan kedua adalah kesederhanaan versus jangkauan: cache aplikasi dekat dengan data Anda dan mudah dinalar, sementara tepi jauh, cepat, dan lebih sulit di-invalidasi. Selesaikan keduanya dengan mengklasifikasikan data Anda menurut kebutuhan kesegaran dan volume baca, lalu menempatkan dan mengonfigurasi setiap kelas dengan sengaja.
Pertanyaan untuk didiskusikan dengan tim Anda
Berapa toleransi kebasian nyata setiap jenis data yang kita cache, dan sudahkah kita menetapkan TTL dan invalidasi dari toleransi itu alih-alih dari kebiasaan? Kebanyakan tim melakukan caching dengan TTL yang dipilih seseorang sekali dan tak pernah ditinjau ulang, sehingga sebagian data disajikan lebih basi daripada yang dapat diterima bisnis sementara data lain kedaluwarsa begitu agresif sehingga cache nyaris tak membantu. Bawa sepuluh sumber daya ter-cache teratas Anda dan, untuk masing-masing, tanyakan kepada pemilik data itu seberapa basi ia boleh dengan aman: detik, menit, jam, atau tak pernah setelah terbit. Anda biasanya akan menemukan jawaban sangat bervariasi dan TTL Anda saat ini tidak cocok dengannya. Hasil yang Anda inginkan adalah klasifikasi kesegaran singkat, setiap kelas dipetakan ke pendekatan (TTL pendek, TTL panjang plus pembersihan, atau kunci berversi yang tak berubah), sehingga keputusan caching mengikuti semantik data alih-alih tebakan.
Jika entri cache paling populer kita kedaluwarsa sekarang di bawah lalu lintas puncak, apa yang akan terjadi pada origin? Pertanyaan ini mengungkap apakah Anda punya perlindungan stampede nyata atau hanya harapan. Banyak sistem berjalan baik sampai kunci panas kedaluwarsa selama puncak lalu lintas dan setiap permintaan menstampede basis data sekaligus, mengubah cache dari perisai menjadi pemicu. Telusuri jalurnya secara konkret untuk endpoint tersibuk Anda: apakah ada penggabungan permintaan sehingga hanya satu kemelesetan mencapai origin, apakah ada jitter sehingga entri tidak kedaluwarsa serentak, apakah ada kebijakan stale-while-revalidate sehingga pengguna tidak pernah menunggu pengisian ulang? Bawa bukti uji beban, bukan intuisi, karena pertahanan stampede yang bertahan pada sepuluh pengguna masih dapat runtuh pada sepuluh ribu. Jika Anda tidak dapat menjawab dengan yakin, investasi ketahanan Anda berikutnya baru saja menemukan Anda.
Apakah kita yakin tidak ada cache bersama yang pernah menyimpan data privat satu pengguna di bawah kunci yang dapat dicapai pengguna lain? Ini kesalahan caching yang menjadi insiden keamanan dan berita utama. Ia terjadi ketika respons personal atau terautentikasi di-cache di bawah kunci yang menghilangkan identitas pengguna, atau ketika header
Cache-Controlyang dimaksudkan menjaga respons privat hilang, sehingga proksi bersama atau CDN menyimpannya dan menyajikannya kepada orang berikutnya. Audit respons mana yang dapat di-cache pada lapisan bersama, pastikan setiap respons per pengguna ditandaiprivateatauno-store, dan pastikan setiap kunci cache menyertakan setiap masukan yang mengubah respons. Perlakukan ini sebagai tinjauan keamanan, karena radius ledakannya setiap pengguna hilir, dan kaitkan dengan praktik di bab 4.2.Pola tulis mana yang sebenarnya dipakai setiap cache kita, dan apakah seseorang memilihnya dengan sengaja? Cache-aside, write-through, write-back, dan write-around membuat janji berlawanan tentang kesegaran dan tentang apa yang hilang ketika cache gagal, namun di kebanyakan basis kode polanya apa pun yang kebetulan disalin penulis pertama. Bagi tim besar ini penting karena satu layanan yang mengasumsikan kesegaran cache-aside sementara yang lain diam-diam menjalankan write-back dapat menghasilkan data yang tampak rusak padahal hanya basi, dan insinyur on-call membuang jam mengejar hantu. Bawa inventaris per cache: pola tulis, kesegaran yang dijaminnya, dan apa yang terjadi pada penulisan yang belum di-flush jika proses mati. Di mana cache mana pun memakai write-back, bawa kisah ketahanan yang mendukungnya. Dalam sistem enterprise dan pemerintah yang menangani data keuangan atau catatan, cache write-back tanpa jaminan pendukung adalah temuan audit yang menunggu terjadi, jadi diskusi harus berakhir dengan pola setiap cache dinamai, dibenarkan, dan dituliskan.
Ketika kita men-deploy atau mengubah data, apakah setiap lapisan cache yang relevan meng-invalidasi dengan benar, atau kita bergantung pada seseorang mengingat untuk membersihkan? Invalidasi adalah bagian sulit, dan mode kegagalannya senyap: nilai yang diperbaiki yang tetap salah selama berjam-jam karena satu lapisan hierarki, CDN, reverse proxy, atau cache aplikasi, tak pernah menerima pesan. Organisasi besar melipatgandakan risiko ini, karena satu perubahan logis mungkin perlu merambat ke banyak cache di banyak wilayah yang dimiliki tim berbeda. Bawa jejak konkret satu perubahan data terbaru dan ikuti melalui setiap lapisan cache, bertanya pada masing-masing: apa yang memicu invalidasi di sini, dan berapa lama? Pilih desain yang mengubah invalidasi menjadi penamaan (kunci berversi) atau menjadi peristiwa (perubahan menerbitkan pembersihan) daripada runbook manual. Dalam sistem sektor publik di mana angka terbit yang salah, tarif pajak atau jumlah tunjangan, dapat membawa bobot hukum, celah invalidasi bukan gangguan melainkan paparan kepatuhan, sehingga hasilnya harus jalur invalidasi yang dipetakan untuk setiap kelas data ter-cache.
Apakah kita memperlakukan caching sebagai infrastruktur platform bersama, atau setiap tim menciptakan ulang kunci, invalidasi, dan perlindungan stampede sendiri? Caching yang dilakukan baik adalah sekumpulan kecil masalah sulit yang diselesaikan sekali: kunci ternormalisasi, invalidasi berbasis peristiwa, penggabungan permintaan, semantik HTTP yang benar, dan observabilitas per lapisan. Ketika setiap tim berimprovisasi, organisasi besar membayar kesalahan yang sama berulang kali, dan bug pencemaran atau kebocoran data privat yang diperbaiki di satu layanan diam-diam bertahan di sepuluh lainnya. Bawa peta jujur siapa yang memiliki konvensi caching hari ini dan seberapa banyak kode caching duplikat ada di seluruh layanan. Pertimbangan yang bersaing adalah otonomi: tim menolak pustaka bersama yang diwajibkan, jadi timbang bawaan jalan-beraspal yang mudah diadopsi terhadap standar keras yang ditegakkan. Bagi grup platform enterprise atau pemerintah, kemampuan caching bersama yang teruji baik juga cara termurah membuat persyaratan keamanan dan audit berlaku seragam, jadi diskusi harus memutuskan apa yang menjadi infrastruktur bersama dan siapa yang mendanainya.
Lensa sektor
Startup. Caching adalah jalur termurah Anda untuk selamat dari lonjakan lalu lintas yang belum sanggup Anda skalakan, jadi belanjakan sedikit waktu Anda pada beberapa penempatan berpengungkit tinggi: CDN dengan URL berversi untuk aset statis, dan satu lapisan cache-aside dengan TTL pendek dan jitter di depan kueri terpanas Anda. Bersandarlah pada layanan CDN dan cache terkelola alih-alih menjalankan sendiri, dan tambahkan penggabungan permintaan sejak dini, karena stampede hari peluncuran terhadap basis data kecil adalah kegagalan yang paling mungkin mengakhiri hari baik dengan buruk. Lewati skema invalidasi rumit sampai Anda punya data yang mengatakan itu penting.
Bisnis kecil. Tanpa spesialis caching dan dengan anggaran ketat, pilih membeli caching yang Anda dapat gratis di dalam perkakas yang sudah Anda jalankan: CDN yang dibundel dengan hosting Anda, header HTTP Cache-Control pada respons kerangka web Anda, dan cache kueri bawaan basis data Anda. Pilihan bangun-versus-beli hampir selalu condong ke beli di sini, karena cache yang salah kunci yang membocorkan data satu pelanggan kepada yang lain berbiaya jauh lebih besar daripada layanan terkelola yang Anda hindari. Dapatkan dua kemenangan murah dengan benar, header HTTP yang tepat dan tidak pernah meng-cache halaman terautentikasi di lapisan bersama, dan biarkan pola eksotis.
Enterprise. Pada skala besar lintas banyak tim risikonya bergeser dari cache tunggal mana pun ke inkonsistensi di antara mereka: skema kunci yang menyimpang, invalidasi yang tidak merata, dan kebocoran data privat yang muncul di satu layanan dan tidak di yang lain. Sediakan caching sebagai infrastruktur platform bersama dengan bawaan jalan-beraspal untuk kunci, invalidasi, perlindungan stampede, dan observabilitas per lapisan, agar hit rate, eviksi, dan kebasian terlihat di satu tempat dan diatur seragam. Jadikan konfigurasi cache dapat ditinjau sebagai kode peka-keamanan, dan perlakukan invalidasi lintas wilayah sebagai masalah desain kelas satu alih-alih runbook per tim.
Pemerintah. Kendala pengadaan dan transparansi membentuk apa yang dapat Anda cache dan bagaimana Anda membuktikannya aman. Cache konten publik secara agresif, panduan, formulir, dan tabel tarif di balik CDN dengan TTL panjang, agar lonjakan tenggat pengajuan diserap jauh dari origin, dan dokumentasikan konfigurasi itu untuk audit. Halaman terautentikasi yang menampilkan catatan milik warga sendiri tidak boleh menyentuh cache bersama, dan aturan itu harus dapat diverifikasi, bukan sekadar ditegaskan. Di mana CDN atau layanan caching dibeli dari vendor, wajibkan kontrak mengekspos kendali yang Anda butuhkan (kunci, pembersihan, dan pencatatan) dan hindari lock-in yang akan menjebak data publik di balik format cache proprietari.
Contoh
Startup. Sebuah aplikasi konsumen kecil menjalankan katalog produknya melalui lapisan cache-aside yang didukung penyimpanan dalam memori, dengan TTL 60 detik dan jitter agar entri tidak kedaluwarsa bersamaan. Aset statis pergi ke CDN dengan nama berkas berversi dan max-age satu tahun, sehingga deploy yang mengubah stylesheet menyajikan URL baru dan tidak pernah perlu pembersihan. Ketika peluncuran di podcast populer mengirim lonjakan lalu lintas, penggabungan single-flight berarti ribuan kemelesetan beranda serentak menyebabkan satu pembacaan basis data, bukan ribuan. Para pendiri hampir tidak mengeluarkan apa pun untuk caching namun menangani lonjakan yang akan melelehkan basis data kecil mereka, karena mereka menempatkan beberapa cache pilihan dengan sengaja.
Enterprise. Sebuah pengecer global melayani jutaan pembeli melalui cache berlapis: CDN untuk gambar dan respons API yang dapat di-cache, cache reverse proxy bersama di setiap wilayah, dan cache aplikasi untuk fragmen harga dan inventaris terhitung. Kunci cache dinormalisasi dan menyertakan mata uang, bahasa, dan kelas perangkat, sehingga personalisasi tidak pernah bocor dan hit rate tetap tinggi. Data produk memakai TTL pendek dengan invalidasi berbasis peristiwa, sehingga perubahan harga menerbitkan ke bus pesan yang membersihkan kunci terdampak lintas wilayah dalam hitungan detik. Setiap lapisan melaporkan hit rate, tingkat eviksi, dan kebasian ke platform observabilitas bab 9.2, dan peringatan pada hit rate yang turun pernah menangkap cache yang terlalu kecil sebelum menjadi pemadaman checkout.
Pemerintah. Sebuah otoritas pajak nasional menjalankan portal pengajuan yang sepi sebagian besar tahun dan kewalahan mendekati tenggat. Tim melakukan caching secara agresif di tempat itu aman dan tidak pernah di tempat tidak. Konten publik (halaman panduan, formulir, tabel tarif) disajikan dari CDN dengan TTL panjang dan URL berversi, menyerap lonjakan baca hari tenggat jauh dari origin. Halaman terautentikasi yang menampilkan pengajuan milik warga ditandai no-store dan tidak pernah menyentuh cache bersama, sehingga tak ada wajib pajak yang pernah disajikan data orang lain. Konfigurasi cache ditinjau sebagai kode peka-keamanan terhadap praktik bab 4.2, dan perlindungan stampede diuji beban pada skala tenggat berbulan-bulan sebelumnya, sehingga portal yang dulu ambruk pada hari tersibuk tahun ini kini bertahan.
Kasus bisnis: motivasi, ROI, dan TCO
Imbal hasil caching tidak biasa langsung dan mudah dikuantifikasi. Cache yang menaikkan hit rate dari 80 ke 95 persen memangkas lalu lintas origin tiga perempat, yang dapat berarti menunda peningkatan basis data, menjalankan lebih sedikit server aplikasi, atau selamat dari lonjakan lalu lintas yang kalau tidak membutuhkan penskalaan darurat. Peningkatan latensi berubah menjadi pendapatan di perdagangan dan menjadi kepuasan serta tingkat penyelesaian di layanan publik, di mana penelitian sejak lama mengaitkan halaman lebih cepat dengan konversi lebih tinggi dan pengabaian lebih rendah. Biaya egress dan komputasi turun karena permintaan yang dilayani dari tepi tidak pernah membayar bandwidth atau pemrosesan origin. Untuk sistem banyak-baca, yang merupakan kebanyakan sistem, caching sering kali kinerja termurah yang dapat Anda beli.
Timbang total biaya kepemilikan dengan jujur. Biaya langsungnya sederhana: infrastruktur CDN dan cache murah dibanding kapasitas origin yang dihematnya. Biaya sebenarnya adalah disiplin rekayasa, karena cache yang salah lebih buruk daripada tanpa cache. Bug kebasian, kesalahan invalidasi, dan kerentanan cache-poisoning semuanya membawa biaya nyata, dan tumbuh ketika caching diimprovisasi per tim alih-alih disediakan sebagai kemampuan bersama yang teruji baik. Kasus bisnis terkuat mendanai sejumlah kecil infrastruktur dan konvensi caching bersama (kunci standar, invalidasi, perlindungan stampede, dan observabilitas) agar setiap tim mendapat manfaat tanpa mengulang kesalahan. Dibingkai untuk pimpinan, caching terhubung dengan metrik yang sudah mereka lacak: biaya infrastruktur, latensi halaman, tingkat konversi dan penyelesaian, serta frekuensi insiden selama peristiwa puncak.
Anti-pola dan jebakan
- Caching tanpa invalidasi: menetapkan TTL panjang tanpa cara membersihkan, sehingga nilai yang diperbaiki tetap salah selama berjam-jam.
- Kunci terlalu kasar: meng-cache respons personal di bawah kunci bersama, membocorkan data satu pengguna kepada yang lain.
- Kunci terlalu halus: menyertakan masukan volatil dalam kunci sehingga tak ada dua permintaan yang pernah cocok dan hit rate runtuh.
- Tanpa perlindungan stampede: kunci panas kedaluwarsa di bawah beban dan setiap permintaan menyerbu origin sekaligus.
- Kedaluwarsa tersinkron: kumpulan entri yang ditulis bersama semuanya kedaluwarsa pada detik yang sama tanpa jitter, menyebabkan thundering herd periodik.
- Meng-cache data privat di lapisan bersama:
Cache-Control: privateatauno-storehilang, sehingga proksi atau CDN menyimpan respons terautentikasi. - Mengabaikan masukan tak berkunci: memantulkan header ke badan respons tetapi menghilangkannya dari kunci, membuka pintu bagi cache poisoning.
- Cache terlalu kecil: cache yang terlalu kecil menampung himpunan kerja thrashing dan mengeluarkan entri tepat sebelum dibutuhkan.
- Cache tak terukur: tanpa metrik hit-rate atau eviksi, sehingga cache yang merosot tak terlihat sampai menjadi pemadaman.
- Write-back tanpa ketahanan: penulisan cepat yang lenyap ketika cache mati sebelum flush, tanpa jaminan pendukung.
Model kematangan
- Tingkat 1, Memulai: Caching ad hoc dan per pengembang, ditambahkan secara reaktif ketika sesuatu terasa lambat. TTL ditebak, kunci tidak konsisten, invalidasi manual atau tidak ada, dan data basi serta bug misterius lazim. Tak seorang pun melacak hit rate, dan lonjakan lalu lintas yang seharusnya diserap cache justru menyebabkan pemadaman.
- Tingkat 2, Mengembangkan: Tim melakukan caching di tempat-tempat yang jelas dan memakai CDN untuk aset statis. TTL dasar dan cache-aside muncul, tetapi konvensi bervariasi dari layanan ke layanan, invalidasi tidak konsisten, perlindungan stampede hilang, aturan caching privat-versus-bersama informal, dan observabilitas terbatas pada pemeriksaan sesekali.
- Tingkat 3, Membakukan: Strategi caching terdokumentasi dan ditegakkan di seluruh organisasi. Kunci cache dinormalisasi, TTL mengikuti klasifikasi kesegaran bersama, invalidasi berbasis peristiwa di tempat yang penting, perlindungan stampede dan semantik HTTP yang benar adalah standar, data privat tidak pernah di-cache di lapisan bersama, dan setiap lapisan melaporkan hit rate dan eviksi ke pipeline observabilitas bersama.
- Tingkat 4, Mengelola: Caching diukur dan dikendalikan terhadap garis dasar. Setiap lapisan punya target hit rate, anggaran kebasian, dan ambang eviksi, dan dasbor memberi peringatan ketika hit rate turun atau tingkat eviksi naik melewati garis dasarnya. Pertahanan stampede diuji beban pada skala puncak, pengurangan beban origin dikuantifikasi per cache, TTL dan kebijakan eviksi disetel dari pola akses terukur, dan konfigurasi cache ditinjau sebagai kode peka-keamanan sebelum rilis.
- Tingkat 5, Mengorkestrasi: Caching terus diperbaiki dan terintegrasi di seluruh organisasi. Penempatan, kunci, dan TTL beradaptasi dengan lalu lintas yang bergeser, komputasi tepi dipakai di tempat ia layak, perencanaan kapasitas dan model biaya menarik dari metrik cache, dan pelajaran dari insiden satu tim memberi makan konvensi bersama. Organisasi memperlakukan caching sebagai kemampuan yang dirancang, terukur, dan adaptif alih-alih kumpulan peretasan lokal.
Gagasan untuk didiskusikan
- Cache tunggal mana dalam sistem Anda yang, jika menjadi dingin sekarang, paling membahayakan origin Anda, dan apa yang melindunginya?
- Untuk setiap lapisan hierarki cache Anda, dapatkah Anda menyebut hit rate saat ini dari ingatan, dan jika tidak, apa yang dikatakan itu kepada Anda?
- Di mana Anda telah mengubah masalah invalidasi menjadi masalah penamaan dengan kunci berversi, dan di mana Anda masih dapat melakukannya?
- Jalur tulis Anda yang mana yang memakai cache-aside, write-through, write-back, atau write-around, dan apakah masing-masing dipilih dengan sengaja?
- Jika penyerang mengendalikan satu header permintaan, dapatkah mereka meracuni respons ter-cache mana pun yang dibagi pengguna Anda?
- Bagaimana Anda akan tahu, dalam hitungan menit, bahwa hit rate Anda diam-diam turun dua puluh poin?
Poin-poin utama
- Caching memangkas latensi, beban, dan biaya, dan hierarki cache (klien, CDN dan tepi, reverse proxy, aplikasi, basis data) memungkinkan Anda menjawab sejauh ke atas dan ke luar yang dapat dilakukan dengan aman.
- Invalidasi adalah bagian sulit; rancang kunci cache dan TTL dengan sengaja, dan ubah masalah invalidasi menjadi masalah penamaan dengan kunci berversi di mana pun Anda bisa.
- Lindungi cache di bawah beban dengan penggabungan permintaan, jitter, dan stale-while-revalidate, karena cache paling dibutuhkan persis ketika stampede dapat merusaknya.
- Pilih pola tulis dan kebijakan eviksi per beban kerja, dan gunakan semantik caching HTTP (
Cache-Control, ETag, validasi) secara eksplisit alih-alih membiarkan cache menebak. - Perlakukan konten ter-cache sebagai permukaan serangan dan ukur hit rate, eviksi, dan kebasian, karena cache yang tak teramati atau salah kunci adalah liabilitas tersembunyi, bukan aset.
Referensi dan bacaan lanjutan
- Martin Kleppmann, Designing Data-Intensive Applications
- Andrew S. Tanenbaum dan Herbert Bos, Modern Operating Systems
- John L. Hennessy dan David A. Patterson, Computer Architecture: A Quantitative Approach
- Roy T. Fielding dan Julian Reschke, “Hypertext Transfer Protocol (HTTP/1.1): Caching,” RFC 7234, IETF
- Mark Nottingham, “Caching Tutorial for Web Authors and Webmasters”
- James Kettle, “Practical Web Cache Poisoning,” PortSwigger Research
- Betsy Beyer, Chris Jones, Jennifer Petoff, dan Niall Richard Murphy (ed.), Site Reliability Engineering: How Google Runs Production Systems
- Michael T. Nygard, Release It! Design and Deploy Production-Ready Software