我正在尝试分散突发接收的数据。这意味着我有一些其他应用程序大量接收的数据。对于每个数据条目,我需要在某个服务器上执行一些额外的请求,我应该在这些服务器上限制流量。因此,我尝试在下一个数据突发到达之前的时间内分散请求。
目前我正在使用令牌桶来分散数据。然而,由于我收到的数据已经很糟糕,我仍然要么填满待处理请求的队列,要么每当有突发事件出现时我都会出现尖峰。所以这个算法似乎没有做我需要的那种整形。
还有哪些其他算法可以限制请求?我知道我有高负载和低负载的时候,所以应用程序应该很好地处理这两者。
我不确定我是否真的能够解释我目前遇到的问题。如果您需要任何澄清,请告诉我。
编辑:
我将尝试进一步澄清问题并解释为什么简单的速率限制器不起作用。
问题在于流量的突发性质以及突发在不同时间具有不同大小的事实。几乎不变的是每次突发之间的延迟。因此,我们得到了一堆数据记录进行处理,我们需要在下一批进入之前将它们尽可能均匀地分布。但是,我们不能 100% 确定下一批何时会进入,只是大致上,所以一个简单divide time by number of records
的不能正常工作。
速率限制不起作用,因为以这种方式传播数据是不够的。如果我们接近速率饱和,一切都很好,并且我们均匀分布(尽管这种情况不应该经常发生)。如果我们低于阈值,那么传播会变得更糟。
我将举一个例子来使这个问题更清楚:
假设我们将流量限制为每秒 10 个请求,并且新数据大约每 10 秒出现一次。
当我们在一个时间帧开始时获得 100 条记录时,我们将每秒查询 10 条记录,并且我们有一个完美的均匀分布。但是,如果我们只获得 15 条记录,我们将有 1 秒查询 10 条记录,1 秒查询 5 条记录和 8 秒查询 0 条记录,因此随着时间的推移,我们的流量水平非常不均。相反,如果我们每秒只查询 1.5 条记录会更好。然而,设置这个速率也会产生问题,因为新数据可能会更早到达,所以我们没有完整的 10 秒,并且 1.5 次查询是不够的。如果我们使用令牌桶,问题实际上会变得更糟,因为令牌桶允许突发在时间框架开始时通过。
然而这个例子过于简单了,因为实际上我们不能完全知道在任何给定时刻挂起的请求的数量,而只是一个上限。所以我们每次都必须根据这个数字进行节流。