In a single-server application, you use a mutex or semaphore to prevent two threads from concurrently modifying the same data. But in a distributed system with multiple servers, a local mutex is useless—Server A's lock is invisible to Server B. You need a Distributed Lock: a lock that is visible and enforceable across all servers in the cluster.
orderId ensures only one server processes it.Redis is the most popular backend for distributed locks due to its speed and atomic operations.
SET resource_name my_random_value NX PX 30000
NX: Only set if the key does NOT already exist (mutual exclusion).PX 30000: Auto-expire after 30 seconds (prevents deadlocks if the lock holder crashes).my_random_value: A unique identifier so only the lock holder can release it.Use a Lua script to atomically check and delete:
if redis.call("get", KEYS[1]) == ARGV[1] then
return redis.call("del", KEYS[1])
end
This ensures that Server A doesn't accidentally release a lock that was already acquired by Server B after Server A's lock expired.
For higher reliability, the Redlock algorithm acquires locks across multiple independent Redis instances (e.g., 5 instances). The lock is considered acquired only if a majority (at least 3 out of 5) of instances grant it. This tolerates individual Redis node failures.
ZooKeeper uses ephemeral sequential nodes for distributed locking:
/locks/resource/lock-0000000001).