设计一个秒杀系统之削峰填谷

article/2025/9/15 21:29:48

为什么需要削峰?

如果你看过秒杀系统的流量监控图的话,你会发现它是一条直线,就在秒杀开始那一秒是一条很 直很直的线,这是因为秒杀请求在时间上高度集中于某一特定的时间点。这样一来,就会导致一 个特别高的流量峰值,它对资源的消耗是瞬时的。
但是对秒杀这个场景来说,最终能够抢到商品的人数是固定的,也就是说 100 人和 10000 人发 起请求的结果都是一样的,并发度越高,无效请求也越多,或者说,10000件商品10000个人抢购,但是不要让大家一起去抢,这样谁也受不了,让他们排队抢。

这就好比因为存在早高峰和晚高峰的问题,所以有了错峰限行的解决方案。削峰的存在,一是可 以让服务端处理变得更加平稳,二是可以节省服务器的资源成本。针对秒杀这一场景,削峰从本 质上来说就是更多地延缓用户请求的发出,以便减少和过滤掉一些无效请求,它遵从“请求数要 尽量少”的原则。

但是从业务上来说,秒杀活动是希望更多的人来参与的,也就是开始之前希望有更多的人来刷页 面,但是真正开始下单时,秒杀请求并不是越多越好。因此我们可以设计一些规则,让并发的请 求更多地延缓,而且我们甚至可以过滤掉一些无效请求。

流量削峰的思路

流量削峰的一些操作思路:排队、答题、分层过滤。这几种方式都是无损 (即不会损失用户的发出请求)的实现方案,当然还有些有损的实现方案,包括我们后面要介绍 的关于稳定性的一些办法,比如限流和机器负载保护等一些强制措施也能达到削峰保护的目的, 当然这都是不得已的一些措施,因此就不归类到这里了。

排队

要对流量进行削峰,最容易想到的解决方案就是用消息队列来缓冲瞬时流量,把同步的直接调用 转换成异步的间接推送,中间通过一个队列在一端承接瞬时的流量洪峰,在另一端平滑地将消息 推送出去。在这里,消息队列就像“水库”一样, 拦蓄上游的洪水,削减进入下游河道的洪峰流 量,从而达到减免洪水灾害的目的。

用消息队列来缓冲瞬时流量的方案,如下图所示:

但是,如果流量峰值持续一段时间达到了消息队列的处理上限,例如本机的消息积压达到了存储 空间的上限,消息队列同样也会被压垮,这样虽然保护了下游的系统,但是和直接把请求丢弃也 没多大的区别。就像遇到洪水爆发时,即使是有水库恐怕也无济于事。

  • 除了消息队列,类似的排队方式还有很多,例如:
  • 利用线程池加锁等待也是一种常用的排队方式;
  • 先进先出、先进后出等常用的内存排队算法的实现方式;

把请求序列化到文件中,然后再顺序地读文件(例如基于 MySQL binlog 的同步机制)来恢 复请求等方式

可以看到,这些方式都有一个共同特征,就是把“一步的操作”变成“两步的操作”,其中增加 的一步操作用来起到缓冲的作用。

说到这里你可能会说,这样一来增加了访问请求的路径啊,并不符合我们介绍的“4 要 1 不 要”原则。没错,的确看起来不太合理,但是如果不增加一个缓冲步骤,那么在一些场景下系统 很可能会直接崩溃,所以最终还是需要你做出妥协和平衡

答题

你是否还记得,最早期的秒杀只是纯粹地刷新页面和点击购买按钮,它是后来才增加了答题功能 的。那么,为什么要增加答题功能呢?

这主要是为了增加购买的复杂度,从而达到两个目的。

第一个目的是防止部分买家使用秒杀器在参加秒杀时作弊。2011 年秒杀非常火的时候,秒杀器 也比较猖獗,因而没有达到全民参与和营销的目的,所以系统增加了答题来限制秒杀器。增加答 题后,下单的时间基本控制在 2s 后,秒杀器的下单比例也大大下降。答题页面如下图所示。

第二个目的其实就是延缓请求,起到对请求流量进行削峰的作用,从而让系统能够更好地支持瞬 时的流量高峰。这个重要的功能就是把峰值的下单请求拉长,从以前的 1s 之内延长到 2s~10s。这样一来,请求峰值基于时间分片了。这个时间的分片对服务端处理并发非常重要,会大大减轻 压力。而且,由于请求具有先后顺序,靠后的请求到来时自然也就没有库存了,因此根本到不了 最后的下单步骤,所以真正的并发写就非常有限了。这种设计思路目前用得非常普遍,如当年支 付宝的“咻一咻”、微信的“摇一摇”都是类似的方式。

如上图所示,整个秒杀答题的逻辑主要分为 3 部分。

  • 题库生成模块,这个部分主要就是生成一个个问题和答案,其实题目和答案本身并不需要很复 杂,重要的是能够防止由机器来算出结果,即防止秒杀器来答题。

  • 题库的推送模块,用于在秒杀答题前,把题目提前推送给详情系统和交易系统。题库的推送主 要是为了保证每次用户请求的题目是唯一的,目的也是防止答题作弊。

  • 题目的图片生成模块,用于把题目生成为图片格式,并且在图片里增加一些干扰因素。这也同 样是为防止机器直接来答题,它要求只有人才能理解题目本身的含义。这里还要注意一点,由 于答题时网络比较拥挤,我们应该把题目的图片提前推送到 CDN 上并且要进行预热,不然的 话当用户真正请求题目时,图片可能加载比较慢,从而影响答题的体验。

其实真正答题的逻辑比较简单,很好理解:当用户提交的答案和题目对应的答案做比较,如果通 过了就继续进行下一步的下单逻辑,否则就失败。我们可以把问题和答案用下面这样的 key 来进 行 MD5 加密:

问题 key:userId+itemId+question_Id+time+PK

答案 key:userId+itemId+answer+PK

验证的逻辑如下图所示:

注意,这里面的验证逻辑,除了验证问题的答案以外,还包括用户本身身份的验证,例如是否已 经登录、用户的 Cookie 是否完整、用户是否重复频繁提交等。

除了做正确性验证,我们还可以对提交答案的时间做些限制,例如从开始答题到接受答案要超过 1s,因为小于 1s 是人为操作的可能性很小,这样也能防止机器答题的情况。

分层过滤

前面介绍的排队和答题要么是少发请求,要么对发出来的请求进行缓冲,而针对秒杀场景还有一 种方法,就是对请求进行分层过滤,从而过滤掉一些无效的请求。分层过滤其实就是采用“漏 斗”式设计来处理请求的,如下图所示。

1、假如请求分别经过 CDN、前台读系统(如商品详情系统)、后台系统(如交易系统)和数据库 这几层,那么:

2、大部分数据和流量在用户浏览器或者 CDN 上获取,这一层可以拦截大部分数据
的读取;

3、经过第二层(即前台系统)时数据(包括强一致性的数据)尽量得走 Cache,过滤一些无效的 请求;

4、再到第三层后台系统,主要做数据的二次检验,对系统做好保护和限流,这样数据量和请求就 进一步减少;

5、最后在数据层完成数据的强一致性校验。

这样就像漏斗一样,尽量把数据量和请求量一层一层地过滤和减少了。
分层过滤的核心思想是:在不同的层次尽可能地过滤掉无效请求,让“漏斗”最末端的才是有效 请求。而要达到这种效果,我们就必须对数据做分层的校验。

分层校验的基本原则是:

  • 将动态请求的读数据缓存(Cache)在 Web 端,过滤掉无效的数据读;
  • 对读数据不做强一致性校验,减少因为一致性校验产生瓶颈的问题;
  • 对写数据进行基于时间的合理分片,过滤掉过期的失效请求;
  • 对写请求做限流保护,将超出系统承载能力的请求过滤掉;
  • 对写数据进行强一致性校验 只保留最后有效的数据

http://chatgpt.dhexx.cn/article/uEYF4bSr.shtml

相关文章

电力系统的削峰填谷

削峰填谷(Peak cut)是调整用电负荷的一种措施。根据不同用户的用电规律,合理地、有计划地安排和组织各类用户的用电时间。以降低负荷高峰,填补负荷低谷。减小电网负荷峰谷差,使发电、用电趋于平衡。 因电厂是全天候持续…

t分布概率密度函数的推导

推导过程整理自https://www.bilibili.com/video/BV1s54y1S7Ji。 文章目录 预备知识 Γ \Gamma Γ函数(伽马函数)标准正态分布卡方分布 推导目标引理:连续型随机变量商的分布推导过程先计算 W Y / n W\sqrt{Y/n} WY/n ​的概率密度函数 p W (…

求概率密度函数方法之单调性定理

例题: 适用条件:随机变量Y关于X是单调的,也就是说随机变量Y与X存在一一映射的关系。 解法好处:计算量小,步骤简单(1,将变量替换,然后带入原式。2,改变积分对象&#xf…

概率密度估计方法-核密度估计和高斯混合分布

1、概率密度估计方法 概率密度估计方法用于估计一组数据集的概率密度分布,分为参数估计方法和非参数估计方法。 参数估计方法 假定样本集符合某一概率分布,然后根据样本集拟合该分布中的参数,例如:似然估计,混合高斯等…

概率密度函数及其在信号方面的简单理解(上)概率密度函数

概率密度函数及其在信号方面的简单理解(上)概率密度函数 上篇 概率密度函数 1 离散随机变量与连续型随机变量2 离散随机变量的分布函数 2.1 概率函数2.2 概率分布2.3 概率分布函数(累积分布函数!) 3 连续型随机变量的概…

概率密度函数估计

概率密度函数估计 前导知识:【非参数估计—直方图法、Kn近邻估计法、Parzen窗法】 1. 最大似然估计 导包: import numpy as np from numpy.linalg import cholesky import matplotlib.pyplot as plt import random # 用于随机抽样设置随机样本数&…

python实现概率密度匹配法

Python实现系列: Python实现贝叶斯优化算法 python实现t-SNE降维 Python实现12种降维算法 Python实现11 种特征选择策略 Python实现10种聚类算法 Python实现8种相似度度量 python实现反距离权重插值(IDW) Python实现12种概率分布 python实现快速傅里叶变换 python实…

威布尔概率密度分布

目录 相同的平均风速,如果概率密度分布不同,风机的发电量也会完全不同。 威布尔分布是泊松三类分布的特殊形式。概率密度函数 f ( v ) f(v) f(v)为风速 v ( v ≥ 0 ) v(v≥0) v(v≥0)出现的概率,形式如下: f ( v ) k a ( v a ) …

java正态分布的概率密度函数_正态分布概率密度函数

http://www.360doc.com/content/17/0306/13/32342759_634411464.shtml什么是正态分布 正态概率分布是连续型随机变量概率分布中最重要的形式,它在实践中有着广泛的应用。在生活中有许多现象的分布都服从正态分布,如人的身高、体重、智商分数;某种产品的尺寸和质量;降雨量;…

绘制概率密度图

1、内容简介 略 443可以交流、咨询、答疑 2、内容说明 略 3、仿真分析 clc close all clear miu 0.5; delta 0.5; r 0.1:0.1:10; p1 1/sqrt(2*pi)/miu./r.*exp(-(log(r)-miu).^2/2/delta^2); delta 1; p2 1/sqrt(2*pi)/miu./r.*exp(-(log(r)-miu).^2/2/delta^2); fig…

概率密度函数曲线及绘制

目录 前言概率密度函数曲线几类经典的概率密度函数两种绘制密度曲线的方法参考文献 前言 很多数据科学家在做回归模型评估的时候,不仅会去计算模型拟合优度R2,平均绝对误差还会去看测试集的每个样本偏差的分布情况,这个时候就需要用到概率密…

概率密度图

1、 导入库 import numpy as np import pandas as pd import matplotlib as mpl import matplotlib.pyplot as plt import seaborn as sns2、 概率密度图–kdeplot的应用 第一个参数:要绘制的图像数据 第二个参数:shade 是否填充颜色# 获得数据 dataSet pd.read_c…

MATLAB 中RMSE和MAPE的计算方法

RMSE:均方根误差 matlab计算方法: rmse sqrt(mean((YPred-Obverval).^2)); MAPE:平均百分比误差 matlab计算方法: meap mean(abs((observed - predicted)./observed))*100;

均方根误差RMSE(Root Mean Square Error)

MSE(Mean Square Error)均方误差 是真实值与预测值的插值的平方然后求和平均。 RMSE(Root Mean Square Error)均方根误差 均方根误差是预测值与真实值偏差的平方与观测次数n比值的平方根。 衡量的是预测值与真实值之间的偏差&a…

Google Earth Engine(GEE)——计算RMSE

要在 的属性中聚合数据FeatureCollection,请使用 featureCollection.reduceColumns(). 例如,要检查 watersheds 中的区域属性FeatureCollection,此代码计算相对于地球引擎计算区域的均方根误差 (RMSE): 代码: 难点是很多同学不知道如何进行RMSE的函数计算,首先就是求差…

MAE vs RMSE 如何通俗的比较两个度量

平均绝对误差MAE(mean absolute error) 和均方根误差 RMSE(root mean squared error)是衡量变量精度的两个最常用的指标,同时也是机器学习中评价模型的两把重要标尺。那两者之间的差异在哪里?它对我们的生活有什么启示…

RMSE 和 STD 的区别

文章目录 一、概念理解二、公式推导三、总结 一、概念理解 首先看一下两个的概念: RMSE: root mean square error 均方根误差,测绘学科中常称作中误差。它是指一组观测值与真值差的平方和与观测次数比值的平方根,它反映的是观测…

2022-10-31-基于用户的协同过滤推荐算法实现+MAE+RMSE的求解+项目代码+运行结果图

目录 推荐算法学习笔记项目代码运行结果图 推荐算法学习笔记 协同过滤推荐算法测评指标RMSE均方根误差 推荐系统笔记: 一、为什么需要推荐系统 为了解决互联网时代下的信息超载问题。 二、搜索引擎和推荐系统的区别 分类目录,是将著名网站分门别类&…

LPC图像拼接-代码-RMSE问题

LPC的RMSE代码 2021年cvpr-Leveraging Line-point Consistence to Preserve Structures for Wide Parallax Image Stitching(LPC)这篇论文作者给的评价指标代码。 function [ rmse ] RMSE( img, C1, C2, pts1, pts2, mesh_X, mesh_Y, off )X_col lin…

图像处理之图像质量评价指标RMSE(均方根误差)

一、RMSE基本定义 MSE全称为“Root Mean Square Error”,中文意思即为均方根误差,是衡量图像质量的指标之一。计算原理为真实值与预测值的差值的平方然后求和再平均,最后开根号,公式如下: RMSE值越小,说明…