Redlock Python Client
redlock is a Python implementation of the Redlock algorithm for distributed locks with Redis. It provides a simple API to acquire and release locks across multiple Redis instances to ensure reliability in distributed systems. The current version is 1.2.0, with a release cadence that is not very frequent, suggesting a stable but less actively developed library.
Common errors
-
redis.exceptions.ConnectionError: Error 111 connecting to localhost:6379. Connection refused.
cause The Redis server is not running or is not accessible at the specified host and port.fixEnsure your Redis server is running and accessible from the machine running your Python application. Verify host and port configurations. -
TypeError: lock() missing 1 required positional argument: 'ttl'
cause You called the `lock()` method without providing the `ttl` (Time-To-Live) argument, which specifies how long the lock should be valid in milliseconds.fixAdd the `ttl` argument, specifying the lock duration in milliseconds. E.g., `dlm.lock(resource_name, 5000)`. -
Acquired lock for resource: my_critical_resource ... then another process also acquires it shortly after.
cause This typically happens if you are using only one Redis instance, or if your `lock_ttl` is too short for the operation, allowing the lock to expire and be re-acquired by another client. Clock drift across servers can also contribute.fixFor true distributed locking, configure Redlock with multiple Redis master instances. Increase `lock_ttl` to ensure your critical section completes before the lock expires. Regularly check server clock synchronization.
Warnings
- gotcha The `ttl` (Time-To-Live) parameter for `lock()` is specified in milliseconds, not seconds. Forgetting this common Redis API convention can lead to locks expiring much faster or slower than intended.
- gotcha To ensure true distributed locking and fault tolerance as per the Redlock algorithm, you must configure `Redlock` with multiple independent Redis master instances (N/2 + 1 quorum). Using a single Redis instance defeats the purpose of distributed locking and makes your system susceptible to a single point of failure.
- gotcha The Redlock algorithm, and thus this library, does not guarantee that a lock holder will finish its critical section before the lock expires. It's crucial to ensure your critical operations complete well within the `lock_ttl` or implement a mechanism to periodically extend the lock if necessary (though Redlock doesn't natively support easy extensions without re-acquiring).
Install
-
pip install redlock
Imports
- Redlock
from redlock import Redlock
Quickstart
import redis
from redlock import Redlock
import os
# Configure Redis instances. For production, use multiple instances
# and ensure they are properly configured for high availability.
# Here, we default to localhost for a runnable example.
redis_host = os.environ.get('REDIS_HOST', 'localhost')
redis_port = int(os.environ.get('REDIS_PORT', 6379))
redis_masters = [
{"host": redis_host, "port": redis_port, "db": 0}
# For true distributed locking, add more Redis instances:
# {"host": "192.168.1.30", "port": 6379, "db": 0},
# {"host": "192.168.1.31", "port": 6379, "db": 0}
]
# Initialize Redlock with Redis instances
dlm = Redlock(redis_masters=redis_masters)
resource_name = "my_critical_resource"
lock_ttl = 5000 # Lock validity time in milliseconds (5 seconds)
print(f"Attempting to acquire lock for resource: {resource_name}")
lock_info = dlm.lock(resource_name, lock_ttl)
if lock_info:
print(f"Successfully acquired lock: {lock_info}")
try:
# --- Critical section begins ---
print("Performing critical operation...")
# Simulate work
import time
time.sleep(2) # Keep operation less than lock_ttl
# --- Critical section ends ---
finally:
print("Releasing lock...")
dlm.unlock(lock_info)
print("Lock released.")
else:
print(f"Failed to acquire lock for resource: {resource_name}. It might be held by another process.")