Ringkasan dan Pertanyaan Utama
Latensi batch API Sneakerweb, terutama pada endpoint pemrosesan pesanan, melejit secara tidak konsisten selama jam sibuk. Langkah pertama adalah menjawab: apa yang membuat latensi batch menggelembung meskipun throughput rata-rata konsisten?
Jawabannya: kumpulan worker terdistribusi gagal sinkron dalam mengambil dan memproses job, sehingga terjadi antrean ganda dan retry yang menumpuk. Artikel ini menguraikan gejala, observability, root cause, perbaikan, dan strategi pencegahan regresi.
Konteks Arsitektur Sneakerweb Terdistribusi
Sneakerweb mengandalkan arsitektur event-driven dengan API Gateway yang mendorong job ke antrean Kafka, kemudian worker Python/Go mengambil batch, memanggil microservice inventaris, dan menulis hasil ke database utama. Setiap worker juga mengirim metrik latency ke Prometheus, sedangkan tracing menggunakan OpenTelemetry untuk mengikuti durasi tiap batch.
Model batch dimaksudkan agar satu worker memroses beberapa order sekaligus, tetapi sistem mulai menunjukkan latensi batch yang parah saat ada lebih dari lima worker konkuren.
Gejala Latensi Batch dan Observability yang Digunakan
Gejala utama:
- Waktu respon API batch >2 detik padahal rata-rata 400 ms.
- Retry menggandakan job dalam antrean Kafka karena worker asumsi job gagal.
- Trace menunjukkan lock hold time selama 500 ms sebelum batch diproses.
Diagnosa observability:
- Log: worker menuliskan "batch lock acquired" setiap detik, diikuti dengan "batch lock expired" tanpa berhasil memproses.
- Tracing: span OpenTelemetry menunjukkan fase antrean (waiting for lock) memakan lebih banyak waktu ketimbang eksekusi microservice.
- Metrics: metrik custom redis.lock.acquire_duration naik drastis, sedangkan jumlah batch committed stagnan.
Gabungan data tersebut menunjukkan cluster worker saling menunggu lock, kemudian timeout dan retry, menciptakan back-pressure di antrean batch.
Root Cause: Distribusi Worker Tak Sinkron
Akar masalah adalah mekanisme lock distribusi yang tidak aman saat batch diproses. Worker menggunakan lock Redis sederhana dengan expiry 2 detik, sementara batch memerlukan hingga 3 detik. Tanpa perpanjangan secara atomik, lock kadaluarsa sebelum batch selesai, lalu worker lain mengambil job yang sama dan menghasilkan duplikasi sekaligus latensi karena kerja ganda.
Selain itu, pembaruan status job dilakukan di worker utama tanpa koordinasi atomic. Ketika retry terjadi, antrean Kafka memasukkan job ulang yang berasal dari worker lama yang belum tahu job sudah selesai.
Langkah Perbaikan Konkrit
1. Perbaiki Locking Redis
Gunakan pola Redis Redlock dengan perpanjangan lock otomatis saat batch masih berjalan. Contoh kode sederhananya:
lock = redis.lock("batch:123", timeout=5, blocking_timeout=0.5)
if not lock.acquire():
raise RuntimeError("Tidak bisa mengunci batch")
try:
process_batch()
finally:
lock.release()Pastikan blocking_timeout lebih pendek dari waktu ekspor batch untuk menghindari waiting panjang dan timeout lebih panjang dari batch typical duration.
2. Kunci Antrean Kafka di Level Job
Tambahkan flag processing pada job metadata dan update secara atomik (misal dengan Redis hash) sebelum worker mulai batch. Jika worker lain melihat flag aktif lebih lama dari Ambang 2x durasi batch, kirim alert dan jangan retry otomatis.
3. Perbaiki Retry dan Metric
Atur retry_backoff bertingkat berdasarkan cause dan gunakan dead-letter untuk job yang menghitung lebih dari tiga percobaan. Tambahkan metrik batch_lock_conflicts dan batch_retry_due_to_lock agar regression bisa terdeteksi cepat.
4. Validasi Konsistensi Status Job
Pastikan worker menulis status "sukses" ke database di dalam transaksi dan memicu event hanya sekali. Jika update status gagal, job harus tetap dianggap gagal dan dikembalikan ke antrean.
Tips Menghindari Regresi di Deployment Berikutnya
1) Bangun smoke test batch latency: kirim job dummy ke antrean dan pastikan worker menyelesaikannya dalam batas Waktu yang ditentukan.
2) Tambahkan chaos test dengan memaksa worker melepaskan lock lebih awal guna melihat apakah sistem recover atau mengirim alert.
3) Perluas observability: log kecepatan acquire/release lock, dan buat grafana dashboard yang menunjukkan gap antara durasi ekspektasi dan aktual.
4) Review konfigurasi timeout/expiry di satu tempat (mis. config service) untuk menghindari mismatch antara timeout lock dan eksekusi batch.
Kesimpulan
Kasus latensi batch di Sneakerweb terdistribusi muncul karena worker tidak sinkron saat mengunci job. Dengan memperbaiki locking Redis, memperjelas status job, dan menambahkan metrik yang relevan, latensi dapat dikendalikan. Observability terus-menerus dan regression test batch memastikan toko tetap responsif saat worker bergerak secara paralel.
Komentar
0 komentar
Masuk ke akun kamu untuk ikut berkomentar.
Belum ada komentar
Jadilah yang pertama ikut berdiskusi!