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

Redis-5.0141 分布式锁-18

时间:2022-08-16 22:37:27浏览次数:61  
标签:释放 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,加锁,线程,分布式,客户端
From: https://www.cnblogs.com/ggzs/p/16592872.html

相关文章

  • ModuleNotFoundError: No module named 'pygal.i18n'
    1.问题:ModuleNotFoundError:Nomodulenamed'pygal.i18n'  2.解决方法:File->Settings->点击底部加号(+)->AvaiablePackages->pygal-maps_world->installPackage......
  • Redis的两种持久化机制
    Redis的两种持久化机制1、持久化机制client--->redis(内存)--->内存数据-数据持久化--->磁盘两种方法快照(Snapshot)AOF(AppendOnlyFile)只追加日志文件2、快照2.1......
  • Redis主从复制
    Redis主从复制主从复制架构仅仅用来解决数据的冗余备份,从节点仅仅用来同步数据。如果主节点因为某些原因出现了故障导致宕机,无法接收数据,那么从节点也会与主节点断开连接......
  • Redis---客户端命令
    1.前言Redis提供了一些操作客户端(client)的命令,比如查询所有已连接到服务器的客户端数量,控制客户端的连接状态(关闭或者挂起)等。通过客户命令我们可以轻松的实现对客户端的......
  • Redis---zset有序集合(底层原理+图解)
    1.前言顾名思义,Rediszset(有序集合)中的成员是有序排列的,它和set集合的相同之处在于,集合中的每一个成员都是字符串类型,并且不允许重复;而它们最大区别是,有序集合是有序的,s......
  • Redis实现延迟队列
     一、延迟队列进入该队列的消息会被延迟消费的队列,一般的队列,进入队列后会进行排队依次消费掉二、使用场景需要进行延迟消费的场景,本文举例为某本书籍更新了章节,待内......
  • Redis---hash哈希散列
    1.前言Redishash(哈希散列)是由字符类型的field(字段)和value组成的哈希映射表结构(也称散列表),它非常类似于表格结构。在hash类型中,field与value一一对应,且不允许重......
  • Redis---set集合
    1.前言Redisset(集合)遵循无序排列的规则,集合中的每一个成员(也就是元素,叫法不同而已)都是字符串类型,并且不可重复。Redisset是通过哈希映射表实现的,所以它的添加、删除......
  • Redis---列表
    1.前言Redislist(列表)相当于Java语言中的LinkedList结构,是一个链表而非数组,其插入、删除元素的时间复杂度为O(1),但是查询速度欠佳,时间复杂度为O(n)。当向列表中添......
  • 项目中,需要对设备上线离线的动作做日志打印. (利用redis发布订阅监听key解决. 观
    https://blog.csdn.net/weixin_44642403/article/details/116278262?ops_request_misc=&request_id=&biz_id=102&utm_term=redis%E7%9B%91%E5%90%ACkey%E5%9C%A8%E4%BB%80%......