分布式锁之Redis锁实现

零跑项目这一年,从盲订,IP征集,双11抢订,到七城展,好友砍价。需求所涉及的并发越来越高。之前投机取巧走弯路,而现在,redis锁终究要用上。

先前,把redis并发锁想得过于复杂。初步了解后发现,redis并发锁确实简单实用。

今天分三步学习:1,锁,2redis并发锁,3.进阶讨论

 

问题一:什么时候需要考虑并发问题呢?

多个线程   对  单一资源   进行   互斥写操作 的时候,我们需要考虑并发隐患

多线程:可以是一个节点(一台服务器)上同时运行多个线程,也或是多服务器负载均衡。

单资源:多个线程对一个资源,一个数据

互斥操作:每个线程之间的操作对其他线程造成影响(举例:抢票中,票的数量是单一资源且实时的余票数,对每个线程都有影响。  反例:更改昵称是单一资源,但是各个线程先后更改昵称的行为非互斥,并不相互影响,最后更改成功的为有效即可)

 

问题二:锁需要具备那些特性呢(理论知识,面试的时候哈nb用。这段内容是原文复制的,别赞要脸)

1.原子性:一个操作或者多个操作要么全部执行并且执行的过程不会被任何因素打断,要么就都不执行。

2.可见性:多个线程访问同一个变量时,一个线程修改了这个变量的值,其他线程能够立即看得到修改的值。

3.有序性:程序在执行的时候,程序的代码执行顺序和语句的顺序是一致的。

 

问题三:实现并发锁有哪些方式呢?

如果只是单节点多线程服务,完全可以使用 synchronizeLock实现。

扩展知识(只是怕我自己忘)--> syncronize与lock的比较:https://blog.csdn.net/dahongwudi/article/details/78201082

在多节点负载中, synchronize 或 Lock已经完全不够用。我们需要的是分布式锁。

 

分布式锁三大实现:

1、数据库锁:  增加数据库压力,非优雅式阻塞。数据库主键锁 原理与redis相仿。同时数据库也有乐观锁

扩展知识:{

      乐观锁是CAS——Check And Set 如: update tab set a = a+1 where a<10 此处的a<10就是 乐观锁的check;

      悲观锁是假定会发生并发冲突屏蔽一切可能违反数据完整性的操作——如 使用with (UPDLOCK)  或SELECT * FROM tab  WHERE id=1 FOR UPDATE 中的 FOR UPDATE; 

      悲观锁实现的效果是:在查询记录的时候我们就对记录加上了更新锁,表示我们即将对此记录进行更新,所以其他的更新用户就会阻塞

}

2、redis锁: 性能佳,效率高,通过setnx和lua脚本shinx脚本保证解锁时缓存原子性,通过sentinel保证高可用,但同样是非优雅是阻塞锁

3、zookeeper:基于节点特性及 watch实现优雅阻塞锁,健壮性显优于redis。需根据框架 和 业务实际情况 去选择zookeeper或redis。

 

问题四:redis如何实现分布式锁

原理是,redis存储一个键值对,多线程 使用统一的key去存储。存储之前先查询,若查询key无值,就存上值(标识获取锁成功)。进行互斥的业务操作。操作完成后将存储值移除(移除,暂时可理解为删除)。若查询key有值,标识锁正在被使用,则获取锁失败。

简单吧,白话文一句话都能说清的原理,但也有几个要点需留意;

1.使用setnx赋值,而不是简单的set,setnx的用途就是赋值前先查询,如果不存在则赋值,如果存在返回0标识失败。成功返回1。

2.所赋值的value值 必须是唯一值。且解锁时   需匹配value值相同后才可执行解锁。解铃还须系铃人

3.解锁命令并非简单的删除,使用EVAK执行lua脚本,保证解锁时的原子性。

 

问题五:redis在java中如何使用redis锁。

方法当然不是唯一的,本章提供两个方法。

1.jedis:最为常用的jedis。提供了现成的setnx方法,当然更推荐使用set(key,value,nx,px.有效时间)的方法。有效时间写出中文。大家也能猜到,区别在于后者可以设置有效时间。当时用上锁方法后,当然后再try{}finally{}的finally来确保解锁一定被执行,但是防患于未然,加上有效时间,可以更好的避免宕机导致解锁未执行,导致的死锁。

未获取锁的线程,通过循环或递归进行等待,这也就是传说中的 非非非非优雅式阻塞。

2.redisTemplate:他是对redis提供的jedis方法,进行了封装。具体使用和优缺点不细说了。再写就成长篇小说了。本人纵横江湖多年,一向是以短小精悍为宗旨。

 

进阶篇来日补上,会献上jedis 和 redisTemplate,java代码。聊一聊redis进阶知识,切换锁丢失问题,已经对应的RedLock处理方案。

 

 

 

 

 

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值