在分布式系统中,分布式锁被广泛用于共享资源互斥,Master选主等,然而,使用分布式锁使用过程中,需要注意以下一些坑:
分布式锁正确性的坑
首先,分布式锁从协议上是正确的, 这里有一个假设条件是分布式锁的客户端和服务端的CPU时钟运转频率是一致的,或者相差很小。这样才能保证server端不会比client先感知到丢锁事件发生,造成锁的正确性被破坏。
图1
其次,对于基于心跳机制实现的分布式锁,丢锁事件依赖于心跳异常来感知。异常事件可以通过回调函数来通知,也可以通过轮询心跳健康来判断是否发生丢锁。 但不论哪种实现,当丢锁事件发生时,假设对于互斥区的操作已经被发出(如网络延迟, FullGC事件),不可被撤回。那么就存在多个client,同时对互斥区进行操作的风险,如图1所示。 所以,负责互斥区的数据系统一定要有防护措施,能够避免这个情况,拒绝丢锁的进程仍然可以操作互斥区。 可以通过ConditionalUpdate或者基于互斥区版本递增的方法来进行预防。
图2
基于互斥区版本号来预防的方法可以参考: https://github.com/DistributedComponents/disel/wiki/Lease-based-Lock-Protocol