单体时代,可以直接用本地锁来实现对竞争资源的加锁,分布式环境下就要用到分布式锁了。
分布式锁是一种在分布式系统中用于控制并发访问的机制。在分布式系统中,多个客户端同时对同一个资源进行访问时,容易出现数据不一致的问题。分布式锁的作用就是确保同一时刻只有一个客户端能够对某个资源进行访问,以避免数据不一致的问题。
分布式锁通常基于某种共享存储机制实现,比如分布式缓存、数据库或者文件系统等。具体实现方式可以分为乐观锁和悲观锁两种。
分布式锁通常用于以下场景:
分布式缓存:在分布式缓存中,多个节点同时对同一个缓存进行操作时,可能会出现数据不一致的问题。使用分布式锁可以确保同一时刻只有一个节点能够对该缓存进行操作,以避免数据不一致的问题。
数据库操作:在进行数据库操作时,多个节点可能会同时对同一数据进行读写操作,导致数据不一致。使用分布式锁可以确保在同一时刻只有一个节点能够对数据进行操作,保证数据的一致性。
任务调度:在分布式系统中,多个节点可能会同时对同一任务进行操作,导致任务重复执行或者任务未执行。使用分布式锁可以确保在同一时刻只有一个节点能够执行该任务,保证任务的正确性。
总的来说,分布式锁是一种非常重要的技术,可以有效地解决分布式系统中的并发访问问题,保证数据的一致性和正确性。
5. 有哪些分布式锁的实现方案呢?
常见的分布式锁实现方案有三种:MySQL分布式锁、ZooKepper分布式锁、Redis分布式锁。
分布式锁
5.1 MySQL分布式锁如何实现呢?
用数据库实现分布式锁比较简单,就是创建一张锁表,数据库对字段作唯一性约束。
加锁的时候,在锁表中增加一条记录即可;释放锁的时候删除记录就行。
如果有并发请求同时提交到数据库,数据库会保证只有一个请求能够得到锁。
这种属于数据库 IO 操作,效率不高,而且频繁操作会增大数据库的开销,因此这种方式在高并发、高性能的场景中用的不多。
5.2 ZooKeeper如何实现分布式锁?
ZooKeeper也是常见分布式锁实现方法。
ZooKeeper的数据节点和文件目录类似,例如有一个lock节点,在此节点下建立子节点是可以保证先后顺序的,即便是两个进程同时申请新建节点,也会按照先后顺序建立两个节点。
ZooKeeper如何实现分布式锁
所以我们可以用此特性实现分布式锁。以某个资源为目录,然后这个目录下面的节点就是我们需要获取锁的客户端,每个服务在目录下创建节点,如果它的节点,序号在目录下最小,那么就获取到锁,否则等待。释放锁,就是删除服务创建的节点。
ZK实际上是一个比较重的分布式组件,实际上应用没那么多了,所以用ZK实现分布式锁,其实相对也比较少。
5.3 Redis怎么实现分布式锁?
Redis实现分布式锁,是当前应用最广泛的分布式锁实现方式。
Redis执行命令是单线程的,Redis实现分布式锁就是利用这个特性。
实现分布式锁最简单的一个命令:setNx(set if not exist),如果不存在则更新:
setNx resourceName value
加锁了之后如果机器宕机,那我这个锁就无法释放,所以需要加入过期时间,而且过期时间需要和setNx同一个原子操作,在Redis2.8之前需要用lua脚本,但是redis2.8之后redis支持nx和ex操作是同一原子操作。
Redission
当然,一般生产中都是使用Redission客户端,非常良好地封装了分布式锁的api,而且支持RedLock。
领取专属 10元无门槛券
私享最新 技术干货