Redis ile distributed lock nasıl uygulanır? Hangi riskleri vardır ve fencing token neden gereklidir?
Cevap
Birden fazla instance'ın aynı kaynağa (ör. aynı cron işini çalıştırmak, aynı kullanıcı için tek ödeme işlemi) aynı anda erişmesini engellemek için distributed lock kullanılır. Redis'te temel uygulama tek komuttur:
SET lock:invoice:42 <rastgele-token> NX PX 30000NX: key yoksa yaz (kilidi yalnızca bir istemci alır).PX 30000: 30 sn TTL; kilidi alan process çökerse kilit sonsuza kadar kalmaz.- Rastgele token: kilidi yalnızca sahibi bırakabilsin diye.
Bırakırken kontrol ve silme atomik olmalı, bu yüzden Lua script kullanılır:
if redis.call("GET", KEYS[1]) == ARGV[1] then
return redis.call("DEL", KEYS[1])
else
return 0
endToken kontrolü olmadan DEL yaparsanız: A'nın kilidi TTL ile düşmüş, B almış olabilir; A işini bitirip DEL yapınca B'nin kilidini siler.
Riskler
- TTL işten kısa kalırsa: uzun GC pause, ağ gecikmesi veya yavaş işlem nedeniyle kilit süresi dolar, ikinci process kilidi alır ve iki process aynı anda çalışır. Kilidi periyodik uzatmak (watchdog, Redisson bunu yapar) riski azaltır ama ortadan kaldırmaz.
- Failover: Redis primary kilidi replica'ya aktarmadan çökerse, yeni primary'de kilit yoktur. Redlock algoritması (N bağımsız Redis node'unun çoğunluğundan kilit alma) bunu hedefler, ancak zamanlama varsayımları nedeniyle tartışmalıdır (Martin Kleppmann'ın eleştirisi).
Fencing token
Doğruluk kritikse kilit tek başına yetmez. Her kilit alınışında monoton artan bir numara (fencing token) verilir ve korunan kaynak (DB, depolama) daha eski bir token'la gelen yazmayı reddeder.
UPDATE invoices
SET status = 'SENT', lock_token = 34
WHERE id = 42 AND lock_token < 34; -- eski token'lı geç kalan yazma etkisiz kalırNe zaman ne kullanılmalı?
- Verimlilik için (aynı işi iki kez yapmamak, tekrar zararsız): tek node Redis
SET NX PXyeterlidir. - Doğruluk için (iki kez olursa veri bozulur): fencing token, veritabanı seviyesinde kilit (
SELECT ... FOR UPDATE, PostgreSQL advisory lock) veya consensus tabanlı sistemler (etcd, ZooKeeper).
İlgili Sistem Tasarımı soruları
- Mesaj kuyruğu (RabbitMQ, Kafka) ne zaman kullanılır?
- Monolith ile mikroservis mimarisi arasındaki fark nedir? Mikroservislere ne zaman geçilmeli?
- CAP teoremi nedir? Gerçek sistemlerde nasıl yorumlanır?
- Dikey ve yatay ölçekleme arasındaki fark nedir?
- Hangi cache stratejilerini biliyorsunuz?
- REST ile GraphQL arasındaki farklar nelerdir?
Bu konuda başka bir soru biliyor musun?
Mülakatta karşılaştığın soruları ekle, onaylandıktan sonra yayına alınsın.