Redis分布式锁

最近工作涉及到一个需求是关于禁止重复操作的后端校验,当时通过一种与业务耦合的redis加锁方式暂时满足了功能需求,后来在大佬的指点下将该功能抽离出来单独做一个组件,公司目前的项目是典型的分布式系统,自己之前接触的很少,中途也遇到了一些困难,在此做下总结。(基于Spring AOP+自定义注解实现redis分布式锁)什么是分布式锁要介绍分布式锁,首先要提到与分布式锁相对应的是...
摘要由CSDN通过智能技术生成

        最近工作涉及到一个需求是关于禁止重复操作的后端校验,当时通过一种与业务耦合的redis加锁方式暂时满足了功能需求,后来在大佬的指点下将该功能抽离出来单独做一个组件,公司目前的项目是典型的分布式系统,自己之前接触的很少,中途也遇到了一些困难,在此做下总结。(基于Spring AOP+自定义注解实现redis分布式锁)

什么是分布式锁

要介绍分布式锁,首先要提到与分布式锁相对应的是线程锁、进程锁。

① 线程锁:主要用来给方法、代码块加锁。当某个方法或代码使用锁,在同一时刻仅有一个线程执行该方法或该代码段。线程锁只在同一JVM中有效果,因为线程锁的实现在根本上是依靠线程之间共享内存实现的,比如synchronized是共享对象头,显示锁Lock是共享某个变量(state)。

② 进程锁:为了控制同一操作系统中多个进程访问某个共享资源,因为进程具有独立性,各个进程无法访问其他进程的资源,因此无法通过synchronized等线程锁实现进程锁。

分布式锁:当多个进程不在同一个系统中,用分布式锁控制多个进程对资源的访问。
 

为什么需要分布式锁(即要解决什么问题)

        随着业务越来越复杂,应用服务都会朝着分布式、集群方向部署,而分布式CAP原则告诉我们,Consistency(一致性)、 Availability(可用性)、Partition tolerance(分区容错性),三者不可得兼。实践中一般满足CP或AP。

很多场景中,需要使用分布式事务、分布式锁等技术来保证数据最终一致性。有的时候,我们需要保证某一方法同一时刻只能被一个线程执行。   

        在单机环境中,多个线程对共享变量进行访问时,我们可以简单的通过Java自身的同步操作来协调同一时刻对变量的串行访问。然而在分布式环境中,进程的独立性,进程之间无法访问相互之间的资源,无法像之前那样的方式实现进程锁,故需要一个独立的中心节点,以协调多个系统对共享变量的访问,所有进程在访问该变量时,都从同一个地方进行取值并控制,从而实现在类似于单机环境中同步控制的效果。      

需要满足什么条件

① 可以保证在分布式部署的应用集群中,同一个方法在同一时间只能被一台机器上的一个线程执行
② 这把锁要是一把可重入锁(避免死锁)
③ 这把锁最好是一把阻塞锁
④ 有高可用的获取锁和释放锁功能
⑤ 获取锁和释放锁的性能要好

实现方式

主要有三种实现方式:①基于数据库(乐观锁);②基于缓存(redis,memcached等)③基于zookeeper

本次实践主要选用第二种,基于redis进行实现。

实现思路

粗粒度的大致思路:

① 在对共享变量(key)操作前,判断该变量值在redis中是否有对应的key

② 若无,则设置到redis中,并设置该key的超时时间,返回true;若有,则说明该变量已经被别的线程/进程持有,不做任何动作,返回false

大致的思路相对简单,实际实现会遇到很多困难,如实现方式,加锁位置,操作原子性,死锁问题,性能问题等。

实现方案

以下方式没有谁好谁坏之分,需要看实际的业务情况取舍,性能,或是跟业务代码的耦合度,代码结构设计等等

① 以服务的方式提供分布式锁

  这种方式主要是将加锁解锁操作封装成一个服务提供给业务使用,将锁服务耦合到业务中,能够较细粒度的控制好变量的访问,实现较为灵活,性能相对较好,但是技术需求对于业务代码的入侵相对较多。

② 以切面的方式提供分布式锁

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值