分布式锁的实现

锁的目的是为了解决共享资源的竞争问题,比如共享资源C,用户A要在C的基础上加上A1,用户B要在C的基础上加上B1,这种情况下是很难保证最终C的结果是多少;还有比如共享资源C,用户A要做操作A1和A2,要保证A1和A2必须连续执行,即是一个原子操作,用户B同样是原子操作B1和B2,如果没有锁的话就没有办法保证操作的原子性。在单机情况下,锁的控制在操作系统内核中,也就是一个中央控制管理器,但是在分布式系统中,比如操作数据库,要在原有基础上加上增加一个数字,那就需要先取原有的数字再加上某个数字,最终写入到数据库中。为保证操作的原子性就需要一个全局锁,在这样一个分布式系统中如何实现这个全局锁呢? 
其实也是仿照单机系统的概念,有一个锁控制器,一般使用cache来实现的,比如memcache和Redis,每个资源锁有一个唯一的名字,要操作这个资源的时候先要在cache中查询这个锁的状态,如果是lock状态则等待,如果是unlocked状态则将状态变成locked,然后操作资源。 
比如clientA和clientB都需要操作资源C,clientA先需要在redis cache判断资源C的锁是否存在,如果不存在则创建这个锁,并且需要设定一个timeout时间,当这个时间到了之后,再次申请锁C的时候就认为这个锁不存在,再次创建这个锁,申请到锁之后就可以操作资源C了。设定timeout时间,为了防止clientA在拿到锁之后crash,造成锁无法释放,所以需要设定一个timeout。 
那如何设定一个合理的timeout就是比较大的学问?一般是采用timeout到了之后锁自动释放,同时当操作完成之后需要手动将锁释放掉,这样就可以设定一个比较长,保证操作能够执行完的时间。这样锁最多timeout时间内会锁定。还可以用monitor来监控client的心跳,如果client不存在了直接将它的锁释放掉,减少对资源的锁定时间。 
另外一个问题就是cache如果crash话如何处理,一般对于这种cache都需要持久化,要不然会造成不一致性,也就是资源访问冲突问题。 
所以总的来说分布式锁是仿照单机系统,有一个中央锁控制器,当要访问资源之前就需要向锁控制器判断锁是否存在或者释放,再对资源进行操作,中央锁控制器就是用cache来实现的。

http://blog.csdn.net/jacob_007/article/details/52751812

原文地址:https://www.cnblogs.com/hellowzd/p/5979866.html