Redis是一款高性能的NoSQL数据库,自增操作是Redis中一个常见的操作,它可以用来实现唯一ID生成、计数器等应用场景。
Redis的原子性操作
Redis原子性操作指的是Redis中对于某个键值对的读写操作是互斥的,并且Redis的所有操作都是原子性操作。因此,Redis可以非常方便地实现一些需要用到原子性操作的场景。
Redis自增操作
Redis自增操作可以使用Redis提供的INCR命令实现: INCR key其中key为需要自增的键,执行该命令后,Redis会自动将该键对应的值加1,并返回加1后的值。同理,自减操作为DECR。
Redis原子自增/自减技术的实现方式
- 分布式锁实现
- Redis可以通过SETNX命令实现分布式锁,可以利用这个特性来实现原子自增操作。当一个进程需要对一个键进行自增操作时,首先需要获取该键的分布式锁,然后执行INCR命令实现自增操作,最后释放该键的分布式锁。
- 由于Redis获取分布式锁和自增操作都是原子性的操作,因此这样实现能够保证原子性。
- lua脚本实现
- Redis支持使用Lua脚本实现原子操作,可以将多个命令封装在Lua脚本中,然后通过EVAL命令一次性执行。利用这个特性,可以实现原子自增操作。
sentx分布式锁的几个常见问题和解决方式
- setnx抢占锁成功,业务代码或者程序在运行过程中宕机了,没有执行锁删除逻辑,就会造成死锁。
- 解决方式:设置锁的自动过期,即使没有手动删除,会自动删除;
- 设置过期时间跟加锁不是一条语句 如果加锁成功但设置过期时间未成功,会出现问题。
- 解决方式:将加锁与设置过期时间原子完成。
- 删除锁直接删除,由于业务处理时间长,锁过期了,我们直接删除,有可能把别人正在持有的锁删除。
- 解决方式:占锁的时候,值指定为uuid,每个人匹配是自己的锁才删除;
- 如果在查询的时候key没有过期,但执行删除之前key过期了 我们删除的还是别人的锁。
- 解决方式:使用lua脚本 原子的查询与删除锁。
参考链接: