当前位置: 首页 > 科技观察

分布式锁——初探

时间:2023-03-18 16:51:49 科技观察

一、分布式锁的背景开发者经常会遇到多个线程在一个JVM实例中争用独享的共享资源。正好JDK提供了这样的synchronized,JUC包中的xxxLock都是锁工具,可以方便的实现关键资源的互斥;使用锁是一种显式同步方法,用于控制线程间操作的相对顺序。其实还有一种隐式同步方式,就是消息传递,不过大家似乎更熟悉显式使用锁。当前的大多数系统已经演化为分布式架构。例如,一个实例中的多个线程必须相互排除对关键资源的使用。在分布式情况下,也有共享资源需要在多个实例之间独占使用。这个问题就是分布式互斥的问题。.虽然大佬Lamport已经在论文《Time, clocks, and the ordering of events in a distributed system》中证明了使用状态机(比如共识算法)可以去中心化的解决多进程互斥问题,但是我们还是更倾向于对以下三种使用分布式锁原因:Point:使用分布式锁服务可以更容易维护现有程序的结构。程序员更熟悉使用锁来同步对资源的访问。共识算法可能需要客户端运行在更多的服务器上才能满足共识算法的要求,但实际只是满足客户端的功能需求,并没有使用那么多的服务器。总的来说,分布式锁更轻便,更易于使用,并且更节省资源。2、使用分布式锁的目的使用分布式锁的目的主要有两个:效率:使用锁避免重复工作,计算重复内容等。这种场景下,即使多个用户同时持有锁,同时与资源服务进行交互,也是可以容忍的。Correctness:即“安全”,我们希望资源服务在锁的保护下能够做“正确”的事情。更严格的说,我们希望在任意时刻,只有一个用户可以访问资源服务,即使在用户与资源服务交互的过程中,锁过期了,资源服务的一致性也不会受到影响。被毁。3、分布式锁的功能特点一个分布式锁应该具备以下功能特点:互斥:同一时间只有一个客户端持有锁安全:为避免死锁,如果一个客户端获取锁如果处理时间超过最大约定时间,或者在持锁期间发生故障无法主动释放锁,其持有的锁也可以通过其他机制正确释放,并保证以后其他客户端也可以加锁,并且整个处理流程继续正常执行。可用性:又称容错,分布式锁需要具备高可用性,避免单点故障。当提供锁的服务节点发生故障(宕机)时,不影响服务运行。这里有两种模式:一种是分布式锁服务本身有集群模式,遇到故障可以自动切换恢复工作;另一种是客户端向多个独立的锁服务发起请求。当一个锁服务失败时,它仍然可以从其他锁服务读取锁。信息(Redlock)重入:对于同一个锁,加锁和解锁必须是同一个进程,即其他进程持有的锁不能被释放。高效灵活:锁定和解锁速度更快;支持阻塞和非阻塞;支持公平锁和非公平锁。4、多视角下的分布式锁通过不同的视角,可以从多个维度全面了解各种分布式锁的实现差异。视角一:轮询:基于数据库和Redis实现的分布式锁。此类实现方式需要客户终端不断重复请求锁服务,检查是否可以获取到锁;监控类:基于ZooKeeper或etcd的分布式锁。这种实现客户端只需要监听(watch)某个键即可。当锁可用时,锁服务会通知客户端,而不需要客户端不断地请求锁服务。视角二:基于数据库的分布式锁:使用基于主键的乐观锁、悲观锁或唯一约束实现分布式锁基于分布式缓存:Redis和基于Redis的基于分布式共识算法的RedLock(Redisson)分布式锁:ZooKeeper、etcd视角3:MartinKleppmann在个人博客中发表了一篇Howtododistributedlocking的文章,其中涉及到很多对Redlock算法安全性的质疑。SalvatoreSanfilippo(Redis的创始人,也是这里的Redlock算法的作者)随后发表了IsRedlocksafe?针对这些质疑;这两个大家伙的对决肯定是围观的。