How Distributed Locks Prevent Chaos in Massive Red‑Packet Systems
This article explains why traditional locks fail under massive concurrent traffic, how distributed locks coordinate multiple servers to ensure correct total payouts, and compares Redis and Zookeeper implementations, highlighting their mechanisms, pitfalls, and practical considerations for large‑scale systems.
Distributed locks work on the same principle as ordinary locks: they guarantee that only one thread or process can execute a critical section at any given moment, preventing race conditions when many requests are processed concurrently.
Problems with Conventional Locks
In a single JVM, Java provides synchronized and Lock to control concurrency, but a single server cannot handle the massive load of events like holiday red‑packet distributions, where millions of users may request funds simultaneously across hundreds of machines.
If 100 servers each handle 10,000 requests, the total number of requests can reach millions, and without coordination the sum of distributed amounts could far exceed the intended total, leading to financial inconsistencies.
How Distributed Locks Solve the Issue
A distributed lock treats the whole cluster as a single application, requiring a lock that exists outside any individual service instance. When a server receives a request, it asks a central lock manager (e.g., a Redis or Zookeeper service) to acquire the lock before modifying the shared total.
The lock manager records the remaining amount; each successful lock acquisition deducts the requested amount, ensuring the global total never exceeds the predefined limit.
After the business logic finishes, the lock is released so other servers can proceed.
Implementations of Distributed Locks
Redis‑Based Distributed Lock
Redis is single‑threaded for network I/O, so SETNX can be used to create a lock key. If the command returns 1, the lock is acquired; if it returns 0, another server holds the lock.
When the lock holder finishes, it deletes the key, returning 1 to indicate success, allowing others to acquire the lock.
To avoid deadlocks caused by crashes, the lock key should have an expiration. Two approaches are common:
Set an explicit TTL with EXPIRE key timeout so Redis automatically releases the lock after a given number of seconds.
Store a timestamp as the value, let other servers compare the current time with the stored expiration, and use GETSET to atomically claim the lock if it has expired.
Zookeeper‑Based Distributed Lock
Zookeeper provides a hierarchical namespace of znodes. By creating an exclusive znode, a server can acquire a lock; other servers attempting to create the same node will fail and can set a watch on the node.
When the lock holder deletes the znode after completing its work, Zookeeper notifies the waiting servers, and the next one creates the node to obtain the lock.
Using temporary znodes ensures that if a server crashes, the znode is automatically removed, preventing permanent deadlock. To reduce the “herd effect,” temporary sequential znodes can be used so each server watches the predecessor node, guaranteeing a clear acquisition order.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
Java Interview Crash Guide
Dedicated to sharing Java interview Q&A; follow and reply "java" to receive a free premium Java interview guide.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
