项目中使用 redis,再高并发下竟然遇到了这种问题,一年开发经验解决不了,来个大神看看。。

2021-06-06 00:31:41 +08:00
 Jekins

提交订单功能,判断当前用户有没有提交订单(订单创建成功会保存到 redis )。以下是伪代码,逻辑和提交订单是一样的,遇到的问题也是一样的,请求老牛解决!

ConcurrencyTester tester = ThreadUtil.concurrencyTest(1000, () -> { Set<String> keys = redisTemplate.keys("key");//查询 redis 有没有这个 key,有就返回 key if (keys.size() > 0) { return; } System.out.println("我来插入到 redis"); //此处被执行多次 redisTemplate.opsForValue().set("key", "value"); });

5391 次点击
所在节点    Java
23 条回复
Jooooooooo
2021-06-06 00:39:00 +08:00
搜一下 setnx

当然用 redis 做锁当发生故障时极小概率保障不了唯一性, 看你的需求了
swulling
2021-06-06 00:52:41 +08:00
一年开发经验,特别是做高并发,首先需要了解一个概念叫做并发冲突。

查询 Key 是否存在 + 设定 Key 的 Value,这两步在你的实现里不是原子的。解决办法就是使用原子操作替代两步操作。
ccde8259
2021-06-06 01:01:13 +08:00
为什么不用 SETNX
为什么不用 MULTI WATCH
为什么不用 LUA SCRIPT
Hurriance
2021-06-06 01:11:12 +08:00
不嫌麻烦的话可以用 lua + 2 楼的方法
jones2000
2021-06-06 03:12:44 +08:00
直接插入不覆盖的模式, 如果插入成功就说明是新订单, 插入失败就说明订单已存在。
Addup
2021-06-06 03:16:36 +08:00
用 lua 注意定时清理下脚本缓存, 这里有两个坑: 不然不断累积导致内存爆满, 建有 dts 的话从机也需要执行命令清脚本缓存, 脚本缓存过多时, 清除命令耗时过长可能导致 dts 连接异常.
fewok
2021-06-06 04:17:45 +08:00
咱们先说人话,你们交易业务,下单最高峰,秒杀最高峰的 TPS 是多少???
jorneyr
2021-06-06 08:27:00 +08:00
redisTemplate.keys("key");
Java 代码在这里并发了,多个线程执行到这里时 key 不存在,则进行了多条插入。

Redis 的单线程保证的是自己内部,Java 端的并发 Redis 处理不了。
limuyan44
2021-06-06 09:21:31 +08:00
对于并发而言,这种问题过于常识了,建议先找点相关的文章看看,这还是涉及钱的下单功能,这么搞迟早把自己坑死。
szzadkk
2021-06-06 10:00:17 +08:00
这个操作不是原子性的,肯定有问题,用 setnx 或者 lua 脚本
ttyn
2021-06-06 11:00:49 +08:00
猜测你本意是用 Redis 做并发锁,防止订单重复提交。
要理解你失败的原因,需要先了解 Redis 的原子操作,作为一年的开发经验,有点为难你。
Redis 有个现成的东西,叫 Redlock,参考: https://blog.csdn.net/hanchao5272/article/details/99695360
Jekins
2021-06-06 11:05:58 +08:00
@ccde8259 感谢分享经验
Jekins
2021-06-06 11:06:36 +08:00
@ttyn 谢谢老哥,我只干了一年都还不到,之前确实没有碰到过这种情况。。
Jekins
2021-06-06 11:07:02 +08:00
感谢楼上各位老哥!
Jekins
2021-06-06 11:14:14 +08:00
@fewok 当前这个项目新开发的,没有什么并发,但是遇到了这个并发下单问题,也是以后要面对的。。
pydiff
2021-06-07 10:52:38 +08:00
有点好奇,究竟是什么样的公司,敢让一个新手来做这种关键业务,如果 boom 了算谁的呢
shimianxiang
2021-06-07 13:44:21 +08:00
建议直接 lua,还好扩展
vgbhfive
2021-06-07 14:44:45 +08:00
lua 脚本或者 setnx 保证原子性
wunsch0106
2021-06-08 11:45:16 +08:00
@pydiff 敢叫他上就敢写呗,boom 了肯定领导负责啊
neptuno
2021-06-11 14:54:52 +08:00
原子操作,lua+redis 分布式锁,网上随便找个例子模仿写

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/781634

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX