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

数据流水线

被隔离的行最后去了哪里

在 TT Lab 中继续学习

一句话总结

隔离是不丢弃行的机制,它本身并不是解决办法。如果没有修正后重新放回去的闭环,也没有盯着存龄的眼睛,隔离就会变成一个没人打开的抽屉。

为什么需要它

加上了质量检查。不能用的行不丢弃,而是连同原因一起留在隔离表里。到这一步通常都会做。

半年后打开那张表,里面有 4 万行。原因有六种,其中一种占了 3 万行,而这 3 万行全部是同一天上游搬动了一个字段造成的。从那天起就没有人看过这张表。在此期间,销售汇总一直少了 3 万条在往外发,仪表板始终是绿灯。

这里暴露出来的是:运行状态和数据状态是不同的两条轴。管道每天都成功了。成功是指“没有报错就结束了”,并不是“该放进去的都放进去了”。如果把这两件事混在一栏里汇报,两件事就都看不见。

本课程与 fde-data 的分野

fde-data 的 CSV 实验,做到的是把客户给的一个文件里不能用的行剥离出来,留成拒绝文件。那个文件只来一次,拒绝列表发给客户就结束了。本课程讲的是每天运行的管道,所以不会到此为止——隔离会在每次运行中重新堆积,昨天隔离的行今天又来了,而有人把它修好放回去的话,这一行可能被算两次。一次性拆开处理和持续运转,设计是不同的。

把期望写成文件,而不是代码

期望(expectation)是把“这份数据如果是对的,就应该这样”写下来。如果用条件语句散落在代码里,就没有人知道到底在看什么。如果在一个文件里以列表的形式写下来,有三点会不同——可以拿着这个文件和上游谈,规则增加时代码不用改,而违反的规则的名字就成为隔离原因。

{"rules": [
  {"name": "order_id_format", "column": "order_id", "type": "regex",
   "pattern": "^ORD-[0-9]{6}$"},
  {"name": "qty_range", "column": "qty", "type": "range", "min": 1, "max": 50},
  {"name": "status_enum", "column": "status", "type": "enum",
   "values": ["NEW", "PAID", "CANCELLED"]}
]}

如果把原因设为规则名,“为什么被隔离”就不再是一句自由文本,而成为可以计数的值。能计数,才能按原因看各有多少条,并看出哪个原因在增加。

阈值按什么来定

一行出错和整个文件出错是不同的事件。前者用行级隔离处理,后者用运行级中断(circuit break)处理。上游把列顺序换了再发来时,几乎每一行都会错位,这时如果按行隔离,隔离表里会进去一万行,汇总则是空的。这样的文件,一行都不放进去更好。

划分的依据是比例。而且这个比例要从平时的值来定。如果先定下“5%”这种整数,就会变成二选一——在平时是 7% 的数据上每天都会中断,在平时是 0.1% 的数据上,坏了 20 倍也不会中断。要先测出最近几次运行的失败比例,在其之上留出余量。阈值因数据而异,所以要按数据分别写下来。

中断的时候,什么都不放进去。放进一半就停下的话,下一个人就得判断放到了哪里,而这个判断迟早会错。

重新放回的闭环与重复计算

被隔离的行,要修好重新放回去,才算真正结束。这里有两处容易出问题。

第一,在事实(fact)表里进去了两次。把修好的行直接 INSERT,原来的行和修好的行就会同时保留。如果给自然键加上唯一约束,再以更新的方式放入,这个问题就消失了。

第二,把隔离关闭了两次。同样的修正运行两次,就会再次关闭已经关闭的隔离,“这次解决了 3 条”就被报告两次。关闭的时候只关闭仍然处于打开状态的,第二次运行就会是 0 条。重新放回一定会运行多次——因为那是由人手动来跑的。

还有无法修好的隔离。键本身坏掉的行就是这样。如果单据号因为不符合规格而被隔离,一旦修改号码,它就变成另一行了。这种不应该重新放回,而要退回给上游。

给存龄较大的隔离挂上告警

隔离堆积是正常的。问题是不减少。所以不看“隔离了多少条”,而看“最久的隔离是第几次运行的”。

存龄用运行次数而不是时间来量更好处理。在一天运行一次的管道里,“超过 3 次的隔离”意味着三天;而部署停了、管道没运行的话,存龄也不增加——这样更符合人的感觉。

在现场相遇的样子

实际工作中真正重要的事

下一项实验要做什么

把期望写成文件,再一步步扩充守卫 qgate.py。先做出只计数的 check,在 sqlite 中把事实和隔离分开堆积,让错得太多的运行整体中断,把修好的行重新放回去,并且放两次数字也不变,找出存龄大的隔离,把运行状态和数据状态分开汇报。评分器每次都会用不同的阈值和不同的店铺名生成自己的投放文件和期望,真正运行你的守卫,并直接打开数据库,数一数事实和隔离放得对不对。