首页 > 数据库 >Redis实现分布式锁

Redis实现分布式锁

时间:2024-08-18 09:51:39浏览次数:9  
标签:加锁 实现 Redis 过期 线程 进程 分布式

Redis分布式锁是一种在分布式系统中协调多个进程对共享资源访问的同步机制。在单机系统中,可以使用传统的锁机制来保证同一时间只有一个线程访问某个资源。然而,在分布式系统中,由于多个进程可能在不同的服务器上运行,传统的锁机制就不再适用。这时就需要一种跨多个进程的锁机制,即分布式锁。

分布式锁应具备的特性:

  1. 互斥性:在任意时刻,只有一个进程可以持有锁。
  2. 安全性:锁需要保证在分布式系统中的安全性,即使在网络分区或其他故障情况下也能正常工作。
  3. 死锁容错性:即使在某个进程异常或宕机的情况下,锁也能被其他进程获取。
  4. 性能:加锁和解锁操作应该尽可能快,以避免影响系统性能。
  5. 可重入性:同一个进程可以多次获取同一把锁。
  6. 锁超时:锁需要有一个超时时间,以避免因为某些原因导致锁无法释放。

Redis分布式锁的实现方式:

  1. SETNX + EXPIRE:使用SETNX命令设置键,如果键不存在则设置成功,然后使用EXPIRE设置键的过期时间。但这种方式不是原子操作,可能存在安全问题。

  2. SET命令扩展:使用SET key value EX seconds PX milliseconds NX命令,其中EXPX分别设置键的过期时间(秒和毫秒),NX表示只有键不存在时才设置。

  3. Lua脚本:使用Lua脚本保证加锁操作的原子性,减少因进程崩溃导致锁无法释放的风险。

  4. Redisson框架:Redisson是一个基于Redis的Java框架,提供了多种分布式数据结构和服务,包括实现分布式锁的功能。Redisson使用看门狗机制来自动续期锁,避免锁过期。

  5. Redlock算法:由Redis作者提出的一种算法,使用多个Redis master节点来实现高安全性的分布式锁。客户端尝试在多个Redis实例上加锁,如果大多数实例加锁成功,则认为锁获取成功。

使用场景:

  • 秒杀活动:确保同一时刻只有一个用户可以成功下单。
  • 订单处理:在处理订单时,确保同一订单不会同时被多个进程处理。
  • 库存管理:在库存有限的情况下,防止超卖。

注意事项:

  • 锁的超时时间应该根据业务逻辑的执行时间来合理设置。
  • 在分布式锁实现时,需要考虑到网络分区、节点故障等异常情况。
  • 释放锁时,需要确保只有加锁的进程可以释放锁,避免安全问题。

Redis分布式锁由于其高性能和易用性,在现代分布式系统中得到了广泛应用。然而,正确实现分布式锁需要仔细考虑各种异常情况,以确保系统的稳定性和数据的一致性。下面给大家介绍一种现在比较常用的redis分布式锁,基于Redission实现分布式锁。

基于Redission实现分布式锁

使用Redission分布式锁,保障在分布式的条件下,可以锁住多个线程,不会因为做了Nginx负载均衡之后,导致被同步锁锁住的资源被其他服务器的进程当中的线程所访问。

通过SetNX实现分布式锁的话,它主要是通过SetNX设置一个键,如果这个键没有值则表示加锁成功,如果有值则表示当前的锁不可用。使用SetNX的时候,一定一定要加一个过期时间,因为如果不加过期时间,当这个服务器挂了之后,则会导致这个锁一直被占用,从而导致一个死锁的问题。

使用SetNX有一个很大的弊端,即如果业务的处理时间超过了锁的过期时间,那么当过期时间到了,即使业务未处理完,整个锁也会被释放,其他的线程便会来使用这把锁,整体的业务流程就会出现很大的问题。这时可以通过增加业务时间,和设置一个子线程每隔一段时间查看业务线程是否还在,在的话就自动增加过期时间,这个实现起来十分困难。

因此,redis提供了这个redission组件,来实现了上述的功能。下面为Redisson的实现原理,即获取锁,然后获取成功之后,便会执行相关业务,同时由于看门狗机制的存在,它会自动检测该线程是否还持有锁。

并且为了保证redis在分布式集群中的数据一致性的问题,redisson还提供了一个Redlock机制,用来保证主从结点之间的数据强一致性问题。如果未使用redlock,则在主节点数据操作完成后,便会响应一个操作成功,而使用redlock的话,只有当所有的主从节点都把相关数据操作完成后,才会响应一个操作成功,达到了数据强一致性的目的。

 分布式锁在当前的主流业务中十分的常见,有时候还会配合相关的消息队列一同来实现相关的功能。Redission的分布式锁实现起来十分简单,只需导入相关依赖后,通过一个try.lock便可实现对资源的上锁。

笔者小,中,大厂均有面试经验,目前正在从事全栈开发工作,坚持每日分享java全栈开发知识与相关的面试真题,希望能够给大家带来帮助,同大家共同进步。

标签:加锁,实现,Redis,过期,线程,进程,分布式
From: https://blog.csdn.net/qq_56438516/article/details/141280279

相关文章

  • C#实现国产Linux视频录制生成mp4(附源码,银河麒麟、统信UOS)
    随着信创国产化浪潮的来临,在国产操作系统上的应用开发的需求越来越多,最近有个客户需要在银河麒麟或统信UOS上实现录制摄像头视频和麦克风声音,将它们录制成一个mp4文件。那么这样的功能要如何实现了?一.技术方案要完成这些功能,具体来说,需要解决如下几个技术问题:(1)麦克风数据采集......
  • 【数据结构】详细剖析链表,带你实现单链表,双向链表,附链表编程练习题
    目录一.链表1.链表的概念及结构2.单链表的实现2.1单链表节点结构2.2动态申请一个节点2.3单链表打印2.4单链表尾插2.5单链表头插2.6单链表尾删2.7单链表头删2.8单链表查找 2.9单链表在pos后一位插入x2.10单链表删除pos后一位的值2.11单链表销毁 ......
  • Roslyn 简单实现代码智能提示补全功能
    相信有很多伙伴热衷于编写IDE应用,在dotnet系下,通过Roslyn友好的API和强大的能力,实现一个代码智能提示是非常简单的事情。本文将和大家简单介绍一下如何使用Roslyn实现简单的代码智能提示补全功能现在的dotnetC#核心构建工具链是非常完善的且开放的,基于dotnet完善......
  • RabbitMQ实现消息可靠性的三种方法(发送者可靠性,MQ可靠性,消费者可靠性)
    1.发送者可靠性1.1发送者重连RabbitMQ的发送者重连机制是一种应对网络不稳定或连接中断情况的策略,它能够自动尝试重新建立与RabbitMQ服务器的连接,以确保消息能够成功发送。发送者重连通常涉及到一些配置参数,如连接超时时间、重试间隔、最大重试次数等。例如,在Spring框架的......
  • 基于Java+SpringBoot+Mysql实现的共享厨房平台功能设计与实现四
    一、前言介绍:1.1项目摘要随着城市化进程的加快和人们对生活品质要求的提升,共享经济模式在全球范围内迅速兴起。共享厨房平台作为共享经济的一种创新形式,旨在通过整合闲置的厨房资源,为用户提供一个便捷、经济且富有创意的烹饪空间。现代都市生活中,许多年轻人、创业者及小......
  • 基于Java+SpringBoot+Mysql实现的共享厨房平台功能设计与实现六
    一、前言介绍:1.1项目摘要随着城市化进程的加快和人们对生活品质要求的提升,共享经济模式在全球范围内迅速兴起。共享厨房平台作为共享经济的一种创新形式,旨在通过整合闲置的厨房资源,为用户提供一个便捷、经济且富有创意的烹饪空间。现代都市生活中,许多年轻人、创业者及小......
  • [Redis]缓存穿透/缓存击穿/缓存雪崩
    缓存穿透用户访问一些不存在的数据,redis没有,于是去mysql查询也没有,这样就发生了两次无效的查询。缓存穿透是指客户端请求的数据在缓存中和数据库中都不存在,缓存永远不会生效。这样,每次针对此key的请求从缓存获取不到,请求都会压到数据源,从而可能压垮数据源。比如用一个不存在的......
  • [Redis]延迟消息队列
    延迟消息队列redis数据结构,用什么结构实现延迟消息队列延迟消息队列是一种消息队列系统,它允许消息的发布者在消息发送时指定消息的投递时间,使消息在未来的某个预定时间点被消费者接收。这种机制对于需要在稍后执行的任务或具有特定延迟需求的应用非常有用。对于实现延迟消息队......
  • 驾驭数据之序:SQL序列的奥秘与实现
    标题:驾驭数据之序:SQL序列的奥秘与实现摘要在数据库管理中,保证数据的有序性和唯一性是至关重要的。SQL序列(Sequence)作为一种强大的数据库对象,为我们提供了一种在不同数据库系统中生成连续数字的手段。本文将深入探讨序列的概念、重要性以及在不同SQL环境中的实现方法。1.......
  • Redis中Big Key该如何解决?
    目录1、BigKey的产生2、BigKey场景分析3、BigKey的危害4、检测BigKey 5、解决BigKey问题BigKey拆分(1)按时间/业务拆分(2)按哈希(Hash)拆分(3)按前缀树拆分BigKey定期清理Bigkey压缩BigKey批处理优化持久化配置6、总结 BigKey问题是指某个键(key)的值(value)......