Redis并发竞争key的解决方案详解
1.Redis高并发的问题
Redis缓存的高性能有目共睹,应用的场景也是非常广泛,但是在高并发的场景下,也会出现问题:缓存击穿、缓存雪崩、缓存和数据一致性,以及今天要谈到的缓存并发竞争。
这里的并发指的是多个redis的client同时set key引起的并发问题。
2.出现并发设置Key的原因
Redis是一种单线程机制的nosql数据库,基于key-value,数据可持久化落盘。由于单线程所以Redis本身并没有锁的概念,多个客户端连接并不存在竞争关系,但是利用jedis等客户端对Redis进行并发访问时会出现问题。
比如:同时有多个子系统去set一个key。这个时候要注意什么呢?
3.举一个例子
多客户端同时并发写一个key,一个key的值是1,本来按顺序修改为2,3,4,最后是4,但是顺序变成了4,3,2,最后变成了2。
如何解决redis的并发竞争key问题呢?下面给到2个Redis并发竞争的解决方案。
第一种方案:分布式锁+时间戳
1.整体技术方案
这种情况,主要是准备一个分布式锁,大家去抢锁,抢到锁就做set操作。
加锁的目的实际上就是把并行读写改成串行读写的方式,从而来避免资源竞争。
2.Redis分布式锁的实现
主要用到的redis函数是setnx()
用SETNX实现分布式锁
利用SETNX非常简单地实现分布式锁。例如:某客户端要获得一个名字youzhi的锁,客户端使用下面的命令进行获取:
SETNX lock.youzhi<current Unix time + lock timeout + 1>
如返回1,则该客户端获得锁,把lock.youzhi的键值设置为时间值表示该键已被锁定,该客户端最后可以通过DEL lock.foo来释放该锁。
如返回0,表明该锁已被其他客户端取得,这时我们可以先返回或进行重试等对方完成或等待锁超时。
3.时间戳
由于上面举的例子,要求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操作了。
4.什么是分布式锁
因为传统的加锁的做法(如java的synchronized和Lock)这里没用,只适合单点。因为这是分布式环境,需要的是分布式锁。
当然,分布式锁可以基于很多种方式实现,比如zookeeper、redis等,不管哪种方式实现,基本原理是不变的:用一个状态值表示锁,对锁的占用和释放通过状态值来标识。
第二种方案:利用消息队列
在并发量过大的情况下,可以通过消息中间件进行处理,把并行读写进行串行化。
把Redis.set操作放在队列中使其串行化,必须的一个一个执行。
这种方式在一些高并发的场景中算是一种通用的解决方案。
文章来源:https://www.cnblogs.com/fengff/p/10917420.html
https://whetherlove.github.io/2018/10/09/Redis%E9%9B%86%E7%BE%A4-%E9%9B%86%E7%BE%A4%E4%B8%80%E8%87%B4%E6%80%A7%E9%97%AE%E9%A2%98/
Redis并发竞争key的解决方案详解相关推荐
- Redis系列教程(七):Redis并发竞争key的解决方案详解
Redis高并发的问题 Redis缓存的高性能有目共睹,应用的场景也是非常广泛,但是在高并发的场景下,也会出现问题: 高并发架构系列:Redis缓存和MySQL数据一致性方案详解 如何解决Redis缓 ...
- Redis系列教程(六):Redis缓存和MySQL数据一致性方案详解
需求起因 在高并发的业务场景下,数据库大多数情况都是用户并发访问最薄弱的环节.所以,就需要使用redis做一个缓冲操作,让请求先访问到redis,而不是直接访问MySQL等数据库. 这个业务场景,主要 ...
- mysql 点赞数据库设计_基于redis实现的点赞功能设计思路详解
点赞其实是一个很有意思的功能.基本的设计思路有大致两种, 一种自然是用mysql等 数据库直接落地存储, 另外一种就是利用点赞的业务特征来扔到redis(或memcache)中, 然后离线刷回mysq ...
- 高并发架构系列:Redis缓存和MySQL数据一致性方案详解
需求起因 在高并发的业务场景下,数据库大多数情况都是用户并发访问最薄弱的环节.所以,就需要使用redis做一个缓冲操作,让请求先访问到redis,而不是直接访问MySQL等数据库. 这个业务场景,主要 ...
- 高并发高流量网站架构详解
(推荐)高并发高流量网站架构详解 Web2.0的兴起,掀起了互联网新一轮的网络创业大潮.以用户为导 向的新网站建设概念,细分了网站功能和用户群,不仅成功的造就了一大批新生的网站,也极大的方便了上网的人 ...
- Redis五种基本数据类型底层详解(原理篇)
Redis五种基本数据类型底层详解 详细介绍Redis用到的数据结构 简单动态字符串 SDS和C字符串的区别 总结 链表 字典 哈希表 字典 哈希算法 解决键冲突 rehash(重点) 渐进式reha ...
- 【转】C++11 并发指南五(std::condition_variable 详解)
http://www.cnblogs.com/haippy/p/3252041.html 前面三讲<C++11 并发指南二(std::thread 详解)>,<C++11 并发指南三 ...
- C++11 并发指南六( atomic 类型详解二 std::atomic )
C++11 并发指南六(atomic 类型详解一 atomic_flag 介绍) 一文介绍了 C++11 中最简单的原子类型 std::atomic_flag,但是 std::atomic_flag ...
- C++11 并发指南五(std::condition_variable 详解)
前面三讲<C++11 并发指南二(std::thread 详解)>,<C++11 并发指南三(std::mutex 详解)>分别介绍了 std::thread,std::mut ...
最新文章
- 2021清华大学年度人物候选 | 曹丰泽:我要证明,理想主义的路是走得通的
- 单片机复位后为什么要对sp重新赋值_常见的单片机复位方式及其原理分析
- SQLServer优化二
- 【Elasticsearch】如何在生产中执行Elasticsearch的零停机升级
- Map集合的遍历方法
- 云服务器ecs_阿里云ECS云服务器抢占式实例计费模式优缺点
- java软件的安装过程
- S7-1500系统内使用ET200S 1SI模块实现Modbus 从站通信
- 我用 Python 自制成语接龙小游戏,刺激!
- PCB设计中地的分类及含义
- 社区折腾日志:基于python搭建个人微信/支付宝免签支付功能
- 每天不知道吃什么,于是我做了个随机选择的小程序
- PHP 如何安装ionCube扩展
- LeetCode-876. 链表的中间结点
- python识别图片验证码,踩坑亲测
- 10 探索其他Excel对象
- CentOs中安装并运行rocketmq(报错 ignoring input and appending output to ‘nohup.out’;jps: command not found)
- 用js模仿word格式刷功能
- Mac OS X 背后的故事(九)半导体的丰收(下)
- BERT Enhanced Neural Machine Translation and Sequence Tagging Model
热门文章
- 由键盘输入正数n,要求输出如下2*n+1行的菱形图案。用c语言实现。
- 【崩坏星穹铁道】仙舟引航罗盘解密c++
- 资料,丰富资料,丰富资料(模式识别......)
- php 给视频添加水印,记php调用ffmpeg给视频加文字水印
- CometOJ国庆欢乐赛 C两排房子 二分 D1 二分贪心 E贪心特判
- 这种国家的外贸不做也罢
- 安卓10侧边返回_安卓10.0内测版出现新版手势操作:取消返回键、全靠Home胶囊完成...
- 干货 | 万字详解整个数据仓库设计体系
- 移动的宽带特别不好用,非常卡,怎么回事?
- 算法与数据结构入门一篇就搞定