Distributed Lock Overview and Implementations with Redis, etcd, and Zookeeper
This article explains the concept of distributed locks, compares system classifications based on safety, and provides detailed implementation guides for Redis‑based locks using SET NX EX, as well as exclusive and shared locks using etcd/Zookeeper with proper handling of TTL, leases, and atomic operations.
Distributed locks are essential primitives in distributed environments that ensure mutual exclusion when multiple processes operate on shared resources.
In a single‑process setting, thread mutexes provided by the kernel or libraries prevent concurrent reads and writes; when extending to distributed systems, a lock service is required so that different hosts can acquire a lock and access the resource exclusively.
Distributed locks can be classified into two groups based on safety: (1) systems based on asynchronous replication such as Redis or MySQL, which often use a TTL mechanism and are suitable for short‑lived tasks where occasional lock loss is tolerable; (2) systems based on consensus protocols like Paxos, exemplified by etcd and Zookeeper, which provide higher safety through leases and are appropriate for long‑running critical sections.
Redis‑based lock : The lock can be acquired atomically with the command SET lock_name value NX EX lock_time , where EX sets the expiration in seconds and NX ensures the key is set only if it does not already exist. The lock is released with DEL lock_name . To avoid accidental release after a crash, a unique identifier (UUID) should be stored as the value and the release operation must verify the UUID, typically using a Lua script for atomic check‑and‑delete.
etcd/Zookeeper exclusive lock : Clients create a temporary node (e.g., /exclusive_lock/lock1 ) under a designated lock directory. Only one client can successfully create the node, thus acquiring the lock. Other clients register a watcher on the directory to be notified when the node disappears (due to lease expiration or explicit deletion). The lock is released by removing the temporary node, and client crashes automatically clean up the node.
Shared (read) lock : Implemented by creating sequential temporary nodes under /shared_lock/ (e.g., /shared_lock/host1‑R‑001 for reads, /shared_lock/host1‑W‑002 for writes). A client obtains the lock by examining the ordering of all child nodes: it may proceed if there is no preceding write node (for reads) or if it holds the smallest node (for writes). Release follows the same procedure as exclusive locks, and watchers are used to re‑attempt acquisition after changes.
The article also discusses edge cases such as lock expiration, client crashes, and the need for atomic operations to prevent erroneous lock releases, providing practical code snippets and diagrams to illustrate the workflows.
360 Tech Engineering
Official tech channel of 360, building the most professional technology aggregation platform for the brand.
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.