【问题标题】:Guava RateLimiter warmup clarificationGuava RateLimiter 预热说明
【发布时间】:2018-10-21 00:06:14
【问题描述】:

鉴于我正在使用带有 warmpup 的 Guava ratelimiter,我正在尝试找出一种方法来计算在特定时间会发生多少 QPS。我读了 cmets here,但我仍然不清楚。希望这里有人可以为我澄清。

我的用例:

我调用了一个限制为 50 TPS 的外部服务。需要注意的是,我们调用它们的前 500 次必须远低于 50 TPS,之后我们可以恢复 50TPS。 (如果有比使用 ratelimiter 更好的解决方案,我很想听听!)

伪代码:

RateLimiter rateLimiter = RateLimiter.create(50.0, 10, minutes);
for (String customerId : customerList) {
    rateLimiter.acquire();
    // call external service
}

假设我们只用一个线程来做这件事。有没有办法计算给定时间的 TPS(QPS)? 3分钟? 5分钟?等等

【问题讨论】:

    标签: java guava


    【解决方案1】:

    RateLimiterwarmupPeriod 的冷(最小)速率是稳定(最大)速率的 1/3(这是从coldFactor 硬编码为RateLimiter.java:147-184 中的3.0 导出的)。在饱和需求(即不间断的许可请求)下,速率将以恒定速率增加,直到达到稳定(最大)速率。

    由于这是linear equation,我们可以将其写成y = m * x + b 的形式

    • y (a.k.a y(x)) 或 qps(t)) 是我们在饱和时段(例如 3 分钟)下的预期 QPS,
    • m 是从我们的冷(最小)速率到我们稳定(最大)速率的变化率,
    • x(或t)是饱和需求下的经过时间,并且
    • b 是我们的冷(最小)速率(我们稳定(最大)速率的 1/3)。

    总而言之,我们有qps(t) = (stableRate - coldRate) / warmupPeriod * saturatedPeriod + coldRate,其中coldRate = stableRate / 3

    因此,对于您的示例,我们可以在 3 分钟内获得预期的 QPS:

    qps(3) = (50.0 - 50.0/3.0) / 10.0 * 3.0 + 50.0/3.0 ~= 26.6666
    

    这是一个Java实现:

    /**
     * Calculates the expected QPS given a stableRate, a warmupPeriod, and a saturatedPeriod.
     * <p>
     * Both specified periods must use the same time unit.
     *
     * @param stableRate      how many permits become available per second once stable
     * @param warmupPeriod    the duration of the period where the {@code RateLimiter} ramps up
     *                        its rate, before reaching its stable (maximum) rate
     * @param saturatedPeriod the duration of the period for which the {@code RateLimiter} has
     *                        been under saturated demand starting from a cold state
     * @return The expected QPS assuming saturated demand starting from a cold state
     */
    public static double qps(double stableRate, double warmupPeriod, double saturatedPeriod) {
        if (saturatedPeriod >= warmupPeriod) {
            return stableRate;
        }
        double coldRate = stableRate / 3.0;
        return (stableRate - coldRate) * saturatedPeriod / warmupPeriod + coldRate;
    }
    

    请注意,在实践中使用单线程您将无法满足RateLimiter 的需求,因此您的实际 QPS 将略低于预期,并且很少(如果有的话)实际上达到稳定(最大)速率.但是,使用多个线程将允许您始终有一个未决的许可请求和饱和需求。

    【讨论】:

    • 感谢您的回复!清理事情。可以肯定的是,如果我想根据我在帖子中提到的设置在 3 分钟内找到 QPS,这会是等式的样子吗? Ratelimiter: RateLimiter.create(50.0, 10, minutes); y = (10.0 [m] * 3.0 [x]) + (50/3.0) [b] 并且 y 将是 3 分钟的 QPS?
    • 不完全是,实际上是(50.0 - 50.0/3.0) / 10.0 * 3.0 + 50.0/3.0。我已经更新了我的答案以试图澄清这一点。谢谢。
    猜你喜欢
    • 2017-11-03
    • 1970-01-01
    • 1970-01-01
    • 2015-10-31
    • 1970-01-01
    • 2021-05-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多