从概率统计看限流阈值问题

简介: 服务提供方所在的应用A有100台机器,某个调用方需要申请该应用的某个服务1000 QPS的调用量,根据经验,如果A应用的单机限流值配置成10,应该会有比较多的额度内的流量被限制住,如果配置的太高,又会有稳定性风险,限流值应该配置成多少合适呢?

问题    

      “服务提供方所在的应用A有100台机器,某个调用方需要申请该应用的某个服务1000 QPS的调用量,根据经验,如果A应用的单机限流值配置成10,应该会有比较多的额度内的流量被限制住,如果配置的太高,又会有稳定性风险,限流值应该配置成多少合适呢?”

 

分析

        把限流的问题抽象一下:若单机QPS平均值为m,求实际落到该机器的QPS 不超过k的概率P(x<=k),知道了这个概率分布情况,我们就能知道限流值n设置为多少合适,或者能相对量化的分析所配置的限流的作用效果。

       为了便于分析,我们不妨假设,在不扩缩容的某个时间段,流量落到某台机器的概率是稳定的,而且我们知道每次流量落到哪台机器是独立事件,那么在单位时间内,落在某台机器的流量x可以认为是服从泊松分布的。

结论

故实际落到该机器的QPS x<=k 的概率为:

image.png

n三k

m

P(X<-K)二

xe-m

n!

nE0

   使用该公式,代入不同的k和m,可以得到单机QPS平均值m取不同值时,实际打到某台机器的流量x不超过k的概率值(精确到百分比小数点后5位)。

m=1 m=5 m=10 m=20
k x<k的概率 k x<k的概率 k x<k的概率 k x<k的概率
0 36.78794% 0 0.67379% 0 0.00454% 0 0.00000%
1 73.57589% 1 4.04277% 1 0.04994% 1 0.00000%
2 91.96986% 2 12.46520% 2 0.27694% 2 0.00005%
3 98.10118% 3 26.50259% 3 1.03361% 3 0.00032%
4 99.63402% 4 44.04933% 4 2.92527% 4 0.00169%
5 99.94058% 5 61.59607% 5 6.70860% 5 0.00719%
6 99.99168% 6 76.21835% 6 13.01414% 6 0.02551%
7 99.99898% 7 86.66283% 7 22.02206% 7 0.07786%
8 99.99989% 8 93.19064% 8 33.28197% 8 0.20873%
9 99.99999% 9 96.81719% 9 45.79297% 9 0.49954%
10 1 10 98.63047% 10 58.30398% 10 1.08117%
11 1 11 99.45469% 11 69.67761% 11 2.13868%
12 1 12 99.79811% 12 79.15565% 12 3.90120%
13 1 13 99.93020% 13 86.44644% 13 6.61276%
14 1 14 99.97737% 14 91.65415% 14 10.48643%
15 1 15 99.99310% 15 95.12596% 15 15.65131%
16 1 16 99.99801% 16 97.29584% 16 22.10742%
17 1 17 99.99946% 17 98.57224% 17 29.70284%
18 1 18 99.99986% 18 99.28135% 18 38.14219%
19 1 19 99.99997% 19 99.65457% 19 47.02573%
20 1 20 99.99999% 20 99.84117% 20 55.90926%
21 1 21 100.00000% 21 99.93003% 21 64.36976%
22 1 22 100.00000% 22 99.97043% 22 72.06113%
23 1 23 100.00000% 23 99.98799% 23 78.74928%
24 1 24 100.00000% 24 99.99531% 24 84.32274%
25 1 25 1 25 0.99998232 25 88.78150%
26 1 26 1 26 0.99999358 26 92.21132%
27 1 27 1 27 0.99999775 27 94.75193%
28 1 28 1 28 0.99999924 28 96.56665%
29 1 29 1 29 0.99999975 29 97.81818%
30 1 30 1 30 0.99999992 30 98.65253%
31 1 31 1 31 0.99999998 31 99.19082%
32 1 32 1 32 0.99999999 32 99.52726%
33 1 33 1 33 1 33 99.73116%
34 1 34 1 34 1 34 99.85110%
35 1 35 1 35 1 35 99.91963%
36 1 36 1 36 1 36 99.95771%
37 1 37 1 37 1 37 99.97829%
38 1 38 1 38 1 38 99.98912%
39 1 39 1 39 1 39 99.99468%

  通过该表格可以发现,如果要保证99.9%的流量不被限流:

  当单机QPS平均值为1的时候,我们的限流值要设置为不小于5.

  当单机QPS平均值为5的时候,我们的限流值要设置为不小于12.

  当单机QPS平均值为10的时候,我们的限流值要设置为不小于21.

  当单机QPS平均值为20的时候,我们的限流值要设置为不小于35.

  如果需要看更详细的概率分布,可以用下面这段简单的工具代码来生成,需要注意的是m调大的时候,实际QPS的上限MAX_K要相应的调大。

package com.cainiao.hyena;
import java.math.BigDecimal;
import java.math.RoundingMode;
/**
 * [Poisson分布概率计算工具]
 *
 * @author jianping.pjp created on 2020/12/8 下午11:29
 * Copyright 2020 (C) <Alibaba Global>
 */
public class PoissonTest {
    //在指定QPS平均值的前提下,我们猜测实际最大能打到的QPS,可根据实际跑出的结果来调整,这个值是和平均值正相关的
    private static final int MAX_K = 40;
    public static void main(String[] args) {
        int m = 10;
        BigDecimal p = new BigDecimal(0);
        for (int k = 0; k < MAX_K; k++) {
            BigDecimal x = p2(m, k);
            p = p.add(x);
            System.out.println(k + "," + p.setScale(10, RoundingMode.DOWN).doubleValue());
        }
    }
    private static BigDecimal p2(int m, int k) {
        BigDecimal a = new BigDecimal(1);
        if (k == 0) {
            return new BigDecimal(Math.exp(-m));
        }
        BigDecimal r = new BigDecimal(-m).divide(new BigDecimal(k), 100, RoundingMode.DOWN);
        BigDecimal b = new BigDecimal(Math.exp(r.doubleValue()));
        for (int n = 1; n <= k; n++) {
            BigDecimal an = new BigDecimal(m).divide(new BigDecimal(n), 100, RoundingMode.DOWN).multiply(b);
            a = a.multiply(an);
        }
        return a;
    }
}

 

验证

通过下面验QPS模拟生成工具代码可以验证我们的猜测,以下代码对平均值10 QPS做了100万次模拟试验,实验的结果符合我们的猜测。

package com.cainiao.hyena;
import java.util.HashMap;
import java.util.Map;
import java.util.Random;
/**
 * [模拟QPS实现验证]
 *
 * @author jianping.pjp created on 2020/12/10 下午1:07
 * Copyright 2020 (C) <Alibaba Global>
 */
public class PoissonVerification {
    //在指定QPS平均值的前提下,我们猜测实际最大能打到的QPS,可根据实际跑出的结果来调整,这个值是和平均值正相关的
    private final static int MAX_K = 40;
    public static void main(String [] args){
        Random r = new Random();
        //每次实验打到指定机器的实际QPS
        Map<Integer,Integer> map = new HashMap<>();
        //模拟QPS平均值
        int qps = 10;
        //实现次数
        int experimentsTimes = 1000000;
        for(int i=0;i<qps*experimentsTimes;i++){
            int n = r.nextInt(experimentsTimes);
            Integer c= map.get(n);
            if(c==null){
                c = 0;
            }
            c++;
            map.put(n,c);
        }
        for(int k=0;k<MAX_K;k++){
            //实际QPS不超过K的实验次数
            int lk = 0;
            for(int i=0;i<experimentsTimes;i++){
                Integer c = map.get(i);
                if(null ==c || c<=k){
                    lk++;
                }
            }
            double ratio = (double)lk/experimentsTimes;
            System.out.println(k+","+ratio);
        }
    }
}
                     m=10
k  x<k的概率 试验结果
0 0.00454% 0.00510%
1 0.04994% 0.05090%
2 0.27694% 0.28200%
3 1.03361% 1.02100%
4 2.92527% 2.91860%
5 6.70860% 6.70020%
6 13.01414% 12.99690%
7 22.02206% 21.95120%
8 33.28197% 33.25910%
9 45.79297% 45.80050%
10 58.30398% 58.31790%
11 69.67761% 69.67210%
12 79.15565% 79.15300%
13 86.44644% 86.48280%
14 91.65415% 91.68780%
15 95.12596% 95.15310%
16 97.29584% 97.30320%
17 98.57224% 98.56930%
18 99.28135% 99.28800%
19 99.65457% 99.66060%
20 99.84117% 99.84590%
21 99.93003% 99.92790%
22 99.97043% 99.97050%
23 99.98799% 99.98880%
24 99.99531% 99.99570%
25 0.99998232 99.99870%
26 0.99999358 99.99930%
27 0.99999775 99.99990%
28 0.99999924 1
29 0.99999975 1
30 0.99999992 1
31 0.99999998 1
32 0.99999999 1
33 1 1

相关资料

http://www.ruanyifeng.com/blog/2015/06/poisson-distribution.html

https://www.zhihu.com/question/26441147/answer/208718584

目录
相关文章
|
存储 运维 NoSQL
Redis分片集群中数据是怎么存储和读取
为了实现水平扩展和高可用性,Redis采用了分片机制。分片是将数据按照一定规则分配到多个节点上进行存储,每个节点只负责部分数据的存储和处理。这样可以提高系统的吞吐量和可扩展性。
849 0
|
安全 Java 持续交付
如何实现上传jar直接部署成功,这篇文章直接带你上手springboot实现jar包热更新!
本文详细讲解了在Spring Boot应用中实现Jar包热更新的实践方法。通过自定义类加载器(`HotClassLoader`),动态加载和卸载指定目录下的Jar包,结合Spring Bean动态注册机制,使新加载的类能够被Spring容器管理。同时,提供了文件上传接口,方便用户手动触发Jar包更新。文章还强调了安全性、依赖管理和线程安全等注意事项,并给出了测试步骤和总结,帮助开发者高效实现热更新功能,减少服务中断和提升开发效率。
|
6月前
|
关系型数据库 数据库 文件存储
告别数字麻木,重拾消费感知:ezBookkeeping —— 您的轻量自托管记账伴侣
在数字支付时代,金钱变得抽象,ezBookkeeping 让消费重新可感。这款开源、自托管的轻量记账工具,支持 Docker 部署,兼顾隐私与易用,助你找回对支出的真实掌控,适合树莓派到 NAS 各类设备。
877 0
告别数字麻木,重拾消费感知:ezBookkeeping —— 您的轻量自托管记账伴侣
|
10月前
|
监控 数据挖掘 API
利用拼多多 API 接口,实现拼多多店铺物流时效优化
在电商竞争激烈的今天,物流时效直接影响拼多多店铺的客户满意度与复购率。本文介绍如何通过拼多多开放平台的 API 接口,自动化获取订单与物流数据,分析时效瓶颈并制定优化策略。内容涵盖 API 基本功能、物流数据分析、智能优化方法及 Python 实现示例,帮助商家提升配送效率,降低退货率,增强用户体验与店铺竞争力。
1329 0
|
9月前
|
JSON 关系型数据库 MySQL
贷款审批通过生成器,虚拟贷款图片生成器, 贷款截图生成器【php版】
用php开发的一个贷款额度生成器,效果非常的6,具体是怎么操作的呢,请看我下面的代码演示,但是需要你把代码部署到服务器才可以,或者直接下载我们的项目包。
|
架构师 Oracle 大数据
从大数据时代变迁到数据架构师的精通之路
无论从事何种职业,自学能力都显得尤为重要。为了不断提升自己,我们可以尝试建立一套个性化的知识目录或索引,通过它来发现自身的不足,并有针对性地进行学习。对于数据架构师而言,他们需要掌握的知识领域广泛而深入,不仅包括硬件、网络、安全等基础技术,还要了解应用层面,并熟练掌握至少一门编程语言。同时,深入理解数据库技术、具备大数据实操经验以及精通数据仓库建模和ELT技术也是必不可少的。只有这样,数据架构师才能具备足够的深度和广度,应对复杂的业务和技术挑战。 构建个人知识体系是数据架构师在学习和工作中的一项重要任务。通过系统化、不断深化的知识积累,数据架构师能够有效应对快速变化的商业环境和技术革新,进一
|
人工智能
写歌词的技巧和方法全解析:开启你的音乐创作之旅,妙笔生词智能写歌词软件
怀揣音乐梦想,渴望用歌词抒发情感?掌握关键技巧,你也能踏上创作之旅。灵感来自生活点滴,主题明确,语言简洁,韵律和谐。借助“妙笔生词智能写歌词软件”,AI辅助创作,轻松写出动人歌词,实现音乐梦想。
|
资源调度 Serverless 计算机视觉
高斯函数 Gaussian Function
**高斯函数,或称正态分布,以数学家高斯命名,具有钟形曲线特征。关键参数包括期望值μ(决定分布中心)和标准差σ(影响分布的宽度)。当μ=0且σ²=1时,分布为标准正态分布。高斯函数广泛应用于统计学、信号处理和图像处理,如高斯滤波器用于图像模糊。其概率密度函数为e^(-x²/2σ²),积分结果为误差函数。在编程中,高斯函数常用于创建二维权重矩阵进行图像的加权平均,实现模糊效果。
2982 1
|
JavaScript 前端开发 Python
apply的用法
apply的用法
|
Ubuntu 计算机视觉 C++
Ubuntu 20.04 编译 Opencv 4.11,详细步骤(带图)及报错解决,我的踩坑之旅~
Ubuntu 20.04 编译 Opencv 4.11,详细步骤(带图)及报错解决,我的踩坑之旅~
10930 0