我因一次本可挺过的崩溃损失了一周
我曾经因为一次崩溃,损失了将近一整周的工作成果。倒不是因为这次崩溃本身有多么罕见、多么灾难性——它只是一次普普通通、平淡无奇的中断,那种随时都可能发生的小事。我之所以损失了一周,是因为我在整个过程中什么都没有保存。于是一次在临近结束前几分钟突然袭来的中断,抹掉了好几天累积下来的进度,而我无从找回其中任何一点。它就这么没了,而且自始至终它都处在随时可能丢失的状态,只是我从未察觉。
事后回想,最让人难受的,恰恰是这一切本来有多么容易避免。崩溃并没有毁掉我的工作。是我没能让自己的工作变得可以幸存,才毁掉了它。
“它会顺利跑完”的悄然乐观
我把那些长时间运行的进程,构建得仿佛它们每一次都会从头到尾干干净净地跑完、绝不中断。没有保存任何中间状态。没有任何办法从中途恢复。只是启动它,让它跑,然后默认它会一直跑到终点。如果你当面问我,这个假设是否安全,我会回答不安全。但我从来没问过自己,于是我就一直在这个假设之上继续搭建。
这是一种普遍存在却几乎隐形的乐观:悄悄地认定顺利路径就是唯一的路径。你为那个一切顺遂的世界做设计,因为在你搭建的时候,脑海里想象的正是那个世界。然后你把它发布到真实的世界里,而真实世界有许许多多别的路径,其中大多数都没那么令人愉快。
任何运行得足够久的东西,终将被中断
这就是我一直拒绝纳入规划的那条真相。任何运行得足够久的进程,迟早都会被中断。一次崩溃。一次电源闪断。一台内存耗尽的机器。我自己的一个失误。一次等不了的重启。具体是什么原因并不重要,而且原因多得你根本数不过来。
在很短的时间窗口里,中断是一种风险。但在足够长的时间跨度上,它就不再是风险,而是变成了一种必然。问题不在于一个长时间运行的东西会不会被中断,而只在于何时、以及多频繁地被中断。一旦你这样看待它,那种”假设它不会发生”的设计方式便露出了真面目:那是在蓄意地、为一件注定会发生的事做出错误的规划。
代价由你保存了什么决定,而不是由崩溃决定
正是这个洞见,重新组织了我对这一切的思考。一次中断造成的损失,几乎完全取决于你的工作有多可恢复——而不是取决于中断有多严重。崩溃很少是那个起决定作用的变量。真正起作用的,是你事先做了什么。
完全相同的一次崩溃,在完全相同的时刻袭来,如果你刚刚保存过进度,它只让你损失五分钟;如果你什么都没保存,它就让你损失五天。两种情况下的中断是一模一样的。后果却天差地别,而这差别完全由你更早时候做出的一个选择决定——早在崩溃到来之前。崩溃并不决定你损失多少。是你决定的,提前决定的,通过你决定愿意让多少东西变得可恢复。
设置检查点是算术,不是疑神疑鬼
一旦我这样去框定它,定期保存中间状态这件事,就不再像是过度谨慎,而开始像是一道简单的算术题。中断在时间维度上是确定的。它发生时的代价,被你上一次保存距今多久所限定。所以频繁保存,不过是为一件注定会发生的事买一份便宜的保险,而这份保费的高低,你想压多低就能压多低——只要稍微多保存几次就行。
拒绝这样做,不是勇敢,不是专注,也不是高效推进。它只是糟糕的数学——为了眼下一点点便利,拒绝一份廉价的保护,去对抗一件确凿无疑会发生的事。我曾一直为自己”没把时间浪费在安全网上”而沾沾自喜,却在不知不觉中,对一件根本毫无悬念的事,承担着一笔巨大而毫无保障的风险。
为恢复而设计,而不仅仅是为重启而设计
不过,在定期保存之上还有一个层次,而它才是最要紧的那个。更深一层的修复,是把长时间运行的工作构建成:一次中断之后能从它停下的地方继续,而不是从头开始重来。
当中断频繁发生时,这个区别就是一切。一个每次被打倒就从零重启的进程,在足够恶劣的环境里,可能永远也跑不完——每一次中断都抹掉一切,而如果中断相对于运行时长来得足够频繁,那么无论你多么拼命,净进度都是零。相比之下,一个能够恢复的进程,永远在向前推进。它可以被一次又一次地打倒,却终究还是会抵达,因为每一次中断只让它损失上次保存以来的那一点点。重启的脆弱会层层累积;恢复的稳健则朝相反的方向层层累积。
几乎处处适用的同一条原则
这条原则远不止适用于某一次长时间运行的计算。它适用于几乎任何价值随时间累积、且不刻意保存就会丢失的工作。模式都是一样的:进度不断累积,一次中断到来,凡是没被做成持久的东西,统统消失。
于是,对于任何耗时且重要的事情,我学会去问的那个问题,不再是那个让人安心的版本——“万一这被中断了怎么办?“——那种被当作假设、远远拿在手臂之外掂量的问法。它变成了那个直白的、默认它一定会发生的版本:“当这被中断时,我会损失多少?“这个问题,早早问出来,会改变你所构建的东西。第一个问题让你心存侥幸。第二个问题逼你做好准备。
更深的教训:中断是一件早有日程的事
这一切归根结底是:我不再为那个一切顺遂的世界做设计,而开始为那个事情会例行出错的世界做设计——因为后者才是真正存在的世界,而前者从来都不过是我悄悄拿来替代现实的一个怡人假设罢了。
我后来明白,韧性不是悲观。它是准确。中断并不是一个遥远的、可以乐观地打折扣的假设。它实际上是一件早有日程的事——只不过没人告诉你日期而已。把它当作必将到来去构建,并不阴郁,也不胆怯。它只是诚实地面对那个唯一可供你构建的世界。我损失了一周,才学会:崩溃从来都不是问题所在。问题在于,在一个被中断已成必然的世界里,我构建了一个根本没有办法在被中断后幸存下来的东西。
— 不荐信号,不保收益,非投资建议。