栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

redis分布式锁

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

redis分布式锁

什么是分布式锁?         线程锁:主要用来给方法、代码块加锁。当某个方法或代码使用锁,在同一时刻仅有一个线程执行该方法或该代码 段。线程锁只在同一 JVM 中有效果,因为线程锁的实现在根本上是依靠线程之间共享内存实现的,比如 synchronized是共享对象头,显示锁 Lock 是共享某个变( state )。         进程锁:为了控制同一操作系统中多个进程访问某个共享资源,因为进程具有独立性,各个进程无法访问其他进程 的资源,因此无法通过 synchronized 等线程锁实现进程锁。         分布式锁:当多个进程不在同一个系统中,用分布式锁控制多个进程对资源的访问 使用分布式锁要满足的几个条件:         1. 系统是一个分布式系统(关键是分布式,单机的可以使用 ReentrantLock 或者 synchronized 代码块来实现)         2. 共享资源(各个系统访问同一个资源,资源的载体可能是传统关系型数据库或者 NoSQL )         3. 同步访问(即有很多个进程同时访问同一个共享资源。)         应用的场景         线程间并发问题和进程间并发问题都是可以通过分布式锁解决的,但是强烈不建议这样做!因为采用分布式锁解决 这些小问题是非常消耗资源的!分布式锁应该用来解决分布式情况下的多进程并发问题才是最合适的。         有这样一个情境,线程A 和线程 B 都共享某个变量 X 。         如果是单机情况下(单JVM ),线程之间共享内存,只要使用线程锁就可以解决并发问题。         如果是分布式情况下(多JVM ),线程 A 和线程 B 很可能不是在同一 JVM 中,这样线程锁就无法起到作用了,这时候 就要用到分布式锁来解决。         分布式锁可以基于很多种方式实现,比如zookeeper 、 redis... 。不管哪种方式,他的基本原理是不变的:用一 个状态值表示锁,对锁的占用和释放通过状态值来标识。 redis实现分布式         Redis为单进程单线程模式,采用队列模式将并发访问变成串行访问,且多客户端对 Redis 的连接并不存在竞争 关系。 redis 的 SETNX 命令可以方便的实现分布式锁。

SETNX key value

        同一时刻只能有一个进程获取到锁。setnx

        将 key 的值设为 value ,当且仅当 key 不存在。         若给定的 key 已经存在,则 SETNX 不做任何动作。         设置成功,返回 1 。 设置失败,返回 0 。         通常使用以下方式进行尝试获取锁:         SETNX lock.foo (锁的结束时间)返回1时说明获取锁成功, 可以通过DEL lock.foo 来删除锁退出。返回0时说明获取失败,此时可以选择重试循环,直到成功或者锁超时结束。                  释放锁:锁信息必须是会过期超时的,不能让一个线程长期占有一个锁而导致死锁; (最简单的方式就是 del , 如果在删除之前死锁了。) getSET         先获取key 对应的 value 值。若不存在则返回 nil ,然后将旧的 value 更新为新的 value 。         语法: GETSET key value         将给定 key 的值设为 value ,并返回 key 的旧值 (old value) 。         当 key 存在但不是字符串类型时,返回一个错误。 解决死锁         有一个问题:如果一个持有锁的客户端失败或崩溃了不能释放锁,该怎么解决 ?         我们可以通过锁的键对应的时间戳来判断这种情况是否发生了,如果当前的时间已经大于lock.foo 的值,说明该锁已失效,可以被重新使用。         但不能简单的去删除锁,通常删除锁是由持有锁者进行的,所以只需要等待超时即可,请求setnx lock.info time 前去获取锁失败时再发送get lock.info 查看锁是否超时,若超时了则进行getset lock.info time 如果拿到的锁仍然是超时的那就说明,拿到锁了,如果不是超时的则被别人抢先一步了。虽然修改了别人的超时时间,但一点点并不会影响什么的。         为了让分布式锁的算法更稳键些,持有锁的客户端在解锁之前应该再检查一次自己的锁是否已经超时, 再去做 DEL 操作,因为可能客户端因为某个耗时的操作而挂起,操作完的时候锁因为超时已经被别人获得,这时就 不必解锁了。
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/351712.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号