以下内容纯粹是个人理解,并不一定正确。在网上没有搜到特别满意的资料,先总结一下,记录下来,日后再出发。
一、什么是分布式锁
“分布式锁是控制分布式系统之间同步访问共享资源的一种方式。在分布式系统中,常常需要协调他们的动作。如果不同的系统或是同一个系统的不同主机之间共享了一个或一组资源,那么访问这些资源的时候,往往需要互斥来防止彼此干扰来保证一致性,在这种情况下,便需要使用到分布式锁。”
这是百度百科的解释。由此可知,分布式锁是用于分布式系统的一种锁。分布式锁相对于单体单机的单系统而言。在单体系统中,当然也有锁,比如我们在开发多线程系统中,修改一些公有变量的值就常常要加锁。数据库中的表、记录也有锁,比如表锁、行锁之类的。
二、为什么要有分布式锁
从分布式锁的概念可知,在分布式系统中,加锁也是为了管理多节点共同操作共享资源而设置的。总的来说,使用分布式锁,目的有二:
1、维持共享资源的一致性
2、避免多节点对共享资源进行重复操作
避免重复操作好懂。维持共享资源的一致性也不难理解。所谓一致性,跟单体中的一致性是一样的,就是避免:
1)不可重复读
A节点先读数据,期间B节点对数据进行了操作,则A操作处理期间的数据与真实不符。
2)脏读
A节点先读数据,处理后保存,此时B节点读取数据;接着A节点处理过程中发现故障,将数据回滚,则B读到的数据与真实不符。
3)修改丢失
A、B两节点同时读取数据,分别处理后保存;则必有一个节点将另一节点的修改覆盖。想想银行余额操作,票务操作之类。
本质上是一样的。可能分布式锁比单体系统中的锁多的一点就是避免重复劳动。其实也可以将多线程看做是缩微的分布式系统。
三、分布式锁的实现
如上所述,分布式锁和单体系统里的锁没有本质上的区别。只是分布式系统由多节点组成,每个节点相对独立,之间靠通讯联结,不可测因素较多。比如,A节点加了一把锁,按照剧本处理完毕后会释放锁,然后它故障了,那么这把锁一直在,其他节点就用不了了,因此要有过期时间;然后问题又来了,节点间是分布式的,一般靠心跳之类的机制来维系。假如超时后,节点忽然又联系上了,继续之前的工作,然后释放锁,此时锁已为其他节点所有,那么对其他节点是否有影响?。。。
所以说,分布式锁比单体系统中的锁更复杂,考虑的因素更多。
查了下资料,分布式锁可以自己实现,比如用数据库来实现,将锁标识之类记录在数据库里,这估计是最原始最自然的办法;也可以用redis创建变量,什么zookeeper框架的创建新节点之类的机制。
四、锁的类型
锁的类型按不同的标准,可以有多种划分。比如共享锁、排他锁;乐观锁、悲观锁。不同维度就有不同的锁。
共享锁用于读,只要加了共享锁,就不能加排他锁;共享锁不一定要显式释放,只要有人申请,就转移给他了,只有一把;排他锁用于写,只能一人申请,显式释放。
悲观锁,假定数据或资源很多人抢,大概率会被修改,所以操作前先申请锁,否则不开动。共享锁,排他锁都属于悲观锁。悲观锁较消耗资源。
乐观锁,相反,认为资源修改几率不高,在提交前才检查下是否有冲突,有冲突才采取相应补救措施。乐观锁比较宽松,通常读取数据时将数据和数据版本一起读出吗,然后回写时通过检查数据的版本号来实现。比如:
参考文章:
什么是分布式锁?