为什么Prometheus不适合高基数数据?

98次阅读
没有评论

问题描述

在使用Prometheus时,对于高基数数据为什么不适合使用Prometheus感到困惑。他想知道为什么需要使用低基数数据,这与SQL数据库的情况恰恰相反。他想了解这背后的技术原因。

解决方案

请注意以下操作注意版本差异及修改前做好备份。

方案1

据我所知,Prometheus并不介意高基数的数据。Prometheus不喜欢的是高基数的标签。
让我们从Prometheus官方文档开始,它给出了一个很好的高层次解释:

注意:请记住,每个键值标签对的唯一组合都代表一个新的时间序列,这可能会大大增加存储的数据量。不要使用标签来存储具有高基数(许多不同标签值)的维度,例如用户ID、电子邮件地址或其他无界值集。
官方文档链接

重要的部分是,Prometheus中的唯一键值组合会创建新的时间序列。
例如,如果你存储一个记录用户完成注册表单所花费时间的仪表盘类型指标registration_complete,Prometheus不会有任何问题。你将有一个时间序列,其中包含数十万个值:每个注册的用户都有一个值(花费的时间)。你可以随时间绘制该指标,获取p95等等。

如果你想为其添加一些基数,可以添加一个标签,比如region:US-east、Asia-Pacific等。你可以绘制所有地区并进行比较,或者将它们分组。地区的数量可能很低(<10),而且肯定是有限的。如果在AWS上,地区的数量是固定的,并且随时间变化不大。当然,AWS可能会添加、删除或重命名一个地区,但这不是每分钟都在变化,也不会有成千上万个地区。

所以回到Prometheus不建议的事情:你不应该创建高基数的标签。你不应该为你的registration_complete指标添加一个user_id标签。如果这样做,你将有数十万个不同的时间序列,每个用户一个!而且它们都只有一个数据点。这真的是最糟糕的情况。

在这种情况下,为了在所有标签上绘制registration_complete指标,Prometheus将不得不查询所有单独的时间序列(成千上万个)并对它们进行聚合。

你说你来自SQL背景,所以我会尝试一个类比。在Prometheus中,唯一键值标签对创建新的时间序列相当于在SQL中创建单独的表。拥有一个user_id标签等于每个user_id拥有一个表。

注意:并非所有的TSDB都以相同的方式工作,我无法代表所有TSDB发表意见。

正文完