TT Lab
开始
学习 学习路径 课程

Grafana — 仪表盘是一个问题

折线图接不住排名类的问题

在 TT Lab 中继续学习

一句话总结

“哪个最糟糕”是在问排名,而排名是折线图回答不了的。表格和转换(transformation)就是接住这个问题的工具。

为什么需要它

故障会议上最常出现的问题,是两个中的一个:“从什么时候开始这样的”和“哪个最糟糕”。前一个问的是随时间的变化,后一个问的是某一时刻的列表。但仪表板往往被做成只能回答前一个问题的形式。

假设把四个处理器的 p95 叠在一个面板里绘制。如果数值彼此接近,比如 0.216、0.219、0.229、0.233,四条线就会一直缠在一起。要判断哪条线是哪个处理器,得到图例里找颜色对上;要知道排名,得把鼠标停在某一时刻读出四个值,再在脑子里排序。变成八个的时候,没有人会去做这件事,只会说一句“看起来都差不多”就过去了。

这不是绘图偏好的问题,而是问题的形状与答案的形状不匹配。问排名的问题,答案是排好序的列表,而展示排好序的列表的形式,就是表格。

工作原理

在 Grafana 中把时间序列转成表格,分为三层。第一是查询。同样的 PromQL,如果以瞬时值查询(instant)发出,每个序列返回一个值;如果以区间查询(range)发出,每个序列会返回几十到几百个点。Prometheus 数据源的查询编辑器中,有选择这两者的位置,也有选择以什么形式接收结果的位置(Prometheus 查询编辑器文档)。在仪表板 JSON 中,每个查询都以 instant 和 format 两个键保留下来。

如果把区间查询原样灌进表格,行数就是序列数乘以点的数量。看四个序列、两个小时、每 60 秒一个点,就是 4 乘以 121,484 行。没有人能读。所以需要第二层——转换。

转换 做什么 在表格中的效果
reduce 把一个序列压缩成一个数字 484 行变成 4 行
organize 隐藏列、重命名、确定顺序 Field 变成 핸들러
joinByField 按公共列把两个查询的结果拼在一起 延迟和请求率出现在同一行

reduce 会生成“每个序列一个数字”。选最后一个值是“当前”,选最大值是“这个区间的最坏情况”。第三层是显示。表格的单元格可以加上颜色或条形(表格可视化文档),这里有一条规则:颜色只加在带有阈值的数字列上。如果连处理器名称这一列都涂上颜色,颜色就成了没有任何意义的装饰,其他地方真正的红色也随之失去了力量。所以颜色不是作为面板默认值,而是作为指明这一列的覆盖(override)来添加。

把两个查询拼进一个表格,也经常需要。“慢的处理器是不是也接收了更多流量”,只靠延迟,或者只靠请求率,都回答不了。必须按处理器名称把两者拼接,放在同一行,眼睛才终于看到两者的关系。

在现场相遇的样子

支付团队的状态仪表板上,十二个端点的 p99 叠在一个面板里。出了事故,人们打开那个面板,只说得出“好像有什么升上去了”。每次要弄清是哪个端点,都要花 3 分钟。把同一个查询改成瞬时值,转成表格,并按 p99 降序排好之后,在下一次事故中,打开界面 5 秒钟就得到了名称。查询一个字符也没有改。

也有反方向的错误。如果把像总请求率这样询问随时间变化的面板也改成表格,就更糟了。只靠一个数字,无法知道是否和昨天一样。该改成表格的,只有询问排名的面板。

本环境能判定与不能判定的内容

转换是在浏览器中计算的,而不是在服务器上。所以在这个 Pod 中,没有办法看到应用了转换的表格实际是什么样子。也没有图像渲染器插件。取而代之的是,判定分两部分进行——仪表板 JSON 模型中写下的 transformations、type、options,以及查询的 instant、format,还有用数据源把该查询实际发出后得到的值。列宽和颜色在眼睛看来是什么样子,最终还是要通过网页预览打开 3000 端口看一次。

下一项实验要做什么

先亲自尝试在折线图上读出排名——固定一个已经过去的时刻,把四个处理器的 p95 按降序写下来,就会用数字显示出,为什么这件事靠眼睛做不到。接着把同样的问题迁移到表格中,量出区间查询在表格里变成多少行,再用 reduce 压缩,用 organize 整理列。用 joinByField 把两个查询拼接放进一个表格,颜色只以覆盖的方式加在带有阈值的一个列上。最后,把仍然保留为折线图的排名面板亲手改成表格并提交。