V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
TIGERB
V2EX  ›  推广

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

  •  1
     
  •   TIGERB · 2020-05-07 12:57:44 +08:00 · 2638 次点击
    这是一个创建于 1421 天前的主题,其中的信息可能已经有所发展或是发生改变。

    喜大普奔😸😸😸SkrShop 更新了~

    喜大普奔😸😸😸SkrShop 更新了~

    喜大普奔😸😸😸SkrShop 更新了~

    前言

    本文结构很简单:

    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-05-07 14:12:22 +08:00
    第 2 条附言  ·  2020-05-07 14:14:01 +08:00
    看不见图的,原文这里哈~~~

    http://tigerb.cn/2020/05/05/skrshop/seckill/
    11 条回复    2020-05-07 15:57:01 +08:00
    aliasliyu4
        1
    aliasliyu4  
       2020-05-07 13:04:52 +08:00
    不错
    DT37
        2
    DT37  
       2020-05-07 13:31:49 +08:00
    已收藏
    teawithlife
        3
    teawithlife  
       2020-05-07 13:34:04 +08:00   ❤️ 1
    我实在想不出,看这种文章,我能学到什么东西,茴的四种写法么?
    qiayue
        4
    qiayue  
       2020-05-07 13:34:33 +08:00
    掘金的图这里显示不了
    tulong
        5
    tulong  
       2020-05-07 13:43:44 +08:00
    图挂了
    TIGERB
        6
    TIGERB  
    OP
       2020-05-07 14:07:28 +08:00
    @teawithlife 各有所取,互相学习么~
    sujin190
        7
    sujin190  
       2020-05-07 14:20:03 +08:00
    redis 原子操作扛不住,队列就能抗住这咋想的,虽然很多队列都能横向扩展到数百万写,但是写完了你就不需要处理了么,如果说队列只是削峰,那么异步 io 加 redis 就完了,想那么多有的没的干个啥
    TIGERB
        8
    TIGERB  
    OP
       2020-05-07 14:30:50 +08:00
    @sujin190 嗯 我是从实际业务出发,比如你刚创业、或者新产品 搞个活动就几百几千的 qps 怎么简单怎么解决问题的来么
    sujin190
        9
    sujin190  
       2020-05-07 14:53:25 +08:00
    @TIGERB #8 几百!!几千!!!你不是在逗?就这么点,要啥自行车
    xy2020
        10
    xy2020  
       2020-05-07 15:29:24 +08:00 via Android
    秒杀活动,先到先得不公平?????
    TIGERB
        11
    TIGERB  
    OP
       2020-05-07 15:57:01 +08:00
    @sujin190 所以 就可以直接原子操作了么
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   2030 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 30ms · UTC 16:15 · PVG 00:15 · LAX 09:15 · JFK 12:15
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.