面试题答案
一键面试基本原理
在Redis中实现简单锁机制控制对象并发访问,主要基于Redis的单线程原子性操作。通过设置一个特定的键值对来表示锁的状态,利用Redis操作的原子性确保同一时间只有一个客户端能成功获取锁,从而实现对共享资源的并发访问控制。
常用方法 - 使用SETNX命令实现分布式锁
- 获取锁:使用
SETNX key value
命令(SETNX
是SET if Not eXists
的缩写)。如果键key
不存在,该命令会将key
设置为value
并返回1,表示获取锁成功;如果key
已存在,命令不做任何操作并返回0,表示获取锁失败。 - 释放锁:获取锁的客户端在操作完成后,使用
DEL key
命令删除代表锁的键,以此释放锁,让其他客户端有机会获取锁。
示例代码(以Python和Redis-py库为例):
import redis
r = redis.Redis(host='localhost', port=6379, db=0)
def acquire_lock(lock_key, value, timeout=10):
result = r.setnx(lock_key, value)
if result:
r.expire(lock_key, timeout)
return result
def release_lock(lock_key):
r.delete(lock_key)
这种方式可能存在的问题
- 锁超时问题:为了避免死锁,通常会给锁设置一个过期时间。但如果业务逻辑执行时间超过了锁的过期时间,锁会自动释放,其他客户端可能会获取到锁,导致同一时间有多个客户端操作共享资源。
- 误删锁问题:当一个客户端获取锁并设置了过期时间,在执行完业务逻辑前锁过期自动释放,此时另一个客户端获取到锁。原持有锁的客户端执行完业务逻辑后,使用
DEL
命令删除锁,会误删新客户端获取的锁,影响后续的并发控制。 - 单点故障问题:如果Redis实例发生故障,锁机制将无法正常工作,特别是在没有高可用方案(如Redis Sentinel或Redis Cluster)的情况下,可能导致业务中断。
- 网络分区问题:在分布式环境中,网络分区可能导致部分客户端无法连接到Redis实例,从而影响锁的获取和释放,造成资源访问的不一致。