秒杀场景实践:抢红包解决方案

发布时间:2024-12-29 19:50

参与抢购或秒杀,电子红包可能附带 #生活技巧# #节省生活成本# #购物优惠技巧# #电子红包#

秒杀场景实践之抢红包

最新推荐文章于 2024-07-02 17:54:03 发布

壹醉方休 于 2019-10-31 19:43:51 发布

秒杀场景实践之抢红包常用解决方案

文章地址: https://blog.piaoruiqing.com/blog/2019/09/01/秒杀场景实践之抢红包一/

前言

秒杀场景在生活中几乎随处可见, 不论是商品抢购、春运抢票还是一个随处可见的红包, 都会涉及到秒杀的场景. 在面试中, 秒杀业务的设计也成为热门题目为面试官和应聘者津津乐道.

接下来, 本文将针对秒杀场景中的抢红包实现方案进行分享, 包括红包业务常见的实现方案, 瓶颈及优化.

分析

场景

红包的应用场景有很多, 如随机红包、定额红包等, 甚至还有结合其他促销业务的红包变种如抢购物津贴等. 但从技术的角度来看, 不论玩法有多少变化, 其核心都是相似的:

稳定: 扛得住突发的大流量, 确保红包都能成功派发.

准确: 数据一定要正确, 不能出现超额派发的情况.

业务

抢红包可能会由于业务需求不同而产生很多变种, 设计上要足够抽象, 不能为了抢现金红包和抢购物津贴红包写多份相似的代码. 抢到红包的后置操作可以作为消息, 由不同的业务模块自行处理.

技术

抢红包核心业务不复杂, 其关键点在于应对高并发、资源争用等.

高并发: 异步、横向扩展负载均衡、限流等.

读多写少: 缓存.

资源争用: 原子操作, 缓存或数据库等层面可进行控制. 如使用Lua脚本进行减库存操作.

方案一 —— 预分配

适用场景

红包数量相对合理, 很少产生库存剩余的情况、用户量级不大的情况.

优势: 实现简单、配合缓存很容易应对高并发

不足: 频繁发放较多数量大的红包会导致一次性写入大量分配记录, 如果领取的人不多, 会产生很多无效数据.

简要描述

预分配是在发放红包时, 根据红包总额和数量、按照既定算法进行分配, 提前创建好全部的红包分配记录. 领取时只是将红包分配记录进行更新.

比较适合系统发放的红包(面向某一标签的全部用户群体, 发出的红包基本会被领取完), 不适合用户群组红包(无法控制领取红包人数, 当红包个数远大于群组人数的情况下, 无效数据比较多, 比如在一个10人群组发放一个数量为1000的红包).

实现细节

流程

在红包开抢前, 预先分配好红包领取记录, 领取记录的用户ID为负值.

开抢后, 开放唯一领取红包的入口

领取操作核心就是更新红包分配记录:

-- 此处划重点 ( ̄▽ ̄)UPDATE IGNORE record SET user_id = {userId}, gmt_receive = UNIX_TIMESTAMP() WHERE red_envelop_id = 1 AND user_id < 0 LIMIT 1;-- red_envelop_id + user_id 有唯一约束

红包发放记录

红包分配记录

unique: 红包ID+领取用户ID

ID红包ID金额领取用户ID领取时间...1110-10...2160-20...3130-30... 备注

UPDATE IGNORE ... LIMIT 1 : 解决了资源争用问题, 确保并发请求下红包的领取的数据正确性.

red_envelop_id + user_id : 创建索引并唯一约束, 确保对于同一个红包同一用户只能领取一次.

预分配的user_id为负值: 因为red_envelop_id + user_id 有唯一约束.

对于一般流量的小型活动, 这种方式实现简单、成本低, 不引入缓存的情况下只用一个MySQL基本也能扛得住.

[版权声明]
本文发布于朴瑞卿的博客, 允许非商业用途转载, 但转载必须保留原作者朴瑞卿 及链接:http://blog.piaoruiqing.com. 如有授权方面的协商或合作, 请联系邮箱: piaoruiqing@gmail.com.

方案二 —— 实时分配

适用场景

领取人数无法估计、频发退款, 如群组红包(经常发生剩余退款)

实现细节

流程

开抢前将红包信息加载到缓存, 首次加载时间可长一些

抢红包: 从缓存读取(没有则加载), 分配红包后原子更新缓存(若已发放完毕则直接返回失败)

缓存更新后写入数据库(校验数据正确性)

红包发放记录

ID总金额数量剩余金额剩余数量...110031003...

红包分配记录

unique: 红包ID+领取用户ID

ID红包ID金额领取用户ID领取时间...
............... 备注

首次缓存加载时间要稍长一点: 红包刚开始发放时可能会有较大的突发流量, 此时去DB加载缓存不合适.

缓存可以不用和数据库保证强一致: 数据的正确性由数据库进行维护, 如: 缓存扣除了红包额度, 但更新数据库时发生了异常, 此时缓存不需要回滚, 待缓存失效后重新加载即可.(所以缓存时间可以是几秒钟, 不用太长)

更新缓存可以考虑使用Lua脚本以保证原子性.

实时分配红包不会产生无效的记录, 适合大多数场景, 但实现比预分配复杂的多.

细节及优化

客户端点击频率控制能在一定程度上减少流量.

红包领光后在缓存一层拦截掉全部请求, 直接返回失败.

网关层进行限流.

结语

秒杀场景其特点是高并发、读多写少、资源争用, 每一个点都需要根据其业务场景选择适合的解决方案, 如使用缓存解决频繁读取的问题、使用队列解决数据库性能瓶颈等.

对于抢红包业务来说, 预分配和实时分配都是行之有效的方案, 各有优劣, 具体选择哪种, 还是要看业务需求.

分布式搜索引擎面试题(一)

分布式搜索引擎面试题(二)

12306抢票,极限并发带来的思考

如何不停服迁移数据

写一手好SQL很有必要

你不会还在用这8个错误的SQL写法吧?

转发是最好的在看❤️

网址:秒杀场景实践:抢红包解决方案 https://www.yuejiaxmz.com/news/view/602073

相关内容

职场压力管理实践解决方案.docx
全场景解决方案重新定义生活的全部
本地生活解决方案
海尔智家:构建全场景智慧解决方案
LED照明解决方案及应用场景
“大平台、小场景” 美的LIFE智慧医院解决方案进化发布
抢占高端市场 云米发布“全屋智能”解决方案“1=N44”
AI场景之争 Trax占据全场景零售AI解决方案高地
本地生活中小微商家,全场景智慧运营解决方案
29.9秒杀抢购中 家家用得到

随便看看