Redis 的并发竞争 Key
Redis 高并发的问题
Redis 缓存的高性能有目共睹,应用的场景也是非常广泛,但是在高并发的场景下,也会出现问题:缓存击穿、缓存雪崩、缓存和数据一致性,以及今天要谈到的缓存并发竞争。
这里的并发指的是多个 redis 的 client 同时 set key 引起的并发问题。
出现并发设置 Key 的原因
Redis 是一种单线程机制的 nosql 数据库,基于 key-value,数据可持久化落盘。由于单线程所以 Redis 本身并没有锁的概念,多个客户端连接并不存在竞争关系,但是利用 jedis 等客户端对 Redis 进行并发访问时会出现问题。
比如:同时有多个子系统去 set 一个 key。这个时候要注意什么呢?
举一个例子
多客户端同时并发写一个 key,一个 key 的值是 1,本来按顺序修改为 2,3,4
,最后是 4
,但是顺序变成了 4,3,2
,最后变成了 2
。
如何解决 redis 的并发竞争 key 问题呢?下面给到 2 个 Redis 并发竞争的解决方案。
第一种方案:分布式锁+时间戳
整体技术方案
这种情况,主要是准备一个分布式锁,大家去抢锁,抢到锁就做 set 操作。
加锁的目的实际上就是把并行读写改成串行读写的方式,从而来避免资源竞争。
Redis 分布式锁的实现
主要用到的 redis 函数是 setnx()
用 SETNX 实现分布式锁
利用 SETNX 非常简单地实现分布式锁。例如:某客户端要获得一个名字 youzhi
的锁,客户端使用下面的命令进行获取:
SETNX lock.youzhi<current Unix time + lock timeout + 1>
如返回 1,则该客户端获得锁,把 lock.youzhi
的键值设置为时间值表示该键已被锁定,该客户端最后可以通过 DEL lock.foo
来释放该锁。
如返回 0,表明该锁已被其他客户端取得,这时我们可以先返回或进行重试等对方完成或等待锁超时。
时间戳
由于上面举的例子,要求 key 的操作需要顺序执行,所以需要保存一个时间戳判断 set 顺序。
- 系统 A
key 1 {ValueA 7:00}
- 系统 B
key 1 { ValueB 7:05}
假设系统 B 先抢到锁,将 key1 设置为 {ValueB 7:05}
。接下来系统 A 抢到锁,发现自己的 key1 的时间戳早于缓存中的时间戳(7:00<7:05),那就不做 set 操作了。
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论