Blocaje Distribuite în Redis: Comanda SET NX PX și Algoritmul Redlock în Redis & In-Memory Data Store

Ghid complet pentru implementarea corectă a blocajelor distribuite în Redis: excludere mutuală atomică cu SET NX PX, eliberare sigură prin scripturi Lua pentru a evita deblocarea concurentă și arhitectura Redlock.

Sintaxă comandă
SET lock:resursa <token_unic> NX PX 30000 | Script Lua de deblocare verificând token-ul

Într-o arhitectură de microservicii, sincronizarea acțiunilor critice concurente (evitarea plății duble a unei comenzi, procesarea unică a unei facturi, atribuirea unui loc în avion) necesită un blocaj distribuit (Distributed Lock) sigur și ultra-rapid.

Implementarea naivă cu SETNX urmat de EXPIRE este profund eronată: dacă procesul cade între cele două comenzi, blocajul nu va expira niciodată, provocând un deadlock permanent în întregul sistem!

Implementarea Corectă a Blocajului pe o Singură Instanță Redis
# 1. Dobândirea atomică a blocajului (Lock Acquisition):
# - 'NX': Setează cheia DOAR dacă nu există deja (garantează excluderea mutuală).
# - 'PX 30000': Atribuie un timp de viață (TTL) de 30.000 milisecunde (previne deadlock dacă worker-ul crapă).
# - 'token_uuid_unic': Un identificator unic generat aleator (UUIDv4) per încercare de blocare.
SET lock:comanda:9812 "a8f1b620-3b2a-4c28-bb84-9092c710f441" NX PX 30000
# Dacă returnează 'OK' -> Blocajul a fost obținut!
# Dacă returnează '(nil)' -> Resursa este ocupată de un alt worker!

# 2. Eliberarea Sigură a Blocajului (Lock Release):
# ATENȚIE CRITICĂ: Nu folosiți niciodată comanda simplă 'DEL lock:comanda:9812'!
# Dacă execuția sarcinii a durat 31 de secunde, blocajul a expirat automat și a fost preluat de Worker-ul B.
# Un DEL necondiționat lansat de Worker-ul A ar șterge blocajul legitim al Worker-ului B!

# Soluția: Un script Lua care verifică dacă token-ul curent corespunde înainte de ștergere:
EVAL "if redis.call('get', KEYS[1]) == ARGV[1] then return redis.call('del', KEYS[1]) else return 0 end" 1 lock:comanda:9812 "a8f1b620-3b2a-4c28-bb84-9092c710f441"

Algoritmul Redlock pentru Clustere Multi-Master

Dacă folosiți o arhitectură clasică Master-Replica, un failover neașteptat poate duce la pierderea blocajului (deoarece replicarea Redis este asincronă). Pentru garanții matematice stricte de toleranță la erori, algoritmul Redlock (propus de antirez) presupune:

  1. Rularea a $N$ instanțe Redis Master complet independente (de exemplu $N=5$).
  2. Clientul încearcă să obțină blocajul pe toate cele 5 noduri secvențial, folosind același token și un timeout scurt.
  3. Blocajul este considerat valid dacă a fost obținut pe majoritatea nodurilor ($\ge 3$ din 5) într-un timp total mai mic decât durata de viață (TTL) a blocajului.