手把手带你搭建秒杀系统
佘志东
前京东交易平台(上海)负责人、资深架构师
12374 人已学习
新⼈⾸单¥59
登录后,你可以任选2讲全文学习
课程目录
已完结/共 18 讲
前期准备:技术选型与环境准备 (2讲)
准确无误:打造不超卖和公平的秒杀系统 (2讲)
雷令风行:性能调优更上一层楼 (3讲)
手把手带你搭建秒杀系统
15
15
1.0x
00:00/00:00
登录|注册

06|谋定后动:秒杀的流量管控

你好,我是志东,欢迎和我一起从零打造秒杀系统。
上节课我们详细探讨了秒杀的隔离策略,简单回顾一下,为了让秒杀商品不影响其他商品的正常销售,我们从多个角度详细介绍了隔离,特别是系统隔离层面,我们从流量的起始链路入手,介绍了各个链路不同的隔离方法。从这节课开始,我们将重点介绍流量的管控。

如何有效地管控流量?

通过对秒杀流量的隔离,我们已经能够把巨大瞬时流量的影响范围控制在隔离的秒杀环境里了。接下来,我们开始考虑隔离环境的高可用问题,通俗点说,普通商品交易流程保住了,现在就要看怎么把秒杀系统搞稳定,来应对流量冲击,让秒杀系统也不出问题。方法很多,有流量控制、削峰、限流、缓存热点处理、扩容、熔断等一系列措施。
这些措施都是我们在第二模块要重点讲解的技术手段,内容比较多,而且会有一些交叉,我会用三节课来分享。
这节课我们先来看流量控制。在库存有限的情况下,过多的用户参与实际上对电商平台的价值是边际递减的。举个例子,1 万的茅台库存,100 万用户进来秒杀和 1000 万用户进来秒杀,对电商平台而言,所带来的经济效益、社会影响不会有 10 倍的差距。相反,用户越多,一方面消耗机器资源越多;另一方面,越多的人抢不到商品,平台的客诉和舆情压力也就越大。当然如果为了满足用户,让所有用户都能参与,秒杀系统也可以通过堆机器扩容来实现,但是成本太高,ROI 不划算,所以我们需要提前对流量进行管控。
确认放弃笔记?
放弃后所记笔记将不保留。
新功能上线,你的历史笔记已初始化为私密笔记,是否一键批量公开?
批量公开的笔记不会为你同步至部落
公开
同步至部落
取消
完成
0/2000
荧光笔
直线
曲线
笔记
复制
AI
  • 深入了解
  • 翻译
    • 英语
    • 中文简体
    • 中文繁体
    • 法语
    • 德语
    • 日语
    • 韩语
    • 俄语
    • 西班牙语
    • 阿拉伯语
  • 解释
  • 总结

本文介绍了如何在电商平台中设计和实现秒杀系统的流量管控。作者首先介绍了通过隔离策略将秒杀商品的影响范围控制在隔离的秒杀环境中,然后重点介绍了流量的管控方法。流量控制的重要性在于库存有限的情况下,过多的用户参与对电商平台的价值是边际递减的。文章详细介绍了预约系统的设计,包括预约管理后台、预约worker系统和预约核心微服务系统的功能和接口设计,以及数据库和缓存的设计。作者强调了对于高并发系统,需要设计缓存来抵挡大流量,并提出了针对热点问题的解决方案。另外,文章还介绍了预约熔断的流程图和预约系统的优化方法。通过预约自动熔断,可以结合秒杀商品的库存和业务计划引流的PV多少,提前规划好预约阶段开放的抢购资格数量,进行流量规划,准确管控秒杀期的流量。总的来说,本文通过实际案例和技术细节,为读者提供了关于秒杀系统流量管控的全面指导。

仅可试看部分内容,如需阅读全部内容,请付费购买文章所属专栏
《手把手带你搭建秒杀系统》
新⼈⾸单¥59
立即购买
登录 后留言

全部留言(8)

  • 最新
  • 精选
  • 清风
    可以放在redis里,list分页取数据还是很快的,我们现在一个list就存了几百万的数据,速度还是可以的,如果想更快的话可以多用几个key,发送的时候可以用多线程

    作者回复: 赞,这个思路很对,通过拆分成多个redis key,规避mysql的深度分页问题,可以很快速的把消息发出去。改造之后,几千万的消息发送,只要几分钟就完成了。

    2021-10-23
    4
    27
  • 肥low
    按id主键循环limit 100,顺序查出来再发送,还有就是当预约成功后,把预约提醒任务放到MQ里?

    作者回复: 如果数据一定要放在mysql,就需要对深度分页进行优化,比如通过主键来优化或者延迟关联等。另外的思路就是预约信息存放在redis里或者MQ

    2021-10-09
    3
  • James_Shangguan
    单sku 预约几百万用户,可以推测这张表的数据量肯定会很大,可以考虑分库分表优化; 单就本条SQL和发送推送的场景而言,可以考虑利用索引进行优化: SELECT user_name FROM t_reserve_user WHERE sku_id = #{skuId} and id>(#{page.index}-1)*#{page.step} limit #{page.step} #{page.index}表示当前页码 如果这条SQL语句达不到要求还可以考虑添加一些索引。
    2021-10-08
    4
  • kavi
    根据主键id 查询 select user_name from t_reserve_user where id >? and id<? 按规定的offset 查询 如: offset =10000 1.select user_name from t_reserve_user where id >0 and id<=10000; 2.select user_name from t_reserve_user where id >100000 and id<20000;
    2021-11-05
    2
  • Dylan
    where sku_id > max_id。可以让sku_id是自增主键,每次查询下一页都带入上一页最大id。 另外是不是可以让ES去干这事情
    2021-10-07
    1
    2
  • 邓嘉文
    1. 什么是深度分页问题? (1) MySQL 走 B+ 索引的复杂度为 O(log n), 所以 `where sku_id=#{skuId}` 的性能没问题的 (2) `limit #{page.beginIndex},#{page.step}` 会导致 MySQL 从第一条数据开始扫描, 扫描到 `beginIndex` 之后, 再取 `step` 条数据, 这个过程的复杂度为 O(n) MYSQL 是基于硬盘的, 每页大小默认是 16KB, 也就是说每次读取的数据是 16KB, 如果顺序扫描 1000W 数据, 会产生大量的 IO, 就会非常慢 (你可以试试一些网站指定巨大偏移量的分页, 可能会卡死) 1. 解决方法 (1) 分库分表: MYSQL 单表推荐不要超过 500W 数据, 数据过大就应该分库分表 (2) 使用索引确定范围: job程序分页不是随机分页的, 一般是一页一页扫描, 可以使用上一次查询的索引最大值来规避数据的扫描, 例如: ```sql select user_name from t_reserve_user where sku_id=#{skuId} and id>#{lastId} limit #{page.step} ``` (3) 使用缓存: 例如 redis list 来分页 MYSQL 深度分页的性能慢主要有 2 个原因: * 1 是 O(n) 时间复杂度 * 2 是 多次磁盘 IO 使用内存, 比如 redis 可以规避多次磁盘 IO
    2023-08-18归属地:江苏
  • 白白
    如果非要用mysql的话 建立sku_id + user_name的联合索引 每次查询都记录下最后一个user_name select user_name from t_reserve_user where sku_id=#{skuId} and user_name > ${userName} limit #{page.beginIndex},#{page.step} order by sku_id, user_name
    2022-05-01
  • 李威
    请教老师,文中的“对于历史数据,也需要有个定时任务进行结转归档,以减轻数据库的压力”,这个“结转归档”具体是怎么做的?是说把历史的预约数据转存到其他地方进行冷备,然后把历史数据从预约表中删除掉是吗?
    2021-10-21
    1
收起评论
显示
设置
留言
8
收藏
沉浸
阅读
分享
手机端
快捷键
回顶部