我正在寻找一种方法来限制特定事件的发生率。我对每秒事件的数量有一个硬限制,但可以容忍一些错误。实现需要使用尽可能少的内存。我们目前保留一个时间戳队列,这总是准确的,但最好是消除内存占用。
令牌桶算法似乎很合适,但它似乎只能保证平均速率。它可以违反限制,具体取决于事件发生的时间相对于令牌补充点。
如何制定令牌桶的错误?可以校准吗?
在我的第一个提案中,您将必须存储算法的开始时间和计数器,因此只需要两个值。
制定固定的时间表。每个事件将被分配一个特定的时间,该时间直接由算法的开始时间,自那时起的事件数量和所需的速率导出:
event_time = start_time + event_counter / rate
在每个事件之后增加event_counter
并且睡觉直到下一个事件的event_time
到期(sleep(event_time - current_time)
或类似)。
在我的第二个提案中,您还必须存储延迟时间,因此您将存储三个值。
在每个事件之后,只要延迟状态就睡觉并继续下一个事件。此外,在每个事件之后(或者只是在counter % n == 0
仅在n个事件之后才执行),您更新延迟:使用当前时间,开始时间和计数器计算当前平均速率;如果它太高,你会增加延迟;如果它太低你会减少延迟;否则你保持延迟不变。
这会自动计算出您的事件和费率所需的平均延迟。但是,如果您的活动持续时间变化很大,那么将会遇到麻烦。在最坏的情况下(具有特定的持续时间变化),您甚至可能会产生周期性上升和减少延迟的共振效应。