Redis分布式锁的简单实现——set命令及参数

摘自:http://doc.redisfans.com/string/set.html 

 

set命令

SET key value [EX seconds] [PX milliseconds] [NX|XX]

如果 key 已经持有其他值, SET 就覆写旧值,无视类型。

对于某个原本带有生存时间(TTL)的键来说, 当 SET 命令成功在这个键上执行时, 这个键原有的 TTL 将被清除。

 

可选参数

  • EX second :设置键的过期时间为 second 秒。 SET key value EX second 效果等同于 SETEX key second value 。
  • PX millisecond :设置键的过期时间为 millisecond 毫秒。 SET key value PX millisecond 效果等同于 PSETEX key millisecond value 。
  • NX :只在键不存在时,才对键进行设置操作。 SET key value NX 效果等同于 SETNX key value 。
  • XX :只在键已经存在时,才对键进行设置操作。

例:

# 对不存在的键进行设置

redis 127.0.0.1:6379> SET key "value"
OK

redis 127.0.0.1:6379> GET key
"value"


# 对已存在的键进行设置

redis 127.0.0.1:6379> SET key "new-value"
OK

redis 127.0.0.1:6379> GET key
"new-value"


# 使用 EX 选项

redis 127.0.0.1:6379> SET key-with-expire-time "hello" EX 10086
OK

redis 127.0.0.1:6379> GET key-with-expire-time
"hello"

redis 127.0.0.1:6379> TTL key-with-expire-time
(integer) 10069


# 使用 PX 选项

redis 127.0.0.1:6379> SET key-with-pexpire-time "moto" PX 123321
OK

redis 127.0.0.1:6379> GET key-with-pexpire-time
"moto"

redis 127.0.0.1:6379> PTTL key-with-pexpire-time
(integer) 111939


# 使用 NX 选项

redis 127.0.0.1:6379> SET not-exists-key "value" NX
OK      # 键不存在,设置成功

redis 127.0.0.1:6379> GET not-exists-key
"value"

redis 127.0.0.1:6379> SET not-exists-key "new-value" NX
(nil)   # 键已经存在,设置失败

redis 127.0.0.1:6379> GEt not-exists-key
"value" # 维持原值不变


# 使用 XX 选项

redis 127.0.0.1:6379> EXISTS exists-key
(integer) 0

redis 127.0.0.1:6379> SET exists-key "value" XX
(nil)   # 因为键不存在,设置失败

redis 127.0.0.1:6379> SET exists-key "value"
OK      # 先给键设置一个值

redis 127.0.0.1:6379> SET exists-key "new-value" XX
OK      # 设置新值成功

redis 127.0.0.1:6379> GET exists-key
"new-value"


# NX 或 XX 可以和 EX 或者 PX 组合使用

redis 127.0.0.1:6379> SET key-with-expire-and-NX "hello" EX 10086 NX
OK

redis 127.0.0.1:6379> GET key-with-expire-and-NX
"hello"

redis 127.0.0.1:6379> TTL key-with-expire-and-NX
(integer) 10063

redis 127.0.0.1:6379> SET key-with-pexpire-and-XX "old value"
OK

redis 127.0.0.1:6379> SET key-with-pexpire-and-XX "new value" PX 123321
OK

redis 127.0.0.1:6379> GET key-with-pexpire-and-XX
"new value"

redis 127.0.0.1:6379> PTTL key-with-pexpire-and-XX
(integer) 112999


# EX 和 PX 可以同时出现,但后面给出的选项会覆盖前面给出的选项

redis 127.0.0.1:6379> SET key "value" EX 1000 PX 5000000
OK

redis 127.0.0.1:6379> TTL key
(integer) 4993  # 这是 PX 参数设置的值

redis 127.0.0.1:6379> SET another-key "value" PX 5000000 EX 1000
OK

redis 127.0.0.1:6379> TTL another-key
(integer) 997   # 这是 EX 参数设置的值

 

一种在 Redis 中实现锁的简单方法

命令 SET resource-name anystring NX EX max-lock-time 是一种在 Redis 中实现锁的简单方法。

执行set命令,如果服务器返回 OK ,那么这个客户端获得锁。 如果服务器返回 NIL ,那么客户端获取锁失败,可以在稍后再重试。

设置的过期时间到达之后,锁将自动释放。

为了识别锁的持有者,可以设置一个不可猜测(non-guessable)的长随机字符串或直接使用uuid,作为口令(token)。

释放时,使用Lua 脚本,这个脚本只在客户端传入的值和键的口令串相匹配时,才对键进行删除。保持原子性。

脚本示例:

if redis.call("get",KEYS[1]) == ARGV[1]
then
    return redis.call("del",KEYS[1])
else
    return 0
end

这个脚本可以通过 EVAL ...script... 1 resource-name token-value 命令来调用。

分布式锁需要的feature

互斥性:分布式锁需要保证在不同节点的不同线程的互斥。这是最根本的。
可重入性:同一个节点上的同一个线程如果获取了锁之后也可以再次获取这个锁。
锁超时:和本地锁一样支持锁超时,防止死锁。
高可用:加锁和解锁需要高效,同时也需要保证高可用防止分布式锁失效,可以增加降级。

框架Redisson实现的分布式锁

他还有下面的两条feature:

支持阻塞和非阻塞:和 ReentrantLock 一样支持 lock 和 trylock 以及 tryLock(long timeOut)。
支持公平锁和非公平锁(可选):公平锁的意思是按照请求加锁的顺序获得锁,非公平锁就相反是无序的。这个一般来说实现的比较少。

更多见:https://blog.csdn.net/jaryle/article/details/94381552

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Redis现有分布式事务的实现是通过Redis Cluster来实现的。Redis Cluster是Redis 3.0开始推出的分布式解决方案,可以很好地解决不同Redis节点存放不同数据,并将用户请求方便地路由到不同Redis的问题。在Redis Cluster中,使用了数据分区算法将数据分布在不同的节点上,每个节点负责管理自己分区的数据。这样可以提高系统的扩展性和可用性。 对于分布式事务的实现Redis Cluster目前并没有直接支持事务的功能,但可以通过一些技巧和策略来实现类似的效果。例如,可以使用乐观锁机制来保证数据的一致性,通过在应用层进行事务的控制和处理。另外,也可以利用Redis的WATCH指令和MULTI/EXEC指令来实现基于命令的事务,尽管这种方式并不是严格的分布式事务。 此外,还可以利用Redis实现分布式锁来辅助实现分布式事务。Redis提供了一些原子操作,如SETNX、GETSET等,可以用来实现分布式锁。通过在分布式系统中加锁和解锁的操作,可以保证在同一时间只有一个客户端能够对某个资源进行操作,从而保证数据的一致性。 总结起来,Redis目前的分布式事务实现主要依赖于Redis Cluster的分布式解决方案,并结合乐观锁机制、基于命令的事务和分布式锁等技术来实现。这些方法可以满足大部分的分布式事务需求,但需要开发人员在应用层面进行适当的处理和控制。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *3* [超详细Redis入门教程——Redis分布式系统](https://blog.csdn.net/qq_42146402/article/details/131483214)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] - *2* [利用Redis实现分布式锁](https://blog.csdn.net/shasharoman/article/details/85056055)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值