Redis
Begitu aplikasimu berjalan di lebih dari satu proses, semua keadaan bersama harus punya rumah di luar aplikasi. Redis adalah rumah itu, dan Laravel memakainya untuk empat hal sekaligus.
Intisari
- Empat peran: cache, session, queue, dan lock.
- Pakai ekstensi
phpredisdi produksi โ jauh lebih cepat daripada klien PHP murni. - Pisahkan database atau prefiks per peran, supaya
cache:cleartidak menghapus antrean. - Redis adalah satu titik kegagalan kalau session, antrean, dan cache semuanya di sana.
- Setel
maxmemory-policy:allkeys-lruuntuk cache, tapi tidak untuk antrean.
Konfigurasi
REDIS_CLIENT=phpredis
REDIS_HOST=klaster.abc.cache.amazonaws.com
REDIS_PORT=6379
CACHE_STORE=redis
SESSION_DRIVER=redis
QUEUE_CONNECTION=redis
// config/database.php โ pisahkan per peran
'redis' => [
'options' => ['prefix' => env('REDIS_PREFIX', 'portal:')],
'default' => ['host' => env('REDIS_HOST'), 'database' => 0],
'cache' => ['host' => env('REDIS_HOST'), 'database' => 1],
'session' => ['host' => env('REDIS_HOST'), 'database' => 2],
],
Kenapa dipisah. php artisan cache:clear menjalankan FLUSHDB pada database
cache. Kalau antrean tinggal di database yang sama, satu perintah pembersihan cache akan
menghapus seluruh job yang belum diproses. Pemisahan ini murah dilakukan sekarang dan mahal
disesali nanti.
Empat peran
| Peran | Kenapa Redis | Kalau Redis mati |
|---|---|---|
| Cache | Cepat, dibagi semua kontainer | Semua permintaan jatuh ke database |
| Session | Pengguna tidak ter-logout saat berpindah kontainer | Semua pengguna ter-logout |
| Queue | Latensi rendah, mendukung Horizon | Job tidak bisa diantre maupun diproses |
| Lock | Penjadwal onOneServer, penguncian atomik | Tugas berjalan ganda |
Empat peran di satu layanan berarti satu titik kegagalan yang besar. Untuk aplikasi yang tidak boleh mati, pertimbangkan memisahkan setidaknya antrean dari cache โ atau memakai SQS untuk antrean sehingga pekerjaan tetap tersimpan meski Redis bermasalah. Di sisi lain, memisahkan berarti dua klaster yang harus dibayar dan dipantau. Putuskan berdasarkan seberapa mahal satu jam gangguan bagimu.
Kebijakan memori
maxmemory-policy allkeys-lru # untuk cache
maxmemory-policy noeviction # untuk antrean
| Kebijakan | Perilaku saat memori penuh | Cocok untuk |
|---|---|---|
allkeys-lru | Buang kunci yang paling lama tidak dipakai | Cache |
volatile-lru | Hanya buang kunci yang punya TTL | Campuran |
noeviction | Tolak penulisan baru dengan error | Antrean, session |
Ini kegagalan yang sangat membingungkan saat terjadi. Dengan allkeys-lru, Redis yang
penuh akan membuang kunci apa pun untuk memberi ruang โ termasuk job antrean dan session. Gejalanya: pekerjaan
hilang tanpa jejak dan pengguna ter-logout acak, tanpa satu pun error di log aplikasi. Kalau Redis-mu memegang
antrean, jangan pakai allkeys-*.
Memakai Redis langsung
use Illuminate\Support\Facades\Redis;
// Penghitung yang atomik โ aman dari balapan, tanpa transaksi database
Redis::incr("baca:artikel:{$id}");
Redis::expire("baca:artikel:{$id}", 86400);
// Sorted set untuk peringkat
Redis::zincrby('populer:harian', 1, $artikel->id);
$teratas = Redis::zrevrange('populer:harian', 0, 9);
// Pipeline: banyak perintah, satu perjalanan jaringan
Redis::pipeline(function ($pipe) use ($ids) {
foreach ($ids as $id) {
$pipe->incr("baca:artikel:{$id}");
}
});
Penghitung pembacaan adalah kasus yang tepat untuk Redis. Menulis satu baris ke database untuk setiap
kali artikel dibuka akan membebani database dengan tulisan yang tidak penting-penting amat. INCR
di Redis nyaris gratis, dan sebuah job berkala bisa memindahkan angkanya ke database sekali setiap beberapa
menit.
Penguncian atomik
$lock = Cache::lock('impor-feed', 120);
if ($lock->get()) {
try {
$this->imporFeed();
} finally {
$lock->release();
}
}
// Atau: tunggu sampai 10 detik untuk mendapatkan kunci
Cache::lock('impor-feed', 120)->block(10, fn () => $this->imporFeed());
Selalu beri masa berlaku pada kunci. Proses yang mati sebelum sempat melepas kunci tanpa TTL akan memblokir pekerjaan itu selamanya โ dan penyebabnya sangat sulit ditebak berbulan-bulan kemudian.
Yang perlu dipantau
| Metrik | Peringatan saat |
|---|---|
| Pemakaian memori | > 75% dari maxmemory |
| Kunci yang dibuang (evicted) | Angkanya bukan nol pada database antrean |
| Rasio cache hit | < 80% โ kuncinya mungkin salah rancang |
| Koneksi aktif | Mendekati batas maksimum |
| Perintah lambat | Ada KEYS atau FLUSHALL di produksi |
Jangan pernah menjalankan KEYS * di produksi. Redis berjalan satu utas โ perintah itu
memblokir seluruh layanan sampai selesai memindai semua kunci. Dengan jutaan kunci, itu berarti
beberapa detik ketika cache, session, dan antrean semuanya berhenti merespons. Pakai SCAN.
Latihan: pindahkan cache, session, dan antrean ke Redis dengan database terpisah. Lalu jalankan
php artisan cache:clear saat ada job menunggu di antrean, dan buktikan bahwa job-nya
selamat โ bukti pemisahan itu bekerja.
Rangkuman ini sengaja dipangkas ke bagian yang dipakai di roadmap. Buka sumber aslinya saat kamu butuh detail lengkap atau referensi parameter.