.. Kenneth Lee 版权所有 2020
:Authors: Kenneth Lee :Version: 1.0
在概念空间选择方案
今天用了一个很玄的理由拒绝掉了一个方案,现场解释得特没有底气,会议结束后,我理 一下思路,整理成本文这个逻辑。
在我们讨论某些方案的时候,有些方案我们可以很容易接纳它,有些方案我们会很犹豫。 但考虑“具体场景”的时候,其实都没有什么毛病,为什么我们会觉得它不同?
比如,我们做一个Web Server服务。我们提供一个方案,把它实现为一个多线程的进程, 这个进程的用户和用户组是http。这个高层方案我们很容易就能接受。
对比一下:我们实现的这个Web Server是一个变形的进程,它可以处理中断(从而提高性 能),它没有用户和用户组,但root用户不能访问它的目录,只有通过某个基于ipsec端口 进来的请求才能访问它的目录……这个高层方案我们就很难接受了。
这个区别在什么地方呢?如果都推演每个具体的功能,可能两个方案都是通的。但前一个 方案我们在设想它未来发展的时候,我们觉得是受控的。已经存在的其他Web Server,数 据库,ftpserver……都用这种方法实现过,调度的逻辑是证明过是通的,安全模型证明过没 有人发现过漏洞,文件和用户用户组的关系的各种细节也有过无数的方案证明了。
但后者呢?你眼前看到的流程可能都是通的,但原来构想进程是不能处理中断的,现在可 以处理中断了,和signal处理如何互斥?和线程上下文如何互斥?锁函数还能不能调?原 来认为原子的操作是否还是原子的?原来文件和用户的关系是有各种细节支持的,现在用 接入的通道来控制?对于softlink的处理逻辑是什么?这每个都会因为引入这个逻辑而破 坏。
甚至你现场质问一两个这些问题,大家推演一下发现还真没有问题,但我们没有全部推演 过,谁知道有没有问题?
这就是这两者的不同,我们可能因为这个原因,就算没有任何证据证明方案2有破绽,我们 都可能直接拒绝方案2。这种拒绝在讨论中给人的感觉很粗暴和没有道理,但其实它是有道 理的。
这种问题越往系统的底层就越明显,因为高层概念都是建立在底层概念的基础上的。
你加一个系统调用,是否破坏了安全模型?是否破坏了原子性?是否破坏了日志模型,是 否破坏了调试模型……?你增加有一条指令,它是否改变了Cache的承诺?是否改变了原子操 作的排队?是否强制了系统必须有虚拟化模式?是否改变了Barrier指令对流水线的Stall 承诺?……每个有状态机推演的功能,只要引入一个新的状态和迁移,原来的逻辑就会不成 立。这种方案,就算你在当前的方案上说一千道一万,没有针对原来被你破坏掉的状态机 的全集推演,我们都没法相信。
所以,在成熟系统上做方案,我们要尽量“缩起来”,缩到其他概念的背后:比如“我这条新 指令依赖的东西和原来的load指令是一样的,没有使用额外的东西”。或者“我这个系统调 用其实就是把fork和exec两个系统调用组合起来,不要求其他任何概念做出改变”。甚至是 :“我们把原来这整个系统包装成一个虚拟机,我们在外部给他模拟成一个双CPU的系统, 原来的逻辑全部保持一致”……这样我们一般容易接受这个方案。
但如果你的方案是个颠覆性的概念,每个原来的框架面对你这个“另类”都需要进行改变, 在没有推演过这些每个被影响的框架前,我们是不太可能接受这个方案的,甚至我们因为 不可能投的起这个推演的成本,可能在没有任何“具体道理”前,就必须放弃它。这就显得 有些玄了。但这确实是个实实在在的逻辑。这个判断模型是基于形而上的概念关联空间上 的,没法用一个“具体”的例子去解释。