redis分布式锁的异步实现
aioredlock的Python项目详细描述
异步redlock算法实现。
用法
fromaioredlockimportAioredlock,LockError# Define a list of connections to your Redis instances:redis_instances=[('localhost',6379),{'host':'localhost','port':6379,'db':1},'redis://localhost:6379/2',]# Create a lock manager:lock_manager=Aioredlock(redis_instances)# Check wether a resourece acquired by any other redlock instance:assertnotawaitlock_manager.is_locked("resource_name")# Try to acquire the lock:try:lock=awaitlock_manager.lock("resource_name")exceptLockError:print('Lock not acquired')raise# Now the lock is acquired:assertlock.validassertawaitlock_manager.is_locked("resource_name")# Extend lifetime of the lock:awaitlock_manager.extend(lock)# Raises LockError if the lock manager can not extend the lock lifetime# on more then half of the Redis instances.# Release the lock:awaitlock_manager.unlock(lock)# Raises LockError if the lock manager can not release the lock# on more then half of redis instances.# The released lock become invalid:assertnotlock.validassertnotawaitlock_manager.is_locked("resource_name")# Or you can use the lock as async context manager:try:asyncwithawaitlock_manager.lock("resource_name")aslock:assertlock.validisTrue# Do your stuff having the lockawaitlock.extend()# alias for lock_manager.extend(lock)# Do more stuff having the lockassertlock.validisFalse# lock will be released by context managerexceptLockError:print('Lock not acquired')raise# Clear the connections with Redis:awaitlock_manager.destroy()
工作原理
aioredlock构造函数接受以下可选参数:
- redis_connections:运行redis实例的连接列表(主机和端口字典,aioredis.create_redis_pool()的kwargs,或元组(host, port),或sting redis uri)。默认值是[{'host': 'localhost', 'port': 6379}]。
- lock_timeout:表示锁有效期的浮点(秒)。默认值是10.0seconds。
- drift:用于时钟漂移补偿的浮点。默认值由lock_timeout * 0.01 + 0.002seconds计算。
- {TT9}$:表示最大允许重试次数以获取锁的整数。默认值是3次。
- retry_delay_min和retry_delay_max:表示下次重试前等待时间(秒)的浮点值。默认值分别是0.1和0.3。
为了获得锁,应该调用lock函数。如果锁操作成功,lock.valid将为true,如果未获取锁,则将引发LockError。
从那一刻起,锁一直有效,直到调用unlock函数或到达lock_timeout为止。
调用extend函数将锁的生存期重置为lock_timeout间隔。
使用is_locked函数检查资源是否被其他redlock实例锁定。
为了清除与redis的所有连接,可以调用lock_managerdestroy方法。
待办事项
- 如果可能,请根据锁的有效性以安全的方式使lock valid属性过期