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

资本市场与清结算

一句“很慢”的报告,没有可修的地方

在 TT Lab 中继续学习

一句话总结

订单经过的每一处都要打上时间戳,才能说出是哪个区段慢。而且,如果区段的两端是不同的机器,这个差值里就会原样混入两台机器的时钟误差。

为什么需要它

收到“订单很慢”的反馈时,一开始无事可做。因为不知道是什么慢。是网关慢,是风险检查耗时太长,是线路堵了,还是交易所接收得晚——候选有四个,而要去修的团队,四个各不相同。在这种状态下开会,每个团队都会说自己的区段没问题,没有人说错话,却什么也没有得到修复。

所以最先要做的,是给路径量尺寸。确定一笔订单在我们内部经过的位置,并在每个位置留下时间。接收、风险检查完成、会话编码完成、线路发送、交易所接收、收到 ack。定下六个位置,就有了五个区段,从那时起,“慢”就变成了“这个区段慢了这么多”。一旦变成这样,要去修的团队也就确定了。

工作原理

区段延迟就是用后面的时间减去前面的时间。看起来很简单,但这里有一个陷阱。这两个时间是不是同一台机器打的,会改变值的含义。

如果是同一台机器内的两个时间,那么这个差值几乎与这台机器的时钟有多准无关。时钟即使快了 3 毫秒,两个时间都快了 3 毫秒,相减就消失了。所以同一台机器内的区段是可以信任的,在这里使用 单调时钟 更好。墙上时钟在时间同步校正进来时可能倒退,而单调时钟不会倒退。

反过来,两端是不同机器的区段,两台机器的时钟误差会原样进入。我们的网关通过线路发出的时间,与交易所打下的接收时间之差,是真实的线路时间再加上两个时钟之差。如果交易所的时钟落后于我们,这个值就会是负数。这并不意味着跑得比光还快,而是尺子不准。

但往返是会抵消的。线路发送时间和收到 ack 的时间,都是我们的机器打下的。虽然在这期间订单去了一趟交易所,但两个时间出自同一个时钟,所以无论交易所的时钟错了多少,都不会进入差值。单程被污染而往返是干净的,这种性质也是 RFC 5905 的时间同步测量偏移量的方式的基础。所以,要看单程区段,就必须取得偏移量报告来校正,而校正之后仍然留下负数的区段,才是真正的缺陷。这里常见的失误在另一边。一旦某个区段整个是负数,就把它统统归为“全是时钟的错”,结果混在其中的那个真正的一笔,就这样消失了。

汇总之后,不要看平均值。延迟分布向一侧拖着长长的尾巴,所以平均值会被少数很慢的笔拽着走。要看的是百分位数。不过,重要的是,百分位数有多种定义。排序后直接取那个位置的值的方式,与在两个值之间插值的方式,对同样的数据会得出不同的数字。statistics 模块 的说明中也写了多种方式。如果我们的仪表板与对方的合同使用不同的定义,针对同一条线路,一方会说违约,另一方则说没有。所以要把定义写在数据旁边,并原样实现它。

而且,各区段的百分位数无法解释整体的尾部。如果为每个区段求 p99,通常线路区段最大。可是,如果挑出整体延迟最差的前 1% 的订单,数一数这些订单中最大的区段,有时会出现别的区段。各区段的 p99,在每个区段看的是不同的订单,而整体尾部看的是一笔订单内部是什么大。两个问题不同,所以答案也不同。决定修哪里的,是后一个。

最后是延迟预算。给每个区段定一个上限,统计超出的笔数。预算的值不是喜好,而是决定。定得宽松,只有反常的才会被抓到,收紧了,连正常波动也会被抓到,告警会变成一天几千条。到了那一步,没有人再去看那些告警,所以预算要做出两套,实际数一数超出的笔数,再来确定。

在现场相遇的样子

有一次,因为线路区段的结果是负数,那个区段的测量被整个丢弃了。几个月后,在与交易所谈论响应时间时,我们手里没有那个区段的数字。其实只要拿到偏移量报告减一下就行,看到负数的人判断“测量坏了”,把它从仪表板上删除,仅此而已。

还有一次,因为线路区段的 p99 最大,所以决定扩容线路。扩容之后,关于订单很慢的反馈并没有减少。重新打开最慢的那些订单,发现这些订单中最大的区段不是线路,而是风险检查与编码之间的等待,而且只在特定的时间段出现。这是把各区段的 p99 与整体尾部当成同一个问题所付出的代价。

下一项实验要做什么

把 1500 笔订单的区段时间戳、各主机的时钟偏移量报告、两套延迟预算和百分位数定义做成数据。计算区段延迟,找出出现负数的位置,用偏移量校正,把时钟误差与真正的缺陷区分开。然后分别统计各区段的百分位数,与造成整体尾部的区段,确认两者不同,并比较两套预算的超出笔数。最后,把哪个区段从第几分钟开始变差,与根据数据排除的假设,一并写下来。