IT 论文精读 · PAPER 71

Pivot Tracing(动态因果监控)

Mace, Roelke, Fonseca · Brown University · SOSP 2015(最佳论文)

EN →

这篇论文干了什么?

你打开一个 app,它今天特别卡。工程师想弄明白为什么,能翻的只有日志——程序顺手记下的流水账。麻烦在于:流水账记的是当初写代码的人想到要记的东西,你现在想问的那件事,多半不在里面。

2015 年布朗大学的三个人提出 Pivot Tracing,把这件事反了过来:你可以对着一个正在运行、不能停机的系统当场提问,几秒后答案就流回来,问完撤掉。而且它能问出一类以前谁也答不了的问题——比如「机房这块硬盘此刻被谁吃掉了」。

先说个怪事

一个大系统是很多层叠起来的:最上面是用户的任务,中间是数据库,最下面是存储。现在存储层的磁盘被榨干了,大家都在排队。你问:到底是谁干的?结果所有人都答不上来。存储层只知道「是数据库来读的」;数据库只知道「是某个任务让我读的」;那个任务只知道自己交了活儿。每一层都只认得自己的上一站。

就像快递中转站只知道包裹来自上一站,问它「是哪个买家下的单」——它是真不知道。要命的是,答案并非不存在,而是被切碎分散在几个系统里,谁手上都不全。

那个点子

旧世界的规矩是:你必须在写代码时就想好日后要查什么。想得到,事后能查;想不到,就得改代码、重新上线、干等它再犯一次——生产事故往往就这样错过。Pivot Tracing 换了个规矩:先别记,等你想问的时候再问。

它怎么做到的

第一件事:探头是临时装的。程序跑着的时候被就地改写,探头装上去、用完撤掉——像给正在营业的店临时挂个计数器,不用打烊装修。

第二件事,也是真正的新东西:让信息跟着请求走。给每个请求配一个随身小背包。它经过上层时,上层把「我是谁、我为谁跑这一趟」写进背包;一路穿过各种转手,到了最底层的存储,那里的探头打开背包就看见了来路,于是「这次读了多少字节」和「这是谁点的」当场对上号。

比喻是医院:病人自己带着病历本走,抽血处不必跑回挂号处查这人是谁。关键在于配对的依据不是时间——同一毫秒里全机房有上万件事,按时间猜必然猜错——而是「它俩本就在同一趟旅程上,一个在前、一个在后」。

还有一点让它便宜:背包里不塞流水账,只塞一句「这一趟属于某某任务」,剩下的边走边算,到底层算完只把结果发出去。代价也实打实:这一套要求沿途每个组件都老实地把背包传下去,中间有一环弄丢了,那条线就在那儿断掉。

带来了什么

它把「监控」的问法改了:从「上线前决定记什么」,变成「想问就问」。今天大家挂在嘴边的「可观测性」,衡量标准正是这一条——能不能回答一个事先没想到的问题。而那个「随身背包」,如今以 baggage 之名写进了主流追踪标准的接口。

一句话记住

给每个请求配一个随身背包,让上层把「我是谁」写进去、底层打开就能对上号——于是「这块盘现在被谁吃掉了」这种跨系统的问题第一次有了答案;再加上探头能对着运行中的系统随装随撤,监控就从「事前记账」变成了「事后提问」。

想看它的因果连接算子、查询怎么编译成探头、以及实测开销? → 切到精读版