本文目录一览:
- 1、Redis分布式锁的原理是什么?如何续期?
- 2、高并发场景Redis分布式锁实现方式
- 3、Redis的Setnx命令实现分布式锁
- 4、如何用redis实现分布式锁
2、redis是保持的AP而非CP , 如果要追求强一致性可以使用zookeeper分布式锁,但是zookeeper也不是完全没问题,在出现网络颜值,客户端与服务端失联情况的时候也依然可能会出现分布式的问题 。
3、分布式锁是控制分布式系统之间同步访问共享资源的一种方式 。原理就是,当我们要实现分布式锁,最简单的方式可能就是直接创建一张锁表,然后通过操作该表中的数据来实现了 。
高并发场景Redis分布式锁实现方式在同一时刻,只能有一个线程去读写一个【共享资源】,也就是高并发的场景下,通常为了保证数据的正确,需要控制同一时刻只允许一个线程访问 。此时就需要使用分布式锁了 。
如果没有其他线程占用,则就可以通过添加分布式锁来占用这个资源,然后再执行后续的任务,在任务执行完成之后,再释放分布式锁,其他线程就可以继续使用这个资源了 。
基于缓存实现分布式锁:理论上来说使用缓存来实现分布式锁的效率最高,加锁速度最快,因为Redis几乎都是纯内存操作,而基于数据库的方案和基于Zookeeper的方案都会涉及到磁盘文件IO,效率相对低下 。
Redis的Setnx命令实现分布式锁在8版本之后,redis为了解决这个问题 , 提供了官方版的解法,就是命令:set key value nx expireTimeNum ex,将上述两个命令合并成了一个命令 。
此时就需要使用分布式锁了 。简而言之 , 分布式锁就是用来控制同一时刻,只有一个线程可以访问被保护的资源 。可以使用 SETNX key value 命令实现互斥的特性 。
EX 10010 指定过期时间 NX 只在键不存在时 , 才对键进行设置操作 。效果等同于 SETNX 命令 。只不过早期版本redis不支持set的扩展参数,这就需要用到 lua 脚本了。
可以在删除锁的时候先get值,判断值是否是当前线程存的随机值,只有相同才执行删锁的操作;当然也要使用 lua 脚本执行来保证原子性 。
例如,你可以使用Redis的SETNX(Set if Not Exists)命令来尝试获取一个锁 。这个命令会尝试设置一个键值对 , 如果键已经存在,则设置失败;否则,设置成功 。
使用Redis实现分布式锁最简单的方案是使用命令SETNX 。SETNX(SET if Not eXist)的使用方式为:SETNX key value , 只在键key不存在的情况下,将键key的值设置为value,若键key存在,则SETNX不做任何动作 。
如何用redis实现分布式锁使用结束后,要及时释放锁,给后面申请获得资源的机会 。释放锁比较简单 , 使用 DEL 命令删除这个 key 就可以了 。
通过调用 unlockInnerAsync(threadId) 来删除 redis 中的 key 来释放锁 。特别注意一点,当不是持有锁的线程释放锁时引起的失败,不需要调用 cancelExpirationRenewal 方法,取消定时,因为锁还是被其他线程持有 。
需要在获得 lock-key 后判断加锁对象是否为当前client , 是 , 则解锁 。
fencing token可以理解成采用全局递增的序列替代随机字符串,即 有序token ,作为锁token来使用 流程:假设有5个Redis节点A,B,C,D,E 。这个问题用Redis实现分布式锁暂时无解 。而生产环境这种情况是存在的 。
【redis 分布式锁命令 redis分布式锁的命令】Redis分布式锁可以有多种方式实现但是其核心就是通过以下三个Redis命令组合实现 。SETNX SETNX key val 当且仅当key不存在时,set一个key为val的字符串,返回1;若key存在,则什么都不做,返回0 。
推荐阅读
- redis查询全部key redis查询为什么快
- docker tomcat启动后,远程不能访问 docker中tomcat连接redis
- redis 大数据 redis存储大数据集合
- redisson依赖 redis依赖网速