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%的时间,都用在验证码输入上,所以使用脚本点击的影响会降到很低。

相关推荐
好吃的肘子16 分钟前
MongoDB 应用实战
大数据·开发语言·数据库·算法·mongodb·全文检索
weixin_4723394624 分钟前
MySQL MCP 使用案例
数据库·mysql
lqlj22331 小时前
Spark SQL 读取 CSV 文件,并将数据写入 MySQL 数据库
数据库·sql·spark
遗憾皆是温柔2 小时前
MyBatis—动态 SQL
java·数据库·ide·sql·mybatis
未来之窗软件服务2 小时前
Cacti 未经身份验证SQL注入漏洞
android·数据库·sql·服务器安全
fengye2071613 小时前
在MYSQL中导入cookbook.sql文件
数据库·mysql·adb
hudawei9963 小时前
flutter缓存网络视频到本地,可离线观看
flutter·缓存·音视频
小哈里3 小时前
【pypi镜像源】使用devpi实现python镜像源代理(缓存加速,私有仓库,版本控制)
开发语言·python·缓存·镜像源·pypi
CircleMouse3 小时前
基于 RedisTemplate 的分页缓存设计
java·开发语言·后端·spring·缓存
Ailovelearning3 小时前
neo4j框架:ubuntu系统中neo4j安装与使用教程
数据库·neo4j