redis 的incr 高并发 原子性计数器
前言:6月底 公司录单的人比较多,由于先前的系统用的同步锁 ,我们是多服务实例,导致出现重复单号的问题,我想到的解决办法有两种 ,第一种是 Redis锁 第二种是自增key,下面实现的是用第二种方法 自增key 。
不选择Redis锁的原因:
- 它获取锁的方式简单粗暴,获取不到锁直接不断尝试获取锁,比较消耗性能。
- 另外来说的话,Redis 的设计定位决定了它的数据并不是强一致性的,在某些极端情况下,可能会出现问题。锁的模型不够健壮。
- 即便使用 Redlock 算法来实现,在某些复杂场景下,也无法保证其实现 100% 没有问题,关于 Redlock 的讨论可以看 How to do distributed locking。
- Redis 分布式锁,其实需要自己不断去尝试获取锁,比较消耗性能。
1.Redis自增key 的好处
- 原子性(atomicity):一个事务是一个不可分割的最小工作单位,事务中包括的诸操作要么都做,要么都不做。
- Redis所有单个命令的执行都是原子性的,这与它的单线程机制有关;
- Redis命令的原子性使得我们不用考虑并发问题,可以方便的利用原子性自增操作
- 简单解释就是你的服务即使是多机器多进程的,incr也能保证每次返回的结果不会出现相同的值.
2.逻辑梳理
- Redis 获取Key自增次数 每次+1
- 如果不存在key 默认值设置为30000
- 截取数据 返回
3.代码实现:
/*** 此方法只适用于************号和*****************号生成 * @param id 序列主键类型:BA/AJ等* @return*/@Transactional(isolation = Isolation.SERIALIZABLE, rollbackFor = Exception.class)public synchronized String createNumberBAandAJ(String id) {//Redis 获取Key自增次数 每次+1String key="case:GenerateEnum:"+id;Long increment = redisTemplate.opsForValue().increment(key, 1);//如果不存在key 默认值设置为30000 方便区分与数据库字段不相同if(1 == increment ){increment = redisTemplate.opsForValue().increment(key, 30000);}//redisTemplate.boundValueOps("success").get(0, -1)//截取数据String s = "000000" + increment;s = s.substring(s.length() - 6);log.info("截取后的数据================>"+s);return s;}
4.总结:
在一些对高并发请求有限制的系统或者功能里,比如说秒杀活动,或者一些网站返回的当前用户过多,请稍后尝试。这些都是通过对同一时刻请求数量进行了限制,一般用作对后台系统的保护,防止系统因为过大的流量冲击而崩溃。对于系统崩溃带来的后果,显然还是拒绝一部分请求更能被维护者所接受。
而在各种限流中,除了系统自身设计的带锁机制的计数器外,利用Redis实现显然是一种既高效安全又便捷方便的方式。
5.redis 的incr原理
- Redis Incr 命令将 key 中储存的数字值增一。
- 如果 key 不存在,那么 key 的值会先被初始化为 0 ,然后再执行 INCR 操作。
- 如果值包含错误的类型,或字符串类型的值不能表示为数字,那么返回一个错误。
- 本操作的值限制在 64 位(bit)有符号数字表示之内。
计数器是 Redis 的原子性自增操作可实现的最直观的模式了,它的想法相当简单:每当某个操作发生时,向 Redis 发送一个 INCR 命令。
比如在一个 web 应用程序中,如果想知道用户在一年中每天的点击量,那么只要将用户 ID 以及相关的日期信息作为键,并在每次用户点击页面时,执行一次自增操作即可。
比如用户名是 peter ,点击时间是 2012 年 3 月 22 日,那么执行命令 INCR peter::2012.3.22 。
可以用以下几种方式扩展这个简单的模式:
- 可以通过组合使用 INCR 和 EXPIRE ,来达到只在规定的生存时间内进行计数(counting)的目的。
- 客户端可以通过使用 GETSET 命令原子性地获取计数器的当前值并将计数器清零,更多信息请参考 GETSET 命令。
- 使用其他自增/自减操作,比如 DECR 和 INCRBY ,用户可以通过执行不同的操作增加或减少计数器的值,比如在游戏中的记分器就可能用到这些命令。
学习如逆水行舟不进则退,记录问题,增加经历。
redis 的incr 高并发 原子性计数器相关推荐
- mysql点击计数器_MySql计数器,如网站点击数,如何实现高性能高并发的计数器功能...
MySql计数器,如网站点击数,如何实现高性能高并发的计数器功能 Clicks: 5338 Date: 2014-03-29 23:30:42 Power By 李轩Lane TagMysql计数器高 ...
- 面试官:为什么单线程的Redis可以实现高并发访问
背景 上回说到小枫在接受面试官的拷打,所幸第一个问题回答的还不错,因此面试官对于小枫的初步印象还行.我们接着来看看小枫是怎么和面试官继续过招的吧,他还能扛得住面试官几个连环炮呢? 面试官考察目的分析 ...
- 利用Redis锁解决高并发问题
利用Redis锁解决高并发问题 参考文章: (1)利用Redis锁解决高并发问题 (2)https://www.cnblogs.com/yszr/p/11698696.html 备忘一下.
- SpringBoot+Redis+Cookies实现高并发的购物车
案例实战:SpringBoot+Redis+Cookies实现高并发的购物车 步骤1:代码逻辑 /*** 添加购物车*/@PostMapping(value = "/addCart" ...
- java redis队列_redis队列实现高并发怎么用?Java如何使用redis队列解决高并发?
小伙伴们大家好,不知道你们有没有在Java开发中遇到redis队列高并发,这个问题让你很头疼,今天小编就来讲解一下在Java中遇到redis队列高并发了,到底该怎么办. 高并发的业务场景: 我们做商品 ...
- Redis锁解决高并发问题
Redis锁解决高并发问题 redis真的是一个很好的技术,它可以很好的在一定程度上解决网站一瞬间的并发量,例如商品抢购秒杀等活动. redis之所以能解决高并发的原因是它可以直接访问内存,而以往我们 ...
- SpringBoot +Redis +RabbitMQ 实现高并发限时秒杀
SpringBoot +Redis +RabbitMQ 实现高并发限时秒杀 提示:以下是本篇文章正文内容,下面案例可供参考 一.软件安装 1.安装RabbitMQ docker安装:docker安装R ...
- Redis多容器高并发场景 , 设置缓存的时候,要考虑多容器加锁的场景。(incr计数和redis分布式锁区别)
1.设置缓存的时候,要考虑多容器加锁的场景. (1)场景,短信回执场景,会有二次回执的情况,但是我们只处理一次回执的消息体,如何不处理二次回执呢? // 队列中有数据且容量未达到100,可继续放入队列 ...
- 【高并发】Redis如何助力高并发秒杀系统?看完这篇我彻底懂了!!
秒杀业务 在电商领域,存在着典型的秒杀业务场景,那何谓秒杀场景呢.简单的来说就是一件商品的购买人数远远大于这件商品的库存,而且这件商品在很短的时间内就会被抢购一空.比如每年的618.双11大促,小米新 ...
最新文章
- Windows性能分析器概述(一)
- HTML5权威指南--Web Storage,本地数据库,本地缓存API,Web Sockets API,Geolocation API(简要学习笔记二)...
- Python正则表达式的7个使用典范
- java 一个大事务下的新增、修改、查询_重新学习Mysql数据库8:MySQL的事务隔离级别实战...
- context:component-scan/和mvc:annotation-driven/的区别
- MAD huashi
- c ++明明的随机数_从列表C ++程序中随机建议电影
- SilverLight之我见
- Spring Boot文档阅读笔记-构建SOAP的web Service Client
- Android学习_ContentProvider和Uri
- win10QQ语音无法使用麦克风
- 液晶面板价格继续下跌,32英寸平板电视或跌破500元
- win7安装python3.8失败_Python3 | Win7系统下无法安装问题解决
- Mysql常见面试题(陆续更新中)...
- 大数据-什么是大数据?大数据的相关概念
- PHP设计模式(2) -创建型模式
- 星球前线 | Libra最大的竞争对手是什么?Calibra高管给出答案
- 毕业设计 - 题目:垃圾邮件(短信)分类 算法实现 机器学习 深度学习 开题
- 大地测量学转D3D第一篇博客
- 小米手机如何设置默认浏览器,这2个方法值得收藏
热门文章
- Elasticsearch 学习(二).实战使用
- java 最短遍历路径_凯文培根游戏的最短路径图遍历
- filament 5 Use IBL
- LTE学习笔记四:OFDM
- python conda安装与使用教程
- TIM定时器_CNT_ARR_PSC_CRR
- sse服务器推送性能,SSE 服务端向客户端推送
- MySQL中where 1=1真的会影响性能么?
- android WebView加载视频只有声音没有画面
- java 返回ro,错误retrofit rxjava优雅的处理服务器返回异常、错误