什么,秒杀系统也有这么多种! - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
TIGERB
V2EX    推广

什么,秒杀系统也有这么多种!

  •  1
     
  •   TIGERB 2020 年 5 月 7 日 3471 次点击
    这是一个创建于 2075 天前的主题,其中的信息可能已经有所发展或是发生改变。

    喜大普奔SkrShop 更新了~

    喜大普奔SkrShop 更新了~

    喜大普奔SkrSop 更新了~

    前言

    本文结构很简单:

    5 张图送你 5 种秒杀系统,再加点骚操作,再顺带些点心里话♀。

    一个简单的秒杀系统

    实现原理: 通过 redis 原子操作减库存

    图一

    • 优点:简单好用
    • 缺点:考验 redis 服务能力
    • 是否公平:公平,先到先得

    我们称这类秒杀系统为:

    简单秒杀系统

    如果刚开始 QPS 并不高,redis 完全抗的下来的情况,完全可以依赖这个「简单秒杀系统」。

    一个够用的秒杀系统

    实现原理: 服务内存限流算法 + redis 原子操作减库存

    图二

    • 优点:简单好用
    • 缺点:-
    • 是否公平:不是很公平,相对的先到先得

    我们称这类秒杀系统为:

    够用秒杀系统

    性能再好点的秒杀系统

    实现原理: 服务本地内存原子操作减库存

    服务本地内存的库存怎么来的?

    活动开始前分配好每台机器的库存,推送到机器上。

    图三

    • 优点:高性能,释放 redis 压力
    • 缺点:不支持动态伸缩容(活动进行期间),因为库存是活动开始前分配好的
    • 是否公平:不是很公平,不是绝对的先到先得

    我们称这类秒杀系统为:

    预备库存秒杀系统

    支持动态伸缩容的秒杀系统

    实现原理: 服务本地协程 Coroutine定时 redis 原子操作减部分库存到本地内存 + 服务本地内存原子操作减库存

    图四

    • 优点:高性能,释放 redis 压力,支持动态伸缩容(活动进行期间)
    • 缺点:不支持动态伸缩容(活动进行期间),因为库存是活动开始前分配好的
    • 是否公平:不是很公平,但是好了点,几乎先到先得

    我们称这类秒杀系统为:

    实时预备库存秒杀系统

    公平的秒杀系统

    实现原理: 服务本地 Goroutine定时同步是否售罄到本地内存 + 队列 + 排队成功轮训(或主动 Push)结果

    图五

    • 优点:高性能,真公平
    • 缺点:开发成本高(需主动通知或轮训排队结果)
    • 是否公平:很公平,绝对的先到先得

    我们称这类秒杀系统为:

    公平排队秒杀系统

    骚操作

    上面的秒杀系统还不够完美吗?

    答案:是的。

    还有什么优化的空间?

    答案:静态化获取秒杀活动信息的接口。

    静态化是什么意思?

    答案:比如获取秒杀活动信息是通过接口 https://seckill.skrshop.tech/v1/acticity/get 获取的。现在呢,我们需要通过https://static-api.skrshop.tech/seckill/v1/acticity/get 这个接口获取。

    以前是这样

    变成了这样

    结果:可以通过接口https://static-api.skrshop.tech/seckill/v1/acticity/get就获取到了秒杀活动信息,流量都分摊到了 cdn,秒杀服务自身没了这部分的负载。

    小声点说:“秒杀结果我也敢推 CDN。”

    备注: 之后我们会分享`如何用 Golang 设计一个好用的「接口静态化服务」`。 

    总结

    上面我们得到了如下几类秒杀系统

    • 简单秒杀系统
    • 够用秒杀系统
    • 预备库存秒杀系统
    • 实时预备库存秒杀系统
    • 公平排队秒杀系统

    我想说的是里面没有最好的方案,也没有最坏的方案,只有适合你的。

    先到先得来说,一定要看你们的产品对外宣传,切勿上来就追逐绝对的先到先得。其实你看所有的方案,相对而言都是“先到先得”,比如,活动开始一个小时了你再来抢,那相对于准时的用户自然抢不过,对吧。

    又如预备库存秒杀系统,虽然不支持动态伸缩容。但是如果你的环境满足如下任意条件,就完全够用了。

    • 秒杀场景结束时间之快,通常几秒就结束了,真实活动可能会发生如下情况:
      • 服务压力大还没挂:根本就来不及动态伸缩容
      • 服务压力大已经挂了:可以先暂停活动,服务起来&扩容结束,用剩余库存重新推送
    • 运维自身不具备动态伸缩容的能力

    所以:

    合适好用就行,切勿过度设计。


    [Skr Shop] 项目地址长按进入:https://github.com/skr-shop/manuals


    SkrShop 系列更多文章:

    第 1 条附言    2020 年 5 月 7 日
    第 2 条附言    2020 年 5 月 7 日
    看不见图的,原文这里哈~~~

    http://tigerb.cn/2020/05/05/skrshop/seckill/
    11 条回复    2020-05-07 15:57:01 +08:00
    aliasliyu4
        1
    aliasliyu4  
       2020 年 5 月 7 日
    不错
    DT37
        2
    DT37  
       2020 年 5 月 7 日
    已收藏
    teawithlife
        3
    teawithlife  
       2020 年 5 月 7 日   1
    我实在想不出,看这种文章,我能学到什么东西,茴的四种写法么?
    qiayue
        4
    qiayue  
    PRO
       2020 年 5 月 7 日
    掘金的图这里显示不了
    tulong
        5
    tulong  
       2020 年 5 月 7 日
    图挂了
    TIGERB
        6
    TIGERB  
    OP
       2020 年 5 月 7 日
    @teawithlife 各有所取,互相学习么~
    sujin190
        7
    sujin190  
       2020 年 5 月 7 日
    redis 原子操作扛不住,队列就能抗住这咋想的,虽然很多队列都能横向扩展到数百万写,但是写完了你就不需要处理了么,如果说队列只是削峰,那么异步 io 加 redis 就完了,想那么多有的没的干个啥
    TIGERB
        8
    TIGERB  
    OP
       2020 年 5 月 7 日
    @sujin190 嗯 我是从实际业务出发,比如你刚创业、或者新产品 搞个活动就几百几千的 qps 怎么简单怎么解决问题的来么
    sujin190
        9
    sujin190  
       2020 年 5 月 7 日
    @TIGERB #8 几百!!几千!!!你不是在逗?就这么点,要啥自行车
    xy2020
        10
    xy2020  
       2020 年 5 月 7 日 via Android
    秒杀活动,先到先得不公平?????
    TIGERB
        11
    TIGERB  
    OP
       2020 年 5 月 7 日
    @sujin190 所以 就可以直接原子操作了么
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     931 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 28ms UTC 18:58 PVG 02:58 LAX 10:58 JFK 13:58
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86