数据库
首页 > 数据库> > Redis-5.0141 分布式锁-18

Redis-5.0141 分布式锁-18

作者:互联网

1. 问题描述

    随着业务发展的需要,原单体单机部署的系统被演化成分布式集群系统后,由于分布式系统多线程的特点以及分布在不同机器上,这将使原单机部署情况下的并发控制锁策略失效,单纯的 Java API 并不能提供分布式锁的能力。为了解决这个问题就需要一种跨 JVM 的互斥机制来控制共享资源的访问,这就是分布式锁要解决的问题!

2. 分布式锁主流的实现方案:

    根据实现方式,分布式锁还可以分为类 CAS 自旋式分布式锁以及 event 事件类型分布式锁:

每一种分布式锁解决方案都有各自的优缺点:

   性能:redis 最高

   可靠性:zookeeper 最高

3.用java代码使用redis分布锁

    用setnx 的返回值来判断是否有线程正在进行操作,只是用一个键值对作为锁,和java业务代码没有关系 线程是一个个进行排队,只有当返回值是0的时候,说明前面以及没人在操作了.

4.遇到的问题

4.1 其他线程把正在执行线程的锁给释放了

解决方法:利用UUID生成随机值,当进行释放锁操作时先对UUID的随机值进行判断,相同再释放. 这就解决了可能被其他线程释放锁的问题.

4.2 还有一种可能就是在确认过uuid,即将要释放锁时,锁到了过期时间,自动释放了. 这时候另一个线程拿到了锁,并且在进行具体操作时,锁被上一个线程给释放了.

解决方法: 使用lua脚本进行释放锁.


为了确保分布式锁可用,我们至少要确保锁的实现同时满足以下四个条件:

1. 互斥性。在任意时刻,只有一个客户端能持有锁。

2. 不会发生死锁。即使有一个客户端在持有锁的期间崩溃而没有主动解锁,也能保证后续其他客户端能加锁。

3. 解铃还须系铃人。加锁和解锁必须是同一个客户端,客户端自己不能把别人加的锁给解了。

4. 加锁和解锁必须具有原子性。

标签:释放,5.0141,18,redis,Redis,加锁,线程,分布式,客户端
来源: https://www.cnblogs.com/ggzs/p/16592872.html