Redis大白话(●四●)

目录

🧡锁

🧡分布式锁

基于数据库

基于Redis(性能最高)

基于Zookeeper(可靠性最高)


💟这里是CS大白话专场,让枯燥的学习变得有趣!

💟没有对象不要怕,我们new一个出来,每天对ta说不尽情话!

💟好记性不如烂键盘,自己总结不如收藏别人!

💌今天我们主要来讲讲Redis分布式锁,同时了解下锁的相关知识。

🧡锁

💌锁(Lock)是保证数据安全的一种机制和手段。当多个线程要修改同一个共享变量时,我们可以给修改操作上锁(syncronized);当多个用户要修改表中同一个数据时,我们可以给该行数据上锁(行锁)。锁其实是在并发下控制多个操作的顺序执行,以此来保证数据的安全变动

💌当只有一台服务器时,在当前服务器的JVM内部,维护了一个锁监视器对象synchronized就是利用JVM内部的锁监视器来控制线程的,可以保证同一台服务器内的线程互斥。但是当有多台服务器需要访问同一个资源时,当前服务器无法得知其他服务器的上锁情况,为了解决这个问题,我们需要一种跨JVM的互斥机制来控制共享资源的访问,也就是分布式锁

🧡分布式锁

💌在JVM外部的锁监视器,满足在分布式系统或集群模式下多线程可见并且互斥的锁。

基于数据库

🍠乐观锁:允许多个线程访问数据,通过在表中增加一个版本(version)或时间戳(timestamp)来实现。当线程对数据修改之后,会将之前取出的版本/时间戳与当前的版本/时间戳对比,如果相等,那么说明在数据修改期间,没有其他线程对数据进行修改,此时,就允许线程对表中的数据进行
更新,并且同时更新版本+1/当前时间戳。如果不相等,那么说明数据被其他线程更新过了,此时不允许数据更新到表中,一般的处理办法是重新操作。

🍠悲观锁:一个线程拿到悲观锁后,其他任何线程都不能对该数据进行修改,只能等待锁被释放才可以执行。数据库中的行锁,表锁,读锁,写锁,以及syncronized实现的锁均为悲观锁。

基于Redis(性能最高)

🍠SETNX + EXPIRE

💌SETNX 是 SET IF NOT EXISTS 的简写,如果锁key不存在,则SETNX返回1,成功上锁,如果锁key存在,返回0。先用 SETNX 上锁,再用 EXPIRE 给锁设置一个过期时间,防止忘记释放锁,也可以直接用 DEL key 直接删除锁。

命令格式:SETNX key value + EXPIRE key seconds

 💌存在问题:SETNX 和 EXPIRE 不是一个原子操作,在 SETNX 命令执行之后服务器可能会宕机,导致锁永久无法释放。

🍠SET 扩展命令

💌使用SET扩展命令在上锁的同时设置过期时间

命令格式:SET key value [EX seconds|PX milliseconds|EXAT timestamp|PXAT milliseconds+timestamp|KEEPTTL] [NX|XX] [GET]

NX:key不存在时对锁进行操作。

XX:key存在时对锁进行操作。

💌存在问题:当前线程的任务还没有执行完就到期释放锁了,这时其他线程抢到锁,当前线程执行完任务手动释放锁时就会释放其他线程上的锁。

🍠 SET + UUID

💌上锁时设置value为标记当前线程唯一的随机数uuid,防止误删其他线程的锁。在释放锁时判断锁的uuid和自己的uuid是否一致,一致则释放。

💌存在问题:比较uuid一致之后,还没等线程手动释放就刚好到期释放锁了,其他线程抢到锁,当前线程再删除的时候依然会删除其他线程的锁。

🍠 Lua脚本

💌保证加锁和释放锁时的原子性。

// 加锁
String lua_scripts = "if redis.call('setnx', KEYS[1], ARGV[1]) == 1 then redis.call('expire', KEYS[1], ARGV[2]) return 1 else return 0 end";
// 释放锁
String lua_script = "if redis.call('get', KEYS[1]) == ARGV[1] then return redis.call('del',KEYS[1]) else return 0 end"; 

🍠 Redisson

💌给获得锁的线程开启一个定时守护线程watch dog,每隔一段时间检查锁是否还存在,存在则对锁的过期时间延长,防止锁过期提前释放。

基于Zookeeper(可靠性最高)

💌关于Zookeeper会单独开一章进行总结~

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值