Golang 如何计算监控数据密集型系统的百分位数
在监控数据密集型系统时,百分位数可以帮助我们更好地了解系统的性能表现,预测其可能的瓶颈并优化其性能。本文将介绍如何计算监控数据密集型系统的百分位数。
什么是百分位数?
百分位数是指在一组数据中,某个百分比数据的值。例如,95%的响应时间是在多少毫秒以内?
我们通常使用中位数来描述数据集的位置。中位数将数据分成相等的两部分。但是,有时候中位数会误导我们,因为它没有考虑样本数据的变异性。例如,当我们观察一个极其极端的值时,这个值可能会偏移中位数,导致数据更难解释和预测。
因此,引入了百分位数的概念。
例如,50%百分位数就等价于中位数。如果响应时间的50%百分位数为1秒,则表示50%的请求响应时间小于等于1秒,另外50%的请求响应时间大于1秒。
常见的百分位数如下:
- 90%:表示有90%的数据小于等于它,10%的数据大于它
- 95%:表示有95%的数据小于等于它,5%的数据大于它
- 99%:表示有99%的数据小于等于它,1%的数据大于它
- 99.9%:表示有99.9%的数据小于等于它,0.1%的数据大于它
根据我们的要求,我们可以选择不同的百分位数来观察系统性能表现。
如何计算百分位数?
计算百分位数的具体方法有很多种,下面介绍其中两种应用广泛的算法。
算法1:最简单的计算方法
这种方法最简单,但是它需要有序的数据。
例如,观察以下20组响应时间数据:
355, 528, 462, 501, 615, 940, 378, 464, 256, 275, 620, 917, 899, 893, 936, 932, 128, 315, 897, 735
为了计算50%的百分位数,需要首先将数据排序:
128, 256, 275, 315, 355, 378, 462, 464, 501, 528, 615, 735, 899, 893, 917, 932, 936, 940, 897, 620
然后查找数据在数组中的位置(在Python中是索引):
n = 20 * 50 / 100
i = int(n + 0.5)
print(i) # 输出10
数组data的第10个值为528。因此,50%的百分位数为528。
对于其他的百分位数,只需要更改百分数即可。
算法2:快速计算方法
如果我们没有有序数据,那么算法1就会变得很慢。此时可以使用在线计算百分位数的算法。其中一种广泛应用的算法是TDigest算法。
我们可以通过使用PyTDigest库轻松实现TDigest算法。下面是一个示例:
import numpy as np
from pytdigest import TDigest
data = np.random.randint(100, size=100000)
t_d = TDigest()
for value in data:
t_d.update(value)
print(t_d.percentile(50)) # 输出50%的百分位数
PyTDigest库的更新方法不断将新值添加到TDigest实例中。最后,我们可以使用percentile方法获取所需的百分位数。在上面的示例中,我们计算了50%的百分位数。
选择正确的百分位数
我们应该选择哪个百分位数来评估监控数据密集型系统的性能呢?
这取决于我们想要衡量的是响应时间还是吞吐量。如果我们想要最大限度地减少响应时间,我们可能更关心较小的百分位数(例如90%,95%)。如果我们想要最大限度地提高吞吐量,我们可能更关心高百分位数(例如99%)。
然而,在选择百分位数时,我们应该保持一致性。如果我们在某个时间段中关注95%的百分位数,请确保在下一个时间段中继续关注95%的百分位数,以获得一致和可比较的结果。
结论
本文介绍了如何计算监控数据密集型系统的百分位数,以便更好地了解系统的性能表现,预测其可能的瓶颈并优化其性能。我们覆盖了两种计算百分位数的算法,并提供了选择正确百分位数的一些指导性建议。
极客笔记