什么是尾部延迟?


尾部延迟(也称为高百分比延迟)是指客户端很少看到的高延迟。例如:“我的服务通常在10毫秒左右响应,但有时需要100毫秒左右”。世界上有很多导致尾部等待时间的原因,包括争用,垃圾回收,数据包丢失,主机故障以及操作系统在后台执行的奇怪操作。
原因之一是现代体系结构(如微服务和SoA)往往具有很多组件,因此一个用户交互可以转换成很多很多服务调用。在这些系统中,一个常见的模式是有一些前端,可以是服务,某些Javascript或应用程序,它可以调用许多后端服务来完成所需的工作。这些服务然后调用其他服务,依此类推。这形成了两种交互:并行扇出,服务在其中并行调用许多后端,然后等待它们全部完成;串行链,其中一个服务调用另一个后端,后者又调用另一个,依此类推。
这些模式使尾部延迟比您想像的更为重要。
 
为了理解为什么,让我们做一个简单的数值实验。让我们简化世界,使所有服务都以相同的延迟进行响应,并且延迟遵循非常简单的双峰分布:99%的时间平均为10ms(正态分布,标准偏差为2ms),而1%的平均时间时间平均为100毫秒(标准差为10毫秒)。在现实世界中,服务延迟几乎总是像这样的多模式,但通常不只是正态分布的总和(但这在这里无关紧要)。
首先,让我们考虑并行调用。这里的逻辑很简单:我们并行调用N个服务,然后等待最慢的一个。应用我们的直觉表明,随着N的增加,我们等待约100ms缓慢呼叫的可能性越来越大。在N = 1的情况下,发生这种情况的时间约为1%。在N = 10的情况下,大约有10%的时间。在这个简单的模型中,这种基本直觉是正确的。
尾部模式(过去很少见)随着N的增加而开始占主导地位。现在很少见的是正常现象。
串行链更有趣。在这种模型中,服务调用另外一个服务称为一条链。最终延迟是整个链上所有服务调用的延迟总和,因此还有很多情况需要考虑:1个慢速服务,2个慢速服务等。这意味着我们可以预期分布的整体形状随着N的增加而变化。借助中心极限定理,我们可以算出N变大时的样子。同样,尾部延迟在这里变得更加突出。相对少见的尾巴使我们收敛的分布方差增加了25倍。这是一个巨大的差异,这是由于一些起初似乎不太重要的原因引起的。