ICode9

精准搜索请尝试: 精确搜索
首页 > 数据库> 文章详细

Redis-5.0141 分布式锁-18

2022-08-16 22:30:08  阅读:205  来源: 互联网

标签:释放 5.0141 18 redis Redis 加锁 线程 分布式 客户端


1. 问题描述

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

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

  • 基于数据库实现分布式锁

  • 基于缓存(Redis 等)

  • 基于 Zookeeper

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

  • 类 CAS 自旋式分布式锁:询问的方式,类似 java 并发编程中的线程获询问的方式尝试加锁,如 mysql、redis。

  • 另外一类是 event 事件通知进程后续锁的变化,轮询向外的过程,如 zookeeper、etcd。

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

   性能: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

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有