“裴衍之。”程司白开口了,声音比刚才在会议上低了一些,“你为什么坚持用Paxos?”
“因为它成熟。”
“你知道我不是问这个。”程司白转过身,面对他,“你知道Paxos在边缘场景有问题。你在方案文档里写了,在附录C里承认了这个问题。但你还是坚持用它。为什么?”
裴衍之沉默了一会儿。
窗外有鸟叫声,很远,断断续续的,像一段信号不稳定的广播。
“你为什么非要Raft?”他没有回答她的问题,而是反问了一句,“你明明知道Raft在网络不稳定的情况下会有频繁的领导者选举。你为什么非要选它?”
“因为它的性能更好。”
“你也不是在说性能。”裴衍之的声音忽然变得很轻,轻到像是在自言自语,“你只是想证明自己。”
程司白的手指在窗台上敲了一下。
“证明什么?”
“证明你这三年没有白过。”裴衍之看著她,目光平静,平静得像一面没有波澜的湖,“证明你离开我是对的。证明你一个人可以做得更好。”
会议室里安静了很久。
程司白没有否认。她也没有承认。她只是站在那里,手指按在窗台上,指尖因为用力而微微发白。
“两周之后见分晓。”她说完这句话,拿起笔记本和电脑,推开会议室的门走了出去。
走廊里很安静,她的脚步声又一次在大理石地面上响起,一二一二,像一段稳定的时钟信号。
但这一次,节奏乱了一拍。
只有一拍。然后她又恢复了原来的步频。
何悦在茶水间门口探头,看到她走过来,缩回去假装在倒水。程司白经过的时候没有看她,径直走向自己的工位。
她坐下来,打开电脑,萤幕上还是那份简报。
第三页,网络抖动模拟图。
她盯著那张图看了很久。
“你只是想证明自己。”
这句话在她脑子里转了一圈又一圈,像一个死循环,跳不出来。
她不知道他说得对不对。
她只知道,两周之后,她要让数据说话。
这是她唯一相信的东西。
程司白在工位上坐了四十分钟,一个字都没写。
萤幕上还是那份简报,第三页的网络抖动模拟图,蓝色的曲线在坐标轴上波动,像一条不安分的心电图。她的手指放在键盘上,但脑子里反反复复转著同一句话。
你只是想证明自己。
她觉得被冒犯了。
不是因为他说错了,是因为他凭什么这么说。三年没见,第一次正式合作会议,他就在七个人面前说她只是想证明自己。好像她这三年做的所有事情——读完硕士、考下架构师认证、从工程师做到Team Leader、主导了三个成功的项目——都只是为了证明她离开他是对的。
荒谬。
她用力敲了一下键盘,打出了一行乱码,又删掉。
何悦从茶水间走出来,手里端著一杯热茶,经过她工位的时候放慢了脚步。程司白感觉到有人在旁边停下来,没有抬头。
“程姐,你还好吗?”
“没事。”
“你刚才开会的时候好厉害。”何悦把茶放在她桌上,“裴哥都被你说愣住了。”
程司白看了一眼那杯茶,菊花枸杞,何悦每次觉得她压力大的时候都会泡这个。“不用,你喝吧。”
“我泡了两杯。”何悦拉过旁边的椅子坐下,喝了一口自己的茶,眼睛时不时瞟过程司白的脸,像一只试探著要不要靠近的猫。
程司白知道她想说什么。何悦这个人,每次要说重要的事情之前都会先喝一口水,然后沉默五秒。现在她已经喝了三口茶了,沉默了大概十五秒,说明她接下来要说的事情很重要。
“程姐,我跟你说个事,你别说是我告诉你的。”
程司白终于转头看她。“什么事?”
何悦压低了声音,凑过来。“今天下午我跟唐总汇报工作的时候,听到他打电话。好像是打给裴哥以前的同事,问了一些裴哥以前的事。”
程司白的手指在键盘上停了一下。“然后呢?”
“然后唐总挂了电话之后自言自语了一句话。他说——”何悦顿了一下,又喝了一口茶,“他说“这小子当年连共识两个字都不敢写,现在倒是敢跟程司白拍桌子了”。”
会议室的冷气好像又吹过来了。
程司白觉得自己的手指有点凉。她把手指从键盘上收回来,放在膝盖上。
“什么意思?”她问。声音比她自己预期中要轻。
何悦摇了摇头。“我也不太清楚。好像是说裴哥当年离职之后,有一段时间写程式码从来不用“共识”这个词。不是故意的,就是打不出来。唐总说他见过一次,裴哥对著萤幕发呆了十几分钟,最后把“共识算法”改成了“一致性协议”。”
程司白没有说话。
窗外有鸟叫声,很远,断断续续的。阳光透过百叶窗照进来,在她桌上投下一条一条的光影。她看著那些光影,觉得它们像某种编码,某种她读不懂的语言。
“程姐?”何悦小心翼翼地叫她。
“嗯。”
“你跟裴哥……真的只是不熟吗?”
程司白沉默了三秒。“不熟。”
何悦看了她一眼,没有再问。她把茶杯端起来,站起来走了。走了几步又回头说了一句:“程姐,那杯茶你记得喝,凉了就不好喝了。”
茶水间的门关上了。
程司白坐在位置上,看著那杯菊花枸杞茶。热气从杯口升起来,在空气中散开,消失。她伸手碰了一下杯壁,温的,不烫。
她把手收回来。
打开抽屉,拿出那部旧手机,按了一下电源键。萤幕亮起来,还是那张照片,还是那个笑容。她盯著那张照片看了大概十秒,然后关掉,把手机放回去。
抽屉关上的时候,她听到自己的心跳声。
不是很快,但很重。一下一下的,像有人在胸口捶门。
她不想去想何悦说的话。
她不想去想裴衍之为什么不敢写“共识”两个字。
她不想去想他对著萤幕发呆的十几分钟里在想什么。
她不想去想这些,因为想了就会心软。心软是最大的弱点。她不需要弱点。
她打开文档,找到那封已经写好的邮件。
收件人:唐嘉树。
主旨:关于项目合作人更换的申请。
内容很简短。她写这封邮件的时候觉得很有道理——她和裴衍之没办法合作,与其两周之后因为技术分歧再次吵起来,不如现在就申请更换合作人。唐嘉树会理解的,他是技术总监,他知道什么对项目最好。
她看著这封邮件,手指放在滑鼠上,游标停在“发送”按钮上方。
只需要点一下。
她就可以不用再跟他开会,不用再听他说“你只是想证明自己”,不用再在电梯里说“好久不见”。
只需要点一下。
她没有点。
她关掉了邮件。
不是因为她想跟他合作。是因为她不想让唐嘉树觉得她连这点事情都处理不了。她是架构组的负责人,她不能因为私人原因影响工作。就这么简单。
她把萤幕上的简报关掉,打开测试环境的程式码编辑器,开始写Raft变体算法的性能测试脚本。键盘的声音在安静的办公区里响起来,哒哒哒哒,节奏稳定,像一段没有感情的程式码。
她写了一个小时,两个小时,三个小时。窗外的光线从白色变成橘黄色,再变成深蓝色。办公区里的人一个一个走了,灯一盏一盏暗了。她没有注意到。
她只注意到程式码。
测试脚本、边缘场景、并发模拟、故障注入。她把每一个参数都设到最极端,把每一个条件都推到边界,把每一种可能失败的情况都列出来。她要证明Raft变体是稳定的,她要证明她的方案比他的好,她要证明——
证明什么?
她的手指停了下来。
萤幕上是一段刚刚写完的代码,注释里写著一行字:“// 边缘场景测试:网络分区 领导者崩溃 日志不一致”
她盯著这行注释,忽然想起他今天在会议室里说的话。
“你只是想证明自己。”
她用力敲了一下删除键,把那行注释删掉了。
墙上的时钟指向十一点二十三分。办公区里只剩下她一个人,空调的嗡嗡声在寂静中被放大了无数倍。她站起来,想去茶水间倒杯水,经过走廊的时候看到对面的办公区域灯还亮著。
业务中台的办公区域。
隔著一面玻璃墙,她看到裴衍之坐在工位上,萤幕亮著,他在看什么东西。他的姿势和下午一模一样,连杯子放的位置都没有变。他好像一直没有离开过。
程司白站在走廊上,隔著玻璃墙看著他。
他没有发现她。他正盯著萤幕,眉头微微皱著,右手拇指按在键盘边缘——那是他思考时的小动作。他面前的文件夹还是鼓鼓的,但里面的纸好像少了一些,大概是被他抽出来反复看过了。
她站在那里看了大概三十秒。
然后转身走向茶水间。
倒水的时候她听到走廊上有脚步声。很轻,很稳,每一步的间隔都很均匀。她没有回头,但她知道是他。
脚步声在茶水间门口停了一下,然后继续往前走,越来越远。
她端著水杯回到工位的时候,走廊上已经没有人了。对面的灯还亮著,但他不在座位上了。
她坐下来,打开测试脚本继续写。
凌晨一点十七分,她把第一轮测试跑完了。结果比她预期中好——即使在最极端的网络条件下,Raft变体的吞吐量仍然保持在Paxos方案的百分之一百一十以上。她看著萤幕上的数据,没有高兴,也没有不高兴。只是觉得累。
一种从骨头里渗出来的、怎么睡都补不回来的累。
她趴在桌上,想闭一会儿眼睛。
手机震了一下。
她拿起来看。
屏幕上显示一个没有备注名的号码。但她认得那串数字。三年了,她换过两次手机,但这个号码一直没有删。不是刻意留著,是忘记了。对,是忘记了。
她点开消息。
“不是要证明自己。是我怕你的方案出问题,你又会像三年前一样,把所有责任扛在自己身上。”
她盯著这行字看了很久。
久到萤幕自动暗了,她又点亮,又暗了,又点亮。反反复复,像一个跳不出来的循环。
窗外的城市灯光在玻璃上晕开,变成一片模糊的光斑。办公区里只有她萤幕的光,照在她的脸上,把她的表情照得一片空白。
她想起三年前那个凌晨。
那是他们在一起之后第一次出故障。系统在凌晨两点崩了,她负责的架构层出了问题。她一个人通宵排查,找到Bug之后自己修、自己测、自己部署。裴衍之第二天早上来公司的时候,她已经把问题解决了,正趴在桌上睡觉。
他没有叫醒她。他把自己的外套盖在她身上,然后去看了她的程式码。看完之后他跟她说了一句话。
“你以后能不能不要一个人扛?你可以叫我一起。”
她说:“不用。我能处理。”
他没有再说什么。
后来又出了几次故障,每一次她都是一个人通宵,一个人解决。他每次都说“你可以叫我”,她每次都说“不用”。到最后他不再说了,只是在第二天早上给她带一杯咖啡,放在桌上,然后安静地走开。
她以为他理解了。
她以为他接受了她就是这样的人。
现在她才知道,他不是理解了,他是一直在等。
等她有一天会说“好”。
她把手机放在桌上,萤幕朝上。那条消息还亮著,每一个字都很清楚。
“我怕你的方案出问题,你又会像三年前一样,把所有责任扛在自己身上。”
她看了十分钟。
没有回复。
她把手机翻过去,萤幕朝下扣在桌上。然后打开电脑,找到那封写给唐嘉树的邮件草稿。
收件人:唐嘉树。
主旨:关于项目合作人更换的申请。
她把滑鼠移到草稿文件夹上,点了一下。
对话框弹出来:“确定要删除此邮件吗?”
她点了“确定”。
邮件消失了。
她关掉电脑,收拾东西,拎起公事包。经过走廊的时候,她没有看向对面的办公区域。但她知道那里的灯还亮著。
电梯到了一楼,门打开。大厅里很安静,保全在前台后面打瞌睡。她走出大楼,夜风吹过来,带著十一月的凉意。她站在大楼门口,抬头看了一眼。
十五楼的灯还亮著。
她看了大概五秒,然后低下头,走向地铁站。
手机在公事包里。她没有拿出来看。
但她知道那条消息还在那里。
“我怕你的方案出问题。”
这句话在她脑子里转了一整个晚上,像一段无法终止的进程,占用著内存,释放不了。
地铁进站的时候,风从隧道里吹出来,把她的头发吹乱了。她站在月台上,看著列车的灯光从远处一点一点靠近。
她忽然想起来,三年前他们还在一起的时候,有一次他问她:“程司白,你怕什么?”
她说:“我不怕什么。”
他说:“每个人都怕什么。你怕什么?”
她想了一会儿,说:“我怕失控。”
他问:“什么样的失控?”
她说:“所有的。”
他没有再问。
现在她知道,她怕的不是失控本身。她怕的是失控之后,没有人接住她。
她怕她掉下去的时候,底下是空的。
所以她从来不让自己掉下去。她把自己架在一个很高的地方,用理性做支架,用工作做墙,用孤独做屋顶。她一个人住在里面,安全,稳定,不会塌。
但现在有人在外面敲门。
她不知道要不要开。
地铁来了,门打开。她走进去,找了一个靠窗的位置坐下。列车启动的时候,窗外的灯光开始向后退,一盏一盏的,越来越快,最后连成一条线。
她看著那条线,想起他消息里最后那几个字。
“扛在自己身上。”
她的眼眶忽然有点热。
她没有哭。她已经很久没有哭了。上一次哭是三年前分手那天,她把手机摔在地上之后,坐在床上哭了大概五分钟,然后擦干眼泪,去洗了一把脸,回来继续写程式码。
那五分钟是她给自己的极限。
她觉得任何情绪都不应该超过五分钟。超过了就是失控。失控就是危险。
但现在她觉得,也许有些情绪不是用时间来衡量的。
有些情绪会在你以为已经结束的时候重新出现,像一段没有被彻底删除的数据,平时看不见,但每次系统重启的时候都会跳出来,提示你:这里还有东西。
你没有清干净。
她到家的时候已经是凌晨两点四十。打开门,换鞋,放下公事包,走进厨房倒了一杯水。客厅里很暗,只有窗外的路灯透过窗帘照进来,在地板上投下一片橘黄色的光。
她坐在沙发上,拿著手机。
那条消息还在。
她打了几个字:“我知道了。”
没有发送。删掉。
又打了几个字:“你不用担心。”
没有发送。删掉。
又打了几个字:“谢谢。”
没有发送。删掉。
她把萤幕关掉,把手机放在茶几上。
窗外的路灯闪了一下,又恢复了正常。客厅里很安静,安静到她能听见自己的呼吸声。
她闭上眼睛。
脑子里浮现出一个画面。三年前的某个深夜,她在公司加班,趴在桌上睡著了。醒来的时候发现身上盖著一件外套,桌上放著一杯还温的咖啡。咖啡杯旁边压著一张纸条,上面写著:“别太累了。我先走了,明天见。”
她当时把那张纸条揉成一团扔进了垃圾桶。
现在她想起来,那张纸条她其实没有扔。
她把它放在抽屉里,压在最下面。
和那部旧手机放在一起。
和那条“好,不打扰了”放在一起。
和所有她说不需要的东西放在一起。
但她从来没有扔掉过。
会议室四的空调坏了。
程司白走进来的时候就发现了这个问题。室内温度至少二十六度,比走廊里高了三四度,空气不流通,有一股闷闷的味道。她看了一眼墙上的温控面板,萤幕是黑的,没有任何反应。她按了两下,没用。
她选了一个靠窗的位置坐下,把窗户推开一条缝。外面的空气灌进来,带著十一月的凉意和汽车尾气的味道。不好闻,但至少能呼吸。
裴衍之三分钟后到的。他推门进来的时候手里拎著一台笔记型电脑和那个鼓鼓的文件夹,穿了一件浅灰色的T恤,袖口卷到肩膀下方,露出上臂的线条。他看到程司白已经坐在里面了,脚步顿了一下,然后走到会议桌的另一端坐下——还是最远的那个位置。
他把电脑打开,萤幕上是一张密密麻麻的测试计划表。
“开始吧。”他说。
程司白点开自己的测试文档。“我先说。Raft变体的边缘场景测试需要覆盖五个维度:网络分区、节点崩溃、日志不一致、快照恢复、成员变更。每个维度至少跑一千次,总共五千次测试。两周时间够用,但需要你的团队配合提供业务层的模拟数据。”
“可以。”裴衍之在他的测试计划表上加了几行,“业务层的模拟数据我让陆维安准备,两天之内给你。”
“不用两天,明天下午之前。”
裴衍之抬起头看了她一眼。“明天下午之前有点紧。”
“你的方案也需要我的架构组提供底层网络的模拟环境。”程司白没有让步,“我明天上午给你,你明天下午给我。公平。”
裴衍之沉默了三秒。“行。”
程司白在他的测试计划表上画了一个圈,标注了交付时间。两个人的手指在萤幕上几乎碰到一起,她往后缩了一点,他没有动。
会议室的门被推开了。
何悦端著一杯咖啡走进来,脸上挂著一种过于灿烂的笑容。她把咖啡放在程司白面前,然后看了看裴衍之,表情忽然变得有点尴尬。
“啊,裴哥你也在。我只带了一杯……”
“没事。”裴衍之说,“我不渴。”
何悦站在那里,手里还端著托盘,明显没有要走的意思。她看了看程司白,又看了看裴衍之,最后说了一句:“那我先去忙了,你们慢慢聊。”
她走出去的时候没有关门。程司白站起来去关门,经过裴衍之身边的时候闻到那股柠檬和雪松的味道。她的脚步没有停。
门关上之后,会议室里又只剩下他们两个人。
程司白回到座位上,看了一眼那杯咖啡。是她平时喝的美式,不加糖不加奶,杯壁上用记号笔写著一个笑脸。何悦每次给她送咖啡都会画这个,说是“给程式码加点温度”。
她把咖啡推到一边,继续看测试计划表。
裴衍之的手指在键盘上敲了几下,忽然说:“你的Raft变体在成员变更场景下的测试覆盖率是多少?”
“百分之九十五。”
“太低。”
“分布式系统的成员变更场景本来就很难做到百分之百覆盖。百分之九十五已经是业界标准。”
“你的方案用的是单步成员变更,还是联合共识?”
“联合共识。”
“那你的测试覆盖率至少需要百分之九十八。联合共识在成员变更过程中有一个两阶段的状态转换,你百分之九十五的覆盖率测不到边缘情况。”
程司白的手指在键盘上停了一下。他说得对。
“我改到百分之九十八。”她在测试计划表上改了数字,“但你那边的业务层模拟数据也要相应提高精度。”
“可以。”
两个人又沉默了一阵。键盘的声音在会议室里交替响起,哒哒哒哒,像一段双人演奏的曲子,节奏不算合拍,但至少没有打架。
墙上的时钟指向十一点四十分。程司白看了一眼时间,合上电脑。“上午就到这里。下午两点继续。”
裴衍之点点头,也开始收拾东西。
程司白走出会议室的时候,何悦在走廊上“刚好”经过,手里拿著一个空杯子,眼睛却一直往她脸上瞟。
“程姐,开完会啦?”
“嗯。”
“裴哥还在里面?”
“嗯。”
何悦往会议室的方向看了一眼,压低声音:“程姐,你们今天气氛好像好多了。”
程司白没有回答,径直走向自己的工位。何悦跟在后面,脚步轻快得像一只捡到了食物的麻雀。
午饭时间,程司白习惯一个人吃。
不是因为不喜欢跟人打交道,是因为吃饭的时候不需要打交道。她可以一边吃一边看论文,或者什么都不想,只是把食物放进嘴里,咀嚼,吞咽,重复这个过程直到饭盒见底。这是她一天中为数不多的、完全属于自己的时间。
她拎著饭盒走到休息区,找了一个靠角落的位置坐下。休息区有一整面落地窗,可以看到楼下的街道和对面的写字楼。十一月的阳光不烈,透过玻璃照进来,在桌面上投下一片温暖的光斑。
她打开饭盒,里面是昨晚做的番茄炒蛋和清炒西兰花。她用筷子夹了一块番茄放进嘴里,凉了,味道不如刚出锅的时候好,但也还能接受。
筷子刚放下,一个人端著饭盒在她对面坐了下来。
“这里有人吗?”
程司白抬起头。裴衍之站在桌子对面,手里端著一个便利店的便当盒,表情很自然,像在问一个完全正常的问题。
休息区还有十几张空桌子。
“没有。”她说。
裴衍之坐下来,打开便当盒。里面是一份咖哩猪排饭,猪排炸得有点焦,咖哩酱的颜色很深,闻起来有一股辛辣的味道。
两个人各自吃各自的,谁都没有说话。
休息区里还有其他同事在吃饭,偶尔传来一两句聊天声和笑声。程司白所在的角落很安静,安静到她能听见裴衍之咬猪排的声音——脆的,炸过头了的那种脆。
她夹了一块西兰花,放进嘴里。
裴衍之忽然开口了。
“你的Raft变体在日志不一致的修复场景中,用的是什么策略?”
程司白嚼完嘴里的西兰花,放下筷子。“领导者覆盖。新任命的领导者会强制将自己的日志同步到所有跟随者节点。”
“这个策略在日志差异很大的时候会导致大量的网络传输。”
“所以我在日志压缩上做了优化。快照的粒度从固定大小改为动态调整,日志差异越大的时候快照粒度越粗,传输的数据量反而会减少。”
裴衍之想了想。“这个思路有点意思。但动态调整快照粒度可能会影响读性能。”
“影响在可接受范围内。我测过,读性能下降不超过百分之八。”
“百分之八在业务高峰期是一个不小的数字。”
“所以需要你的业务层数据来校准。”程司白又夹了一块番茄,“你下午把模拟数据的规格发给我,我调整一下测试参数。”
“好。”
两个人又沉默了。
裴衍之低头吃饭,程司白也低头吃饭。阳光从落地窗照进来,照在两个人的饭盒上,照在筷子尖上,照在他们之间那几十公分的桌面上。
何悦从休息区门口经过的时候脚步明显慢了下来。她手里端著一杯奶茶,眼睛瞪得很大,嘴巴微微张开,像看到了什么不可思议的东西。她掏出手机,对著程司白和裴衍之的方向拍了一张照片,然后快步走开。
三分钟后,“干饭小分队”群组里出现了一条消息。
何悦:“姐妹们,程姐和裴哥一起吃午饭了!我是不是该买彩票?”
陆维安:“?在哪”
何悦:“休息区靠窗的位置,两个人面对面坐著,气氛很好!!!”
陆维安:“我过去看看”
何悦:“你别去!!不要打扰他们!!”
陆维安:“哦”
何悦:“而且他们好像在聊技术,我听到什么日志压缩和快照粒度。程姐吃饭都在聊工作,我真的服了。”
群组里其他人开始冒泡。有人发了一个震惊的表情,有人问“哪个程姐哪个裴哥”,有人回“还能有哪个程姐哪个裴哥”。
何悦又发了一条:“我决定了,从今天开始我是程裴CP的头号粉丝。群名改一下。”
她把群组名称改成了“共识观察小组”。
陆维安:“这什么名字”
何悦:“你不懂。这是技术梗。”
下午的会议在两点准时开始。
程司白走到会议室门口的时候,发现门开著,空调修好了。室内温度二十二度,舒适,凉爽,适合思考。她在心里感谢了一下维修部门的效率。
裴衍之已经在里面了,面前摊著几张打印出来的图表。他看到程司白进来,把其中一张推到她面前。
“业务层的模拟数据规格。我上午抽空整理了一下,你看看有没有问题。”
程司白接过来看了一眼。表格做得很仔细,每一个字段都有说明,数据范围和分布都标注得很清楚。他在数据的边缘场景部分多加了几行,用红色标注了“高优先级”。
“效率很高。”她说。
裴衍之没有接话。