V 分布式系统 — 把局域网当成一台机器,内核只剩进程加 IPC
是什么
V 是 1980 年代斯坦福 Cheriton 团队做的一套分布式操作系统。它做了一件当时听起来很离谱的事:
把局域网里几十台工作站当成一台逻辑机器。
日常类比:你买了五台一样的笔记本,平时用其中一台。V 干的事相当于——你打开任何一台都能看到同样的桌面、同样的文件,启动一个程序它可能跑在其他机器的 CPU 上,但你完全感觉不到。
要做到这点,V 把内核砍到极小:只剩进程、地址空间、消息传递(IPC)三件事。文件系统、显示、命名、网络协议——全做成普通的用户态进程,互相靠消息调用。
这个”内核越小越好 + IPC 越快越好”的想法,后来直接催生了 L4 和 QNX。
为什么重要
不读 V,下面这些事都解释不了:
- 为什么 1990s 微内核(L4 / QNX / Mach)都长得很像——它们都在抄 V 的骨架
- 为什么”快 IPC”会成为微内核的核心 KPI(V 1988 年同机一回合 0.5 毫秒,那时已经是奇迹)
- 为什么 gRPC / Thrift 这套”调用远程像调用本地”的设计哲学不是新发明——V 1983 年就在 LAN 上做到了
- 为什么 Plan 9 / Erlang OTP / 现代 service mesh 都共享一个直觉:“小服务 + 透明通信”
核心要点
V 的设计可以拆成 四块:
-
微内核(kernel server):只管线程调度、地址空间、消息收发。代码量几千行。所有别的功能(文件、显示、命名)都不在内核里。
-
同步消息 IPC:三个原语——
Send/Receive/Reply。日常类比:打电话——你说一句(Send),对方接(Receive),对方回一句(Reply),整个过程你阻塞着等。 -
网络透明:本地调用和跨机器调用同一套 API。底层 V 内核帮你打包消息、找到目标机器、发包、解包。调用方代码完全不用改。
-
进程组 + 多播:一次
Send可以发给”一组进程”(比如所有命名服务),最先回的那个赢。日常类比:你在群里 @ 一组人问问题,谁先回你就听谁的。
四块加起来叫 V kernel。
实践案例
案例 1:在 V 上”打开一个文件”实际发生什么
你在工作站 A 上写:
fd = open("/users/jason/report.txt");实际过程:
- C 库把
open翻译成一条 V 消息:Send(file_server, "open /users/jason/report.txt") - V 内核查命名服务(也是个用户态进程!),知道
file_server在工作站 B 上 - V 内核把消息封成 VMTP 包,通过 LAN 发给 B
- B 上的文件服务进程收到、读盘、回一个文件句柄
- V 内核把回包还给 A 上你的进程
整套耗时约 2.5 毫秒。代码完全不知道文件在另一台机器。
案例 2:V 的 IPC 为什么快
1988 年同机进程间 Send-Receive-Reply 一回合只要 0.5 毫秒——大约 5000 条 68020 指令。当时 Unix pipe 至少几毫秒,BSD socket 更慢。
诀窍:
- 消息只有 32 bytes固定大小:内核拷一次就完事
- 大数据另走
MoveTo/MoveFrom:直接 DMA 不经过消息体 - 同步阻塞 = 不需要排队 + 不需要锁:调用线程等着回来即可
- 内核小:上下文切换路径短,cache 友好
案例 3:V 的 IPC vs Unix 进程模型
| 维度 | Unix 1988 | V 1988 |
|---|---|---|
| 进程创建 | fork/exec 几毫秒 | ~10 毫秒(要建地址空间) |
| 一回合 IPC | pipe 几毫秒 | 0.5 毫秒 |
| 鼓励的写法 | 重进程 + 管道串联 | 轻进程 + 频繁通信 |
| 跨机器调用 | 没有原生支持,要用 RPC 库 | 内核原生,本地远程同 API |
V 鼓励你写”很多小服务”,Unix 鼓励你写”几个大进程串起来”。这是两种正交的世界观。
踩过的坑
-
同步 IPC 在网络抖动时会卡死调用方:调用方阻塞等回包,远端机器挂了它就一直等。需要超时机制兜底,但超时设多少又是另一坑。
-
进程组多播没有强一致性保证:你
Send给一组文件服务想做副本,但 V 不保证所有副本都收到——应用层得自己处理。 -
32 bytes短消息不够现代结构:复杂参数得拼
MoveTo,写起来啰嗦。L4 后来扩到任意长度修了这个。 -
1988 年 LAN 是 10 Mbps,到 1990s 升到 100 Mbps / 1 Gbps 后:网络比 V 内部 IPC 还快,远程调用的延迟优势相对缩小,单机微内核的卖点反而更突出。L4 就是顺势从”分布式微内核”转成”单机微内核”的。
适用 vs 不适用场景
适用:
- 同构 LAN 集群想做 single system image(V 的本场)
- 实时嵌入式系统(QNX 至今活得好——同步 IPC 延迟可预测)
- 需要”小内核 + 可热拔插服务”的安全关键系统(seL4 是这条路的终点)
不适用:
- 广域网(同步 IPC 延迟撑不住跨城)
- 高吞吐数据流(消息切包不如共享内存)
- 异构集群(V 假设大家都跑 V 内核)
- 需要强一致复制(V 多播不保证)
历史小故事(可跳过)
- 1981 年:Cheriton 在斯坦福开搞 V,目标是给 SUN-3 工作站集群一个统一系统
- 1983-1985 年:第一版 V 跑起来,VMTP(V Message Transport Protocol)作为 IPC 网络层
- 1988 年:CACM 论文发表,把 V 的设计哲学和性能数据公开
- 1995 年:Liedtke 发表 L4,IPC 推到亚微秒,骨架完全继承 V
- 1990s 中:QNX 把 V 的同步消息模型做成商用 RTOS,至今还在汽车、医疗设备里跑
V 项目本身在 1990s 结束,但它的设计 DNA 散布在之后所有微内核里。
V 之上跑的实际服务
V 不只是个内核,1988 年它已经撑起一整套服务:
- VMTP:V Message Transport Protocol,IPC 的网络底层。一回合事务级语义,比 TCP 三次握手轻
- V 文件服务:你的
/users/jason可能挂在另一台机器,本地代码无感 - VGTS(V Graphics Terminal Service):网络透明窗口系统,比 X11 早,思路相近
- DSEE:分布式编程环境,编译器在空闲机器上跑
- 命名服务:把”名字”翻译成”在哪台机器的哪个进程”,本身也是个用户态进程
这套”内核小 + 服务多 + 互相消息”的格局,就是现代 microservice 架构的祖宗。
学到什么
- 小内核 + 快 IPC 是一个能落地的方案——不只是论文里的好看图,1988 年就在跑实际服务
- 同步消息 vs 异步消息:V 选同步,简单可控但容易卡;Mach 选异步,复杂灵活但慢
- 网络透明的代价:调用方不知道远近,但延迟差 5x,必须能容忍
- 设计哲学的传承链:V 1988 → L4 1995 → seL4 2009 → 30 年同一根主线在拧
- 微服务不是新概念:把”小服务 + 透明 RPC”的思路放到应用层就是 gRPC/Thrift;V 在内核层做了同样的事
延伸阅读
- 论文 PDF:The V Distributed System (CACM 1988)
- 配套读:l4-1995 —— Liedtke 把 V 的 IPC 推到亚微秒
- 配套读:mach-1986 —— 同期的另一条微内核路线
- 配套读:sel4-2009 —— 微内核哲学的形式化终点
- 视频:Cheriton 在斯坦福的几次讲座(YouTube 搜 “Cheriton V system”)
关联
- l4-1995 —— L4 是 V 的直系徒孙,把同步 IPC 推到极致
- mach-1986 —— 同期对手,选了异步消息和端口的复杂路线
- sel4-2009 —— 微内核 + 形式化证明的现代答卷
- plan-9-bell-labs —— 网络透明的另一条路:用文件协议替代 IPC