一个故事

某个互联网创业公司太火了,经常发生一堆客户涌上来的情况。导致很多人发现网站和应用很慢,继而开始抱怨。虽然抱怨,但是还是在忍着用它,谁让它这么火呢。但是公司 CEO 感觉这样下去不行啊,得想办法提高服务质量,保证所有人顺畅使用网站和应用,但是不能花太多钱。作为 CTO 的你需要想个方案。不仅仅要扩容,而且要用理论证明一下扩多少是最佳的,钱花得漂亮。这个时候,就应该翻出来互联网技术和架构网站上的文章了:排队论在架构的应用:对服务延迟、稳定性的影响

先看一张图

这张图的纵坐标是等待时间;横坐标是系统负载。

有一个简单的原则:假如某个系统的负载超过的 80%,延迟将会急剧上升。所以对于弹性云应用部署,最佳的负载范围是接近并且不超过系统容量的 80% 。

排队论的细节

假设:请求到达频率为 λ (泊松分布);系统服务完成频率为 μ (泊松分布);比例 λ/μ 称为系统负载。
如果这个比例高于 1,请求到达的速度大于服务速度,那么排队的队列将会无限增长。
如果这个比例小于 1,排队的队列长度会达到某个稳定的均衡点。

平均等待延迟为 W = 1/(μ-λ)

现在假设服务频率是固定的 μ (现有服务资源),请求到达频率为 λ = ρ μ 。

那么 W = 1/μ(1-ρ) ,即等待延迟和 1/(1-ρ) 成正比。 ρ 接近于 1 的时候,等待延迟趋近于无穷大。之前的图画的正是 1/(1-ρ) 。
可以看出延迟在 ρ 超过 0.8 之后增长非常快。

如何处理超出容量的峰值

1. 可控超时算法 (CoDel)

onNewRequest(req, queue):

if (queue.lastEmptyTime() < (now  N seconds)) {
timeout = M ms
} else {
timeout = N seconds;
}
queue.enqueue(req, timeout)

当过去的一段时间内等待队列不为空,则调整超时时间为短时间,否则使用长时间。
在系统超容的情况下快速失败。而且允许系统发生短时间的峰值,提供系统稳定性。
这个可以在服务端实现。

2. 可以考虑用 LIFO

替代 FIFO 的方式抛弃超载请求,提高总服务质量 (Adaptive LIFO)。

另外考虑其他几个模型:随机服务和优先级队列。这个也可以在服务端实现。

3. 限制服务接口请求最高频率

可以参考之前的文章:架构必备:Rate limiting 的作用和常见方式 https://blog.eood.cn/rate-limiting

4. 架构层面请求持久化,最终一致。

弹性架构

现在大部分云上架构都实现了容量的动态伸缩。比如 AWS 和 Google Cloud 的 Auto-scaling Group。虽然弹性部署能够在一定程度上降低系统的开销,但还存在一些问题:

扩容操作需要一段时间,应对请求峰值有挑战。

一方面需要尽快完成系统的收缩和伸展。另一方面对系统容量需求进行预测,对峰值进行预测。

对于财务还可以做以下优化:根据系统负载对总花销进行优化。降低超低负载的情况发生。

注册 DigitalOcean 1G 内存, 30GB SSD 硬盘 VPS, 获取 10 美元折扣

更多资料

  • http://staff.um.edu.mt/jskl1/simweb/intro.htm
  • http://queue.acm.org/detail.cfm?id=2839461
  • http://www.johndcook.com/blog/2009/01/30/server-utilization-joel-on-queuing/
  • http://robharrop.github.io/maths/performance/2016/02/20/service-latency-and-utilisation.html

    推荐这些相关文章

    订阅这个博客:

    关注我的微博:

    关注我的推特: