Redis-秒杀

唉 就记得当时抢冰墩墩的时候的秒杀了

我们要注意什么问题呢?

1.几百万人在这个瞬间抢冰墩墩 这个瞬间会有大量的请求 服务器要能抗的住

2.不能超卖,就那些冰墩墩 卖多了压根没有 好不容易抢到你说没货了怕不是要被冲烂

3.避免少卖 拢共就那些 你再少卖点 没屁了

4.防黄牛 还是那个道理 拢共就五百个 黄牛每人嗯造十个 没了

高并发问题

基本解决高并发的方法都是 削峰、限流、异步、补偿

异步这一步可以通过消息队列来实现,将抢和购解耦,还可以很方便地限频,不至于让MySQL过度承压。抢的话使用Redis来做处理,因为Redis处理 简单的扣减请求是非常快的,而直接到MySQL是比较力不从心。

Redis可是单机支撑每秒几万的写入,并且可以做成集群,提高扩展能力的。我们可以先将库存名额预加载到Redis,然后在Redis中进行扣减,扣减成功的再通过消息队列,传递到MySQL做真

正的订单生成。

超卖问题

第一步,判断库存名额是否充足;

第二步,减少库存名额,扣减成功就是抢到。

用LUA把这两个捆绑成一个原子操作就好

1.正常业务错误,比如库存用完,这种情况符合预期,直接返回给用户即可。

2.访问Redis错误,这种情况返回给用户,让其重试即可

3.访问Redis超时,这种情况下,其实可能库存已经扣减成功,此时不用再重试,免费产生更多的无效扣减,虽然多了一次扣减,但是总数是不变的,只会少卖不会多卖。

少卖问题

少卖什么情况会出现呢?库存减少了,但用户订单没生成。

什么情况会这样呢?有几种可能:

1..上面提到的,减少库存操作超时,但实际是成功的,因为超时并不会进入生成订单流程;

2.在Redis操作成功,但是向Kafka发送消息失败,这种情况也会白白消耗Redis中的库存。

说白了,我们只需要保证Redis库存+ Kafka消耗的最终一致性。

●第一种,也最简单的方式,在投递Kafka失败的情况下,增加渐进式重试;

(成功的可能性越来越小 他就越来越懒)

●第二种,更安全一点,就是在第一种的基础上,将这条消息记录在磁盘上,慢慢重试;

●第三种,写磁盘之前就可能失败,可以考虑走WAL路线,但是这样做下去说不定就做成MySQL的undo log,

redo log这种WAL技术了,会相当复杂,没有必要。

一般都用第二种

怎么解决黄牛呢

首先我们可以每个id限购一个

第一步查询库存,第二步扣减库存,需要优化为第一步查询库存, 第二步查询用户己购买个数,第三步扣减库存,第四步记录用户购买数。(用LUA保证原子性)

这里需要注意的是,如果使用Redis集群,那么Redis的数据分片,需要根据用户来分Key,不然用户数据会查询不到。

有了限购,我们可以保证货品不会被黄牛占据太多

那么还剩一个问题,黄牛大多是通过代码来抢购,点击速度比人点击快得多,这样就导致了竞争不公平。(我当时就是用了一个秒杀脚本 说实话 收获甚微)

怎么解决呢?某个用户请求接口次数过于频繁,一般说明是用脚本在跑, 可以只针对该用户做限制。

针对IP做限制也是常见做的做法,但这样容易误杀,主要考虑到使用同一个网络的用户,可能都是一个出口IP。 限制IP,会导致正常用户也受到影响。

更好用的方案是加上一个验证码验证。 验证码符合91原则(啊.....),90%的时间,都用在验证码输入上,所以使用脚本点击的影响会降到很低。

相关推荐
哈__20 分钟前
KES-Operator重塑Kubernetes环境下的KES数据库集群管理
数据库·kubernetes·operator·kes
hweiyu001 小时前
Redis命令:MSETNX
redis·缓存
IvorySQL2 小时前
IvorySQL 5.6 发布:PG 18.6 内核升级,沙盒即开即用
数据库·人工智能·postgresql
CNSSIRD数据库3 小时前
中国企业环境信用数据库2003-2026
大数据·数据库·数据分析·论文笔记
wdfk_prog3 小时前
ROS教程08:从 TransportTCP::connect() 追到 TCPROS Connection Header、序列化与 Socket 数据传输
运维·缓存·docker·容器·ros
fd32003 小时前
达梦数据库更新统计信息后仍走旧执行计划解决方案
数据库
华章酱4 小时前
MySQL幻读是怎么出现的
数据库·mysql·幻读
浅念-4 小时前
Redis基础详解:单线程模型、String与Hash数据结构
服务器·数据库·redis·sql·mysql·nosql数据库·nosql
updayday8544 小时前
离职域账号状态变更与Ping64操作记录核对
大数据·网络·数据库·安全·智能路由器
Nturmoils5 小时前
只恢复一张表,别把整个库都还回去
数据库