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

简介: 服务提供方所在的应用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

目录
相关文章
|
6月前
|
缓存 算法 Java
限流算法 - 基本实现
限流算法 - 基本实现
59 0
|
消息中间件 算法 Sentinel
只需5分钟,了解常见的四种限流算法
只需5分钟,了解常见的四种限流算法
261 4
|
存储 算法 Java
限流常见的算法有哪些呢?
限流常见的算法有哪些呢?
66 0
|
6月前
|
存储 算法 NoSQL
常见限流算法及其实现
在分布式系统中,随着业务量的增长,如何保护核心资源、防止系统过载、保证系统的稳定性成为了一个重要的问题。限流算法作为一种有效的流量控制手段,被广泛应用于各类系统中。本文将详细介绍四种常见的限流算法、两种常用的限流器工具,从原理、源码的角度进行分析。
429 0
|
6月前
|
算法 Go API
限流算法~
限流算法~
64 1
|
6月前
|
缓存 算法 NoSQL
常见限流算法解读
常见限流算法解读
|
算法
平稳限流?突发限流?还是时间窗口?三种限流算法分析与对比
漏桶限流算法和令牌桶限流算法是两种常见的限流算法,它们的原理和实现方式有所不同。 漏桶限流算法 漏桶限流算法是一种固定容量的桶,水以恒定的速率流出,来限制请求的流量。当请求到来时,会先加入到漏桶中,漏桶以恒定的速率处理请求,处理不了的请求会被丢弃。 以下是漏桶限流算法的流程图:
120 0
|
算法
限流常见的算法有哪些?
常见的限流算法有以下几种:
80 0
|
缓存 NoSQL 算法
服务限流惩罚是怎么一回事
服务限流惩罚是怎么一回事
77 0
阈值的求解(两峰之间)
阈值的求解(两峰之间)
147 0
阈值的求解(两峰之间)