一个gydF4y2Ba总结gydF4y2Ba是一种度量类型gydF4y2Ba普罗米修斯gydF4y2Ba可以用来监控延迟(或请求大小)等其他发行版。例如,当您监视一个REST端点可以使用总结和配置它提供95的延迟。如果百分位是120 ms,意味着95%的电话是超过120毫秒,和5%的人慢。gydF4y2Ba
总结指标在普罗米修斯客户端库,实现gydF4y2Baclient_golanggydF4y2Ba或gydF4y2Baclient_javagydF4y2Ba。你在其他应用程序中调用图书馆,图书馆将为您计算百分位数。gydF4y2Ba
理解底层的算法中使用这些库是很困难的。您将看到代码注释指一篇研究论文名为“gydF4y2Ba有效的计算偏差分位数的数据流gydF4y2Ba“格雷厄姆gydF4y2BaCormodegydF4y2Ba,抛gydF4y2Ba科恩gydF4y2Ba,年代。gydF4y2BaMuthukrishnangydF4y2Ba,DiveshgydF4y2Ba斯利瓦斯塔瓦gydF4y2Ba,通常被称为gydF4y2BaCKMSgydF4y2Ba通过作者的姓氏的首字母。如果你像我一样,你会发现纸难以阅读。gydF4y2Ba
这篇文章是为了总结CKMS算法简而言之。gydF4y2Ba
我gydF4y2Ba真的gydF4y2Ba需要知道吗?gydF4y2Ba
不。您可以使用内部总结指标不知道它们是如何工作的。还有其他的事情,你应该知道什么时候测量延迟,gydF4y2Ba何时使用总结和何时使用直方图gydF4y2Ba,但该算法用于计算百分位数是没有人。gydF4y2Ba
然而,它是很有趣的看下罩,并了解CKMS算法将帮助您避免一些常见的陷阱,当监测gydF4y2Ba延迟gydF4y2Ba或其他发行版。gydF4y2Ba
术语gydF4y2Ba
条款gydF4y2Ba百分位gydF4y2Ba和gydF4y2Ba分位数gydF4y2Ba基本上意味着同样的事情:gydF4y2Ba
- 一个gydF4y2Ba百分位gydF4y2Ba是表示为0到100之间的一个百分比。例如,“延迟分布的第95个百分位是120 ms”意味着95%的观测分布超过120毫秒,5%低于120毫秒。gydF4y2Ba
- 一个gydF4y2Baφ-quantile(0≤φ≤1)gydF4y2Ba表示为一个值在0和1之间。例如,0.95φ-quantile延迟分布是一样的第95个百分位的延迟分布。gydF4y2Ba
在这篇文章中,我们使用gydF4y2Ba分位数gydF4y2Ba作为一个短名称gydF4y2Baφ-quantilegydF4y2Ba之后,使用的术语CKMS纸。gydF4y2Ba
准确的分位数gydF4y2Ba
计算准确的分位数是微不足道的,但它花费大量的内存,因为你需要存储所有延迟观测排序列表。让我们介绍一些变量:gydF4y2Ba
- ngydF4y2Ba:观察的总数(即。,的大小排序列表)。gydF4y2Ba
- 排名gydF4y2Ba:一个观察的位置排序列表。gydF4y2Ba
给出一个完整的排序列表观察,很容易找到分位数。例如,如果你正在寻找0.95分位数,你只需要带上元素*等级= 0.95 * n *(即。的元素位置gydF4y2Ba0.95 * ngydF4y2Ba围捕转换为int)。gydF4y2Ba
数据模型为一个压缩的列表gydF4y2Ba
存储的完整列表观察延迟显然需要太多内存对真实世界的应用程序。因此,CKMS算法定义了gydF4y2Ba压缩gydF4y2Ba函数丢弃观察从列表中,只保留少量的样本。gydF4y2Ba
不利的一面是,我们再也不能知道确切的样品:当我们插入一个新的观察样品的列表,很难说到底在哪个位置会有最终的完整列表。gydF4y2Ba
不过,我们可以跟踪每个样本的最小和最大可能的排名:gydF4y2Ba
注意,可能排名重叠的时间间隔。然而,每个样本的最小可能的排名总是至少1比其前任的最低可能的排名。gydF4y2Ba
在实践中,它是不方便存储为每个样本绝对最小和最大可能的排名,因为当我们插入一个新的样品,所有样品的排名需要增加1。gydF4y2Ba
因此,CKMS算法存储增量,而不是绝对的价值观:gydF4y2Ba
- ggydF4y2Ba:最低等级的样本之间的差异和其前任的最低等级。gydF4y2Ba
- δgydF4y2Ba:间隔的大小,即最大可能排名-最低可能的排名。gydF4y2Ba
编码,上面列出的样品是这样的:gydF4y2Ba
使用表示,我们可以插入新的样品没有更新现有的在列表中。gydF4y2Ba
我们可以很容易地计算出通过添加其最短的一个示例gydF4y2BaggydF4y2Ba价值的总和gydF4y2BaggydF4y2Ba值的前辈在列表中。最大可能的等级是最低优先gydF4y2BaδgydF4y2Ba。gydF4y2Ba
限制了错误:三角洲的上界gydF4y2Ba
总结指标在普罗米修斯的客户端库的API允许用户定义一个允许误差范围。例如,在gydF4y2Baclient_javagydF4y2BaAPI是这样的:gydF4y2Ba
总结。构建(“名字”,“帮助信息”).quantile (0.95, 0.01) .register ();gydF4y2Ba
在这个例子中,0.01的容许误差意味着我们的目标是0.95分位数,但是我们是快乐的0.94分位数和0.96分位数之间的任何值。gydF4y2Ba
为了保证结果是在这些范围内,我们需要设置一个上限gydF4y2BaδgydF4y2Ba,即,我们需要限制可能的排名值范围的大小为每个样本。gydF4y2Ba
一个微不足道的上界gydF4y2BaδgydF4y2Ba可以导出如下:如果我们想要保持在0.94和0.96之间分位数,最低容许等级总数的0.94倍观察,最大允许排名是观测的总数的0.96倍。减去gydF4y2Ba最大-最小gydF4y2Ba和一个上界gydF4y2BaδgydF4y2Ba。gydF4y2Ba
然而,CKMS算法比这更聪明:我们需要严格约束只有大约0.95分位数。我们其他的分位数不感兴趣,所以我们可以放松约束其他分位数。gydF4y2Ba
CKMS算法定义了一个误差函数,一个严格的上限目标分位数,但放松误差你去左边或右边。gydF4y2Ba
上图显示了带有0.95的误差函数作为目标分位数和0.01容许误差。这意味着,实际结果将在0.94分位数和0.96分位数之间。gydF4y2Ba
这是另一个例子:它显示了误差函数以0.5作为目标分位数(中值)和0.02容许误差。这意味着,实际结果将在0.48分位数和0.52分位数之间。gydF4y2Ba
有趣的是,您可以跟踪多个分位点结合这些函数。gydF4y2Ba
总结。构建(“名字”,“帮助信息”).quantile (0.95, 0.01) .quantile (0.5, 0.02) .register ();gydF4y2Ba
合并后的误差函数保证0.5分位数与容许误差0.02和0.95分位数0.01容许误差。gydF4y2Ba
该算法gydF4y2Ba
算法本身非常简单:它定义了功能gydF4y2Ba插入gydF4y2Ba和gydF4y2Ba压缩gydF4y2Ba保证,确保功能gydF4y2BaδgydF4y2Ba不大于所允许的误差函数。gydF4y2Ba
插入gydF4y2Ba
样品由观测值排序的列表。插入一个新值时,我们首先需要找到它的位置排序的列表,然后添加一个新条目以下值:gydF4y2Ba
- g = 1gydF4y2Ba:最低等级至少是1超过前任的最低等级。gydF4y2Ba
- δ=最大允许误差的前任- 1gydF4y2Ba:新条目的不确定性等级至少1小于最大允许的不确定性的前任在新元素之前插入。gydF4y2Ba
当我们插入一个样本在列表的开始或结束时,或一个空列表,我们集gydF4y2Bag = 1gydF4y2Ba和gydF4y2Baδ= 0gydF4y2Ba。gydF4y2Ba
压缩gydF4y2Ba
每隔一段时间gydF4y2Ba压缩gydF4y2Ba从列表中删除条目。作为一个例子,gydF4y2Baclient_javagydF4y2Ba调用gydF4y2Ba压缩gydF4y2Ba定期为每个128插入。gydF4y2Ba
压缩功能扫描列表和合并相邻节点时,这并不违反误差函数。合并后的节点初始化如下:gydF4y2Ba
- 价值gydF4y2Ba:gydF4y2Ba价值gydF4y2Ba正确的节点,丢弃左节点的值。gydF4y2Ba
- ggydF4y2Ba:之和gydF4y2BaggydF4y2Ba的左和右节点。我们把正确的节点的值,合并后的节点的最低等级的区别及其前身是合并后的最小距离的总和节点。gydF4y2Ba
- δgydF4y2Ba:gydF4y2BaδgydF4y2Ba正确的节点。gydF4y2Ba
这里有一个例子合并前两个节点:gydF4y2Ba
评价gydF4y2Ba
压缩率是令人兴奋的。我1000年和100000000年之间插入随机值和重复这个跟踪一个,两个,三个分位数。在压缩列表中样本的数量每次运行仍远低于100年底在大多数运行时,它不会增加增加输入的大小。gydF4y2Ba
我使用了gydF4y2Baclient_javagydF4y2Ba实施的评价,评价的源代码gydF4y2Ba在这里gydF4y2Ba。gydF4y2Ba
陷阱gydF4y2Ba
有一些与CKMS陷阱的方法:gydF4y2Ba
- 你不能总在多个实例。举个例子,如果你有一个总结代表延迟观测到在服务器,另一个代表延迟总结观察到在服务器B,然后没有办法把这些分别计算摘要。gydF4y2Ba
- 相对误差gydF4y2Ba排名gydF4y2Ba,而不是相对于观测值。对于长尾延迟分布这可能产生巨大的差异。例如,0.94分位数可能是120 ms,但0.96分位数可能在2343 ms。接受任何值0.94和0.96分位数之间你会接受任何值120毫秒到2343毫秒之间。gydF4y2Ba
既可以解决使用直方图代替总结,并通过计算从这些直方图使用分位数gydF4y2Bahistogram_quantile ()gydF4y2Ba
普罗米修斯的函数查询语言。不过,您可以使用摘要没有任何先验知识的分布要监视,虽然目前的普罗米修斯直方图需要先验桶边界的定义。gydF4y2Ba
笔记和实现细节gydF4y2Ba
这篇文章的目的是给你一个高度概括的总结指标普罗米修斯的实现客户端库内部工作。有一些细节,我离开后更容易阅读:gydF4y2Ba
- 的上限gydF4y2BaδgydF4y2Ba用于纸上不是gydF4y2BaδgydF4y2Ba,但在gydF4y2Bag +δgydF4y2Ba。这使得计算过于保守,但overtight必然有助于使精度保证。gydF4y2Ba
- 插入分批实现。例如,gydF4y2Baclient_javagydF4y2Ba收集128个值在一个缓冲和刷新值压缩列表当缓冲区满(或当普罗米修斯服务器擦伤)。gydF4y2Ba
- 你不想得到延迟指标对整个应用程序的运行时。你想看一个合理的时间间隔。例如,gydF4y2Baclient_javagydF4y2Ba实现了一个可配置的滑动窗口,默认为10分钟。gydF4y2Ba
相关工作gydF4y2Ba
CKMS算法出版于2005年,是相对旧的(这并不意味着它不适用)。新分位点的研究包括:gydF4y2Ba
- ,那么空间和时间的确定性算法有偏见的分位数在数据流gydF4y2Ba一篇新的文章作者一样CKMS。gydF4y2Ba
- 使用t-Digests计算非常准确的分位数gydF4y2Ba与一个参考实现,Java和独立的实现和Python。允许将分别计算摘要结合不损失精度。gydF4y2Ba