Redis menyimpan semua di RAM, sehingga kehabisan memori adalah mode kegagalan paling umum. maxmemory menetapkan batas, dan maxmemory-policy menentukan apa yang terjadi saat batas tercapai. Kesalahan paling sering adalah membiarkan policy pada noeviction untuk beban kerja cache, yang membuat penulisan gagal alih-alih membuang data lama. Rasio fragmentasi dan MEMORY USAGE adalah alat diagnosis utama.
1. Menetapkan Batas Memori
maxmemory 4gb maxmemory-policy allkeys-lru maxmemory-samples 5
Bila maxmemory tidak disetel, Redis akan terus memakai RAM sampai kernel Linux mematikan prosesnya secara paksa. Seluruh data di RAM lenyap seketika, dan pemulihan dari AOF/RDB bisa memakan waktu lama. Selalu setel maxmemory โ kira-kira 60โ70% dari total RAM mesin, menyisakan ruang untuk proses fork saat BGSAVE.
2. Delapan Kebijakan Eviction
| Kebijakan | Perilaku | Cocok untuk |
|---|---|---|
noeviction | Tolak semua penulisan baru saat penuh (default) | Redis sebagai penyimpan utama, bukan cache |
allkeys-lru | Buang key yang paling lama tidak diakses, dari seluruh key | Cache umum โ pilihan paling sering benar |
allkeys-lfu | Buang key yang paling jarang diakses | Cache dengan pola akses yang stabil & berulang |
allkeys-random | Buang key acak | Bila semua key sama pentingnya; sangat murah |
volatile-lru | LRU, tapi hanya pada key yang punya TTL | Campuran data permanen & cache dalam satu instans |
volatile-lfu | LFU, hanya pada key ber-TTL | Sama, dengan pola akses berulang |
volatile-random | Acak, hanya pada key ber-TTL | Jarang dipakai |
volatile-ttl | Buang yang TTL-nya paling dekat kedaluwarsa | Bila TTL benar-benar mencerminkan prioritas |
volatile-*
Bila kebijakan Anda volatile-lru tetapi tidak ada satu pun key yang punya TTL, Redis tidak punya kandidat untuk dibuang. Perilakunya kembali seperti noeviction: penulisan gagal dengan error OOM meski Anda mengira sudah mengatur eviction. Ini penyebab insiden yang sangat sering terjadi.
LRU membuang yang paling lama tidak disentuh. Kelemahannya: satu kali pemindaian besar (misal laporan batch yang membaca ribuan key sekali saja) bisa menggusur data panas. LFU menghitung frekuensi akses, sehingga key yang cuma disentuh sekali oleh batch tidak akan menggusur key yang diakses ribuan kali. Untuk cache produksi dengan pola trafik nyata, LFU sering lebih baik.
3. LRU di Redis Bersifat Perkiraan
Redis tidak menyimpan daftar LRU yang sempurna karena itu boros memori. Sebagai gantinya ia mengambil maxmemory-samples key secara acak dan membuang yang terburuk di antara sampel itu.
maxmemory-samples 5 # default: cepat, cukup akurat maxmemory-samples 10 # lebih akurat, sedikit lebih mahal CPU
4. Membaca Kondisi Memori
INFO memory
Angka yang benar-benar perlu Anda perhatikan:
| Metrik | Arti |
|---|---|
used_memory | Memori yang dipakai untuk data, menurut Redis |
used_memory_rss | Memori yang benar-benar dipesan dari sistem operasi |
mem_fragmentation_ratio | rss dibagi used_memory |
maxmemory | Batas yang Anda setel |
evicted_keys | Jumlah key yang sudah dibuang โ naik terus artinya cache terlalu kecil |
keyspace_hits / keyspace_misses | Bahan menghitung hit rate cache |
- Sekitar 1,0โ1,5 โ sehat dan normal.
- Di atas 1,5 โ fragmentasi tinggi. Aktifkan
activedefrag yes. - Di bawah 1,0 โ sebagian memori Redis sudah ditukar ke disk (swap). Ini gawat: latensi Redis akan meledak dari mikrodetik menjadi milidetik. Matikan swap atau kecilkan
maxmemory.
5. Menemukan Key yang Rakus
# Ukuran satu key tertentu dalam byte MEMORY USAGE pesanan:1001 # Ringkasan alokasi memori keseluruhan MEMORY DOCTOR MEMORY STATS # Memindai key terbesar TANPA memblokir server. # Jalankan dari terminal, bukan dari dalam redis-cli. redis-cli --bigkeys # Sampel distribusi ukuran key & TTL redis-cli --memkeys redis-cli --hotkeys # butuh maxmemory-policy berbasis LFU
Satu Hash berisi sejuta field atau satu List berisi jutaan elemen akan membuat operasi seperti HGETALL atau DEL memblokir Redis yang single-threaded selama puluhan hingga ratusan milidetik. Semua client lain ikut tertahan. Pecah struktur besar menjadi banyak key kecil, dan gunakan UNLINK (penghapusan asinkron) sebagai ganti DEL untuk objek besar.
6. Menghemat Memori
- Pendekkan nama key.
u:1:njauh lebih hemat daripadauser:1:nama_lengkapbila Anda punya puluhan juta key. Tapi jangan berlebihan sampai tidak terbaca. - Manfaatkan pengkodean hemat. Hash, List, Set, dan ZSet berukuran kecil disimpan dalam bentuk terkompresi (listpack). Ambangnya diatur oleh
hash-max-listpack-entries,zset-max-listpack-entries, dan sejenisnya. Melewati ambang itu, konsumsi memori melonjak drastis. - Pilih Hash daripada banyak key String. Satu Hash berisi 100 field jauh lebih hemat daripada 100 key String terpisah, karena tiap key punya biaya overhead sendiri.
- Selalu pasang TTL pada data cache. Data tanpa TTL akan menumpuk selamanya.
- Aktifkan defragmentasi aktif bila rasio fragmentasi tinggi:
activedefrag yes.
7. Memantau Kesehatan Cache
hit rate = keyspace_hits / (keyspace_hits + keyspace_misses)
Hit rate di bawah 80% biasanya berarti cache Anda terlalu kecil, TTL terlalu pendek, atau yang Anda cache memang bukan data yang sering diminta ulang. Naiknya evicted_keys bersamaan dengan turunnya hit rate adalah tanda paling jelas bahwa maxmemory perlu dinaikkan.