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):只管线程调度、地址空间、消息收发。代码量几千行。文件、显示、命名、VMTP(消息的网络底层)全是用户态服务进程。
-
同步消息 IPC:三个原语——
Send/Receive/Reply。日常类比:打电话——你说一句(Send),对方接(Receive),对方回一句(Reply),整个过程你阻塞着等。 -
网络透明:本地调用和跨机器调用同一套 API。底层 V 内核帮你打包消息、找到目标机器、发包、解包。调用方代码完全不用改。
-
进程组 + 多播:一次
Send可以发给”一组进程”(比如所有命名服务),最先回的那个赢。日常类比:你在群里 @ 一组人问问题,谁先回你就听谁的。
四块加起来叫 V kernel。上面再挂 VGTS(网络透明窗口)、文件服务、命名服务等,撑起整台”逻辑机器”。
案例 1:在 V 上”打开一个文件”实际发生什么
Section titled “案例 1:在 V 上”打开一个文件”实际发生什么”你在工作站 A 上写:
fd = open("/users/student/report.txt");实际过程:
- C 库把
open翻译成一条 V 消息:Send(file_server, "open /users/student/report.txt") - V 内核查命名服务(也是个用户态进程),知道
file_server在工作站 B 上 - V 内核把消息封成 VMTP 包,通过 LAN 发给 B
- B 上的文件服务进程收到、读盘、回一个文件句柄
- V 内核把回包还给 A 上你的进程
整套耗时约 2.5 毫秒。代码完全不知道文件在另一台机器。
案例 2:同机 Send-Receive-Reply 一回合
Section titled “案例 2:同机 Send-Receive-Reply 一回合”/* 客户端 */ /* 服务端 */Send(server, msg); Receive(msg); /* 处理 msg */ Reply(client, result);/* 这里才醒过来 */逐步走读:
- 客户端
Send:把 32 字节固定消息拷进内核,自己阻塞 - 服务端
Receive:取出消息;大数据另走MoveTo/MoveFrom(直接搬内存,不塞进消息体) - 服务端
Reply:回 32 字节结果,客户端被唤醒
1988 年同机一回合约 0.5 毫秒(约 5000 条 68020 指令)。同步阻塞 = 不用排队、不用锁;内核小 = 切换路径短。当时 Unix pipe 往往更慢。
案例 3:V 鼓励的写法和 Unix 差在哪
Section titled “案例 3:V 鼓励的写法和 Unix 差在哪”/* V:很多小服务,靠消息拼起来 */Send(name_server, "where is file_server?");Send(file_server, "read block 42");
/* Unix 1988:几个大进程 + 管道 */pipe(fd); write(fd[1], buf, n); /* 跨机器还得另挂 RPC 库 */| 维度 | Unix 1988 | V 1988 |
|---|---|---|
| 一回合 IPC | pipe 几毫秒 | 约 0.5 毫秒 |
| 跨机器 | 无原生,靠 RPC 库 | 内核原生,本地远程同 API |
| 鼓励写法 | 重进程 + 管道串联 | 轻进程 + 频繁通信 |
这是两种正交世界观:V 把”小服务 + 透明 RPC”做进内核层。
- 同步 IPC 在网络抖动时会卡死调用方:远端挂了你就一直阻塞;必须设超时,超时后取消等待并返回错误,否则线程永久挂起。
- 进程组多播没有强一致性保证:
Send给一组文件服务做副本时,V 不保证全员收到——应用层得自己处理。 - 32 字节短消息不够现代结构:复杂参数得拼
MoveTo,写起来啰嗦;L4 后来扩到任意长度修了这个。 - LAN 变快后远程优势缩小:10 Mbps 升到 100 Mbps / 1 Gbps 后,单机微内核卖点更突出;L4 顺势从”分布式微内核”转向”单机微内核”。
适用 vs 不适用场景
Section titled “适用 vs 不适用场景”适用:
- 同构 LAN 集群想做 single system image(V 的本场;延迟最好压在几毫秒内)
- 实时嵌入式系统(QNX 至今活得好——同步 IPC 延迟可预测)
- 需要”小内核 + 可热拔插服务”的安全关键系统(seL4 是这条路的终点)
不适用:
- 广域网(同步 IPC 延迟撑不住跨城,往往 >50 ms)
- 高吞吐数据流(消息切包不如共享内存)
- 异构集群(V 假设大家都跑 V 内核)
- 需要强一致复制(V 多播不保证)
历史小故事(可跳过)
Section titled “历史小故事(可跳过)”- 1981 年:Cheriton 在斯坦福开搞 V,目标是给早期 SUN(MC68000)工作站集群一个统一系统
- 1983-1985 年:第一版 V 跑起来,VMTP 作为 IPC 网络层;VGTS 提供网络透明窗口
- 1988 年:CACM 论文发表,把 V 的设计哲学和性能数据公开
- 1995 年:Liedtke 发表 L4,IPC 推到亚微秒,骨架继承 V 的同步消息路线
- 1990s 中:QNX 把同步消息模型做成商用 RTOS,至今还在汽车、医疗设备里跑
V 项目本身在 1990s 结束,但它的设计 DNA 散布在之后许多微内核里。
- 小内核 + 快 IPC 能落地——1988 年就在跑文件、窗口、命名等实际服务,不只是论文图
- 同步消息简单可控但易卡;Mach 选异步更灵活但更慢——取舍清晰
- 网络透明有代价:调用方不知远近,延迟可差数倍,必须能容忍或设超时
- 微服务不是新概念:应用层的 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 —— 微内核 + 形式化证明的现代答卷
- plan9-1995 —— 网络透明的另一条路:用文件协议替代 IPC
- sprite-1988 —— 同期另一套工作站集群 OS,对比 single system image
- amoeba-1990 —— 另一条分布式微内核路线,可对照进程与通信模型
- exokernel-1995 —— 把”内核再砍小”推到极致的后续实验
(暂无反向链接)