Redis 实现分布式锁时可能遇到的问题有哪些?
Redis 实现分布式锁时可能遇到的问题有哪些?
回答重点
- 业务未执行完,锁已到期
- 单点故障问题
- 主从问题不同步问题
- 网络分区问题
- 时钟漂移问题
- 锁的可重入性问题
- 误释放锁问题
扩展知识
业务未执行完,锁已到期
为了避免持有锁的客户端崩溃或因网络问题断开连接时,锁无法被正常释放,需要给锁设置过期时间。
那么就有可能出现业务还在执行,锁已到期的情况。
可以设置一种续约机制(Redisson 中的看门狗机制),线程 a 在执行的时候,设置一个超时时间,并且启动一个守护线程,守护线程每隔一段时间就去判断线程 a 的执行情况,如果 a 还没有执行完毕并且 a 的时间快过期了,就重新设置一下超时时间,即继续续约。
锁的过期时间的设置也需要好好评估一下。
如果设置太长,业务结束了它还在阻塞的话,会影响 Redis 的性能。如果设置太短,就出现刚说的问题,因此要保证是设置一个合理的时间使得在大多数情况下任务能够在锁过期之前完成。
单点故障问题
如果 Redis 单机部署,当实例宕机或不可用,整个分布式锁服务将无法正常工作,阻塞业务的正常执行。
主从问题
如果线上 Redis 是主从+哨兵部署的,则分布式锁可能会有问题。
因为 Redis 的主从复制过程是异步实现的,如果 Redis 主节点获取到锁之后,还没同步到其他的从节点,此时 Redis 主节点发生宕机了,这个时候新的主节点上没锁的数据,因此其他客户端可以获取锁,就会导致多个应用服务同时获取锁。
网络分区
在网络不稳定的情况下,客户端与 Redis 之间的连接可能中断,如果未设置锁的过期时间,可能会导致锁无法正常释放。如果有多个锁,还可能引发锁的死锁情况。
时钟漂移
因为 Redis 分布式锁依赖于实例的时间来判断是否过期,如果时钟出现漂移,很可能导致锁直接失效。
可以让所有节点的系统时钟通过 NTP 服务进行同步,减少时钟漂移的影响。
Comments