问题: 内存不足进行内存回收,使用allkeys-lru或者allkeys-random回收策略导致锁失效 ;线程获取分布式锁成功,但处理业务时间过长,此时锁到期被定时清理,导致其它线程获取锁成功并重复执行业务。
解决,对数据库重要资源利用乐观锁保护
udpate goods set stock = stock - #{acquire}
where sku_id = #{skuId} and stock - #{acquire} >= 0
附:redis的内存淘汰机制
1.1 过期清理机制
(1) 定期删除
Redis 定时检查哪些 key 已经过期,发现过期则删除
(2) 惰性删除
如果 key 非常多,定期删除会非常消耗资源,所以引入惰性删除策略
如果 Redis 访问 key 时发现已经过期则直接删除
1.2 内存回收机制
当内存不足时 Redis 会选择一些元素进行删除:
no-enviction
禁止驱逐数据,新写入操作会报错
volatile-lru
从已设置过期时间的数据集选择最近最少使用的数据淘汰
volatile-ttl
从已设置过期时间的数据集选择将要过期的数据淘汰
volatile-random
从已设置过期时间的数据集选择任意的数据淘汰
allkeys-lru
从数据集选择最近最少使用的数据淘汰
allkeys-random
从数据集选择任意的数据淘汰