Pengantar: Kenapa Deadlock Redis pada Job Queue Terjadi?
Ketika job queue backend berhenti memproses tugas, tim operasional sering melihat anomali berupa antrean panjang dan worker yang tetap idle padahal cukup kapasitas. Inilah problem utama: deadlock Redis antara worker yang menunggu lock dan job queue yang terus memicu retry, sehingga seluruh sistem stagnan. Artikel ini menjelaskan bagaimana mengidentifikasi gejala awal dari monitoring/log, langkah observasi untuk menemukan deadlock Redis, analisis penyebab utama, dan perbaikan praktis agar kasus serupa dapat ditangani sendiri.
Observasi dari Monitoring dan Log
Gejala awal berawal dari metrik latency job queue dan penumpukan job yang gagal. Monitoring seperti Prometheus/Grafana biasanya menunjukkan:
- Worker idle, but job queue depth naik tajam.
- Retry rate meningkat secara eksponensial setelah job pertama gagal.
- Redis command latency spike, khususnya
BLPOPatauBRPOPuntuk antrean.
Log worker memperlihatkan pesan error tipe timeout atau exception pada update status job, tanpa ada log keberhasilan berikutnya. Untuk memahami apa yang pasti terjadi pada Redis, gunakan redis-cli monitor untuk melihat operasi real-time.
redis-cli monitorPerhatikan apakah ada pola:
- Worker menulis lock dengan
SET key value NX PX timeout. - Job queue melakukan
BRPOPnamun tidak selesai, menunggu lock yang tidak dilepas. - Terdapat retry job dengan perintah
RPUSHsebelum lock selesai.
Alternatif lain adalah redis-cli CLIENT LIST diikuti INFO clients untuk melihat apakah ada koneksi worker yang menunggu dan apakah ada script lama (Lua) yang menggantung.
Analisis Deadlock antara Worker dan Redis Job Queue
Deadlock muncul bila worker memperoleh lock di Redis untuk eksekusi job, tapi gagal melepaskannya karena proses crash atau blocking saat menulis hasil. Konfigurasi retry otomatis kemudian memasukkan job kembali ke queue, sementara worker lain tidak bisa mengambil job karena key lock tadi masih aktif. Gejala umum:
- Lock TTL terlalu panjang sehingga tidak otomatis hilang saat worker hang.
- Worker menulis status dengan operasi blocking, seperti menunggu downstream HTTP, tanpa timeout.
- Retry queue tidak memeriksa apakah job sebelumnya sudah selesai, sehingga job yang sama dijalankan berkali-kali.
Root cause case ini: worker menulis lock Redis dengan TTL default tinggi untuk menjamin eksklusif, tetapi tidak memiliki circuit breaker saat dependent service lambat. Setelah timeout downstream terpenuhi, worker mencoba menyimpan hasil ke Redis lagi, namun perintah SET untuk melepaskan lock gagal karena lock sebelumnya belum terupdate, sehingga job stuck.
Langkah Perbaikan Praktis
1. Konfigurasi Timeout
Setiap bagian yang mengakses Redis harus memiliki timeout. Misalnya, gunakan client library dengan timeout read/write explicit dan timeouts untuk HTTP dependency agar worker tidak tergantung selamanya. Dalam Redis lock pattern, TTL lock harus lebih pendek dari waktu maksimum yang dibutuhkan job, lalu diperbarui (renew) secara periodik hanya jika job masih berjalan.
2. Circuit Breaker dan Retry Idempotent
Implementasikan circuit breaker di service dependency. Apabila downstream tidak responsif, worker harus membatalkan job, mencatat error, dan beralih ke retry yang tertunda. Pastikan job idempotent, misalnya dengan menyimpan job_id unik di Redis sehingga re-try tidak menyebabkan state tidak konsisten.
3. Observasi Lock dan Queue
Gunakan perintah berikut untuk memeriksa lock yang tersisa dan job queue depth:
redis-cli GET job:lock:worker123Jika lock masih ada padahal worker sudah restart, hapus manual lock tersebut atau gunakan TTL pendek. Untuk antrean:
redis-cli LLEN job:queuekemudian LRANGE job:queue 0 20 untuk melihat job mana yang stuck.
4. Penyesuaian Job Worker
Tambahkan log yang merekam aktivitas lock (mendapatkan, memperbarui, melepaskan) termasuk waktu. Gunakan alarm jika lock tidak dilepas dalam periode tertentu.
Kesimpulan
Deadlock Redis di job queue sering muncul akibat kombinasi timeout lock panjang, retry agresif, dan worker yang tidak tahan terhadap dependensi lambat. Diagnosis dimulai dari monitoring metrik queue, log worker, lalu verifikasi operasi Redis dengan perintah monitor atau CLIENT LIST. Perbaikan praktis meliputi konfigurasi timeout untuk lock dan dependency, penerapan circuit breaker dengan retry terkontrol, serta memastikan job idempotent. Dengan pendekatan ini, tim backend bisa menerapkan diagnosis serupa sebelum sistem kehilangan throughput secara signifikan.
Komentar
0 komentar
Masuk ke akun kamu untuk ikut berkomentar.
Belum ada komentar
Jadilah yang pertama ikut berdiskusi!