This repository explores the implementation of remote locks using Redis 🛠️ in Go 🐹. The system supports single-instance locks 🔑 and quorum-based distributed locks 🌐, providing mechanisms for reliable ✅ and efficient ⚡ synchronization in both standalone 🖥️ and distributed environments. By leveraging Redis’s atomic operations ⚙️, the locks ensure consistency 📏 and robustness 💪.
- Operates on a single Redis instance 📍.
- Provides basic lock acquisition 🔐 and release functionality 🔓.
- Implements TTL ⏱️ (Time-To-Live) to automatically release locks if not manually released.
- Operates across multiple Redis instances 🖥️🖥️🖥️.
- Ensures lock acquisition requires a majority (quorum 🧮) of instances to agree 🤝.
- Provides fault tolerance 🚦, making it suitable for distributed systems 🌍.
- Atomic Operations ⚙️: Redis’s
SETNXensures atomicity 🔒 for lock acquisition. - Fault Tolerance 🚦: Quorum-based locks provide resilience 🌈 against individual Redis instance failures.
- Key Uniqueness 🆔: Each lock is associated with a unique key 🔑 and ID 🪪, preventing accidental overwrites 🛡️.
The RedisLock struct provides methods to:
- Acquire a lock (
Acquire): UsesSETNXto atomically set the key 🔒 with a TTL ⏱️. - Release a lock (
Release): Verifies ownership 🪪 before deleting 🗑️ the key.
The RedisLockQuorum struct provides methods to:
- Acquire a lock across multiple instances 🖥️🖥️🖥️: Requires a quorum 🧮 to successfully set the lock.
- Release a lock across multiple instances 🌍: Ensures a quorum 🧮 agrees before the lock is considered released 🔓.
-
NewRedisLock- Initializes a
RedisLockinstance 🔧 with a Redis client, key 🔑, and unique ID 🪪.
- Initializes a
-
Acquire(Single-Instance)- Attempts to acquire a lock 🔒 using
SETNX. - Sets a TTL ⏱️ of 10 seconds to avoid stale locks
⚠️ .
- Attempts to acquire a lock 🔒 using
-
Release(Single-Instance)- Releases the lock 🔓 only if the key’s value matches the provided ID 🪪.
-
NewRedisLockQuorum- Initializes a
RedisLockQuoruminstance 🔧 with multiple Redis clients, a key 🔑, and a unique ID 🪪.
- Initializes a
-
Acquire(Quorum-Based)- Attempts to acquire a lock 🔒 on multiple Redis instances 🖥️🖥️🖥️.
- Checks if the quorum 🧮 condition (majority of instances) is satisfied ✅.
-
Release(Quorum-Based)- Deletes the key 🔑 from multiple Redis instances 🌐 if the quorum 🧮 condition is met.
client := redis.NewClient(&redis.Options{
Addr: "localhost:6379",
})
id := fmt.Sprintf("%d", time.Now().UnixNano())
lock := NewRedisLock(client, "my_lock", id)
if lock.Acquire() {
fmt.Println("Lock acquired 🔒")
} else {
fmt.Println("Failed to acquire lock ❌")
}
if lock.Release() {
fmt.Println("Lock released 🔓")
} else {
fmt.Println("Failed to release lock ❌")
}clients := []*redis.Client{
redis.NewClient(&redis.Options{Addr: "localhost:6379"}),
redis.NewClient(&redis.Options{Addr: "localhost:6380"}),
redis.NewClient(&redis.Options{Addr: "localhost:6381"}),
}
id := fmt.Sprintf("%d", time.Now().UnixNano())
lock := NewRedisLockQuorum(clients, "my_distributed_lock", id)
if lock.Acquire() {
fmt.Println("Distributed lock acquired 🔒")
} else {
fmt.Println("Failed to acquire distributed lock ❌")
}
if lock.Release() {
fmt.Println("Distributed lock released 🔓")
} else {
fmt.Println("Failed to release distributed lock ❌")
}- Simplicity 🛠️: Leverages Redis’s built-in atomic operations ⚙️ for straightforward implementation.
- Scalability 🌐: Distributed locks support horizontal scaling 📈 across multiple Redis instances 🖥️🖥️🖥️.
- Reliability ✅: Quorum-based locking ensures consistency 📏 even in the presence of failures
⚠️ .
- Latency ⏳: Acquiring distributed locks 🔒 may introduce latency due to network calls 🌐.
- No Strong Consistency 📉: The implementation assumes Redis instances are synchronized 🔄, but network partitions can cause inconsistencies
⚠️ . - Single Point of Failure ❌: For single-instance locks 🔑, failure of the Redis instance 🛑 results in a complete loss of functionality
⚠️ .
- Use quorum-based locks 🌐 for distributed systems 🌍 to mitigate single points of failure
⚠️ . - Implement retry mechanisms 🔁 to handle transient failures during lock acquisition 🔒.
- Dynamically extend TTLs ⏱️ for long-running operations 🔄 to avoid premature expiration
⚠️ . - Monitor Redis clusters 🖥️ for latency ⏳ and reliability ✅ to ensure optimal performance 📈.
This implementation of remote locks 🔐 using Redis 🛠️ demonstrates an effective approach to synchronization 🔄 in both standalone 🖥️ and distributed 🌐 environments. By leveraging Redis’s capabilities ⚙️ and quorum-based decision-making 🧮, the system balances simplicity 🛠️ and reliability ✅. Further enhancements can address limitations like network latency ⏳ and consistency under partitioning