跳转到内容

Sprite 1988 — 把一屋子工作站伪装成一台大主机

是什么

Sprite 是 Berkeley 1980 年代造的一个分布式操作系统。它把实验室里几十台联网工作站,伪装成”一台超大共享主机”——你坐到任意一台机器前登录,看到的文件、用户、正在跑的进程都是同一份

日常类比:宿舍 6 个人各一台电脑。Sprite 让你坐到任意一台前,桌面、文件、未存档的浏览器标签都自动跟着你走。更狠的是,你正在 A 机编译大项目,舍友过来要用 A——编译任务自动飞到隔壁空着的 B 机继续跑,你完全没感觉。

这套思路 1988 年叫 单一系统映像(single-system image),今天 K8s / 容器调度 / 云计算 用的还是同一套抽象。

更具体地:Sprite 想解决的问题,可以用一个数字概括——Berkeley 1986 年实测,工作站日均 60-80% 时间空闲。研究生白天开会、吃饭、写报告,机器干等。Ousterhout 的判断是:与其让每台机器孤立闲置,不如把它们捏成一个资源池,谁忙了谁去池子里抓空闲算力。

为什么重要

不理解 Sprite,下面这些事都没法解释:

  • 为什么 K8s 敢说”一个集群就像一台大机器”——这个理念 1988 年就有了
  • 为什么 vMotion / Live Migration 能把虚拟机不停机搬到另一台物理机——Sprite 的进程迁移是它的祖师爷
  • 为什么 Ousterhout 后来能搞出 Tcl/Tk、LFS、RAMCloud——他做 Sprite 时把”分布式 + 易用”这条路走完了
  • 为什么 1991 年的 LFS(日志结构文件系统)能颠覆传统设计——它是 Sprite 的副产品

核心要点

Sprite 把”一群机器看着像一台”拆成 四件事

  1. 统一文件名空间:所有机器的文件挂在同一棵 / 树下。你写 /users/jason/code.c,无论坐哪台机器,路径都解析到同一个文件。背后用**前缀表(prefix table)**把路径前缀路由到正确的文件服务器,用户透明。

  2. 进程迁移(process migration):每台机器监控自己的负载(load average),空闲超过 5 分钟就进入”招募池”。忙的机器看到招募池有空机器,把运行中进程冻结 → 拷贝内存页 → 转移文件描述符 → 在目标机继续跑。键盘鼠标一动,立刻把进程”驱逐回家”。

  3. 强一致分布式文件缓存:服务器记录”哪些客户端缓存了哪些文件”。一旦有人写,服务器主动回调通知所有缓存方失效。比同时代 NFS 的”30 秒过期”严格得多。

  4. home machine 概念:每个进程有一个”老家”机器。影响老家状态的系统调用(终端 IO、信号、ptrace)即使进程迁走了,也通过 RPC 转发回老家执行。这让迁移对应用代码完全透明——程序不知道自己被搬过。

这四件事加起来,让”一屋子工作站 = 一台大主机”成立。

实践案例

案例 1:进程迁移真的在跑

Berkeley 研究生日常:早上来组里登录任意一台 DECstation 5000,开始 make 编译一个大项目。中午另一个同学回来要用这台机器——他一动键盘,你的 make 进程被自动迁移到隔壁刚走的同学的空机器上继续编译。下午你回来,进程又自动迁回你面前的机器。

这套机制论文里叫 eviction(驱逐),触发条件就是”home 机器有人开始用了”。

案例 2:强一致缓存为什么打败 NFS

NFS 1985 的设计:客户端缓存文件 30 秒,过期就重新拉。两个客户端同时改一个文件,最长能有 30 秒看不到对方的修改

Sprite:服务器维护一张表”文件 X 被客户端 A、B 缓存”。客户端 C 来写时,服务器先广播 invalidate 给 A 和 B。A、B 下次读 X 时发现缓存失效,重新拉。任意时刻所有人看到的都是最新版

代价:服务器有状态,宕机重启后要重建这张表,恢复比 NFS 复杂。

案例 3:进程迁移的现代后裔

Sprite 1988 → MOSIX 1990s → CRIU 2011 → K8s pod migration
vMotion (VMware 2003)

CRIU(Checkpoint/Restore In Userspace)今天在 Linux 上做的事,和 Sprite 30 年前一模一样:冻结进程、序列化状态、在另一台机器恢复。VMware 的 vMotion 把同样的思路从进程层抬到虚拟机层——一台 VM 不停机搬到另一台物理机,用户网页都不掉。

案例 4:前缀表是怎么工作的

实验室有 3 台文件服务器:fs1 管 /home,fs2 管 /projects,fs3 管 /usr。每台客户端启动时下载一张前缀表:

/home → fs1
/projects → fs2
/usr → fs3

你访问 /projects/sprite/main.c:客户端查表,最长前缀匹配到 /projects,把请求 RPC 给 fs2。对应用是单一文件系统,对底层是分片路由——和今天 CDN / 分布式 KV 的思路完全一致。

新增服务器 fs4 接管 /scratch?只需要广播一条前缀表更新,所有客户端把新条目插进去,应用代码无需改动一行。这种”加机器不改代码”的弹性,今天叫 horizontal scaling,1988 年的 Sprite 已经在玩了。

踩过的坑

  1. 迁移代价不能忽略:一个 10MB 内存的进程,10 Mbps 以太网下要传 8 秒。短任务(几秒就跑完)迁移不划算。Sprite 的策略是只迁移预期会跑很久的进程,靠经验阈值判断。

  2. 异构机器迁不了:Sun-3(68k)和 VAX 二进制不兼容,进程没法跨架构迁。论文里默认集群是同构的。

  3. 强一致缓存让服务器成单点:file server 一挂,所有客户端的写都阻塞。Sprite 用复制 + 检查点缓解,但比 NFS 的”无状态服务器”脆弱。

  4. WAN 完全不工作:Sprite 假设的是低延迟 LAN(10 Mbps,<1ms RTT)。跨城市部署,缓存失效广播变成性能毒药。

  5. PC 廉价化让单一映像失去意义:1990 年代 PC 个人化趋势——用户要”自己的桌面、自己的环境”,不要”在哪台机都一样”。Sprite 的核心卖点被时代绕过去了。

  6. home machine 让透明性留了缝:终端 IO、ptrace 这些必须 RPC 回老家,意味着如果 home machine 宕机,迁出去的进程也跟着卡。Sprite 的”完全透明”其实是”对 CPU/内存透明、对 IO 半透明”,论文里坦诚承认了这个权衡。

适用 vs 不适用场景

适用

  • 同构集群 + 低延迟 LAN(学校实验室、公司局域网)
  • 工作负载多变、机器空闲率高(适合迁移调度)
  • 用户共享数据多、不需强隔离(学术环境的典型)

不适用

  • 个人 PC(用户要”我的环境”,不要”任意机器同一个环境”)
  • WAN / 跨地域部署(缓存协议假设低延迟)
  • 异构集群(CPU 架构不同迁不了进程)
  • 需要强隔离的多租户(单一映像 = 安全边界模糊)

历史小故事(可跳过)

  • 1984 年:John Ousterhout 从 CMU 来 Berkeley 当教授。看到学生人手一台 Sun,但每台 60-80% 时间空闲,决定造个 OS 把空闲机器利用起来。
  • 1986 年:Sprite 立项,团队约 5 人——Ousterhout 加四个博士生 Cherenson、Douglis、Nelson、Welch。
  • 1987 年:Sprite 第一版能跑,发表为 UCB Tech Report CSD-87-393。Berkeley 研究生开始日常用 Sprite 上机做作业。
  • 1988 年:IEEE Computer 杂志正式发表,是本笔记基于的版本。同年 AFS 也定型,分布式文件系统两条路线齐发。
  • 1991 年:Ousterhout 的博士生 Mendel Rosenblum 在 Sprite 上做出 LFS(Log-Structured File System)——日志结构文件系统的开山之作。Rosenblum 后来去 Stanford,与妻子 Diane Greene 共同创办 VMware;vMotion 的思想血脉直接连回 Sprite 进程迁移。
  • 1994 年:Sprite 项目结束,Berkeley 研究生集群迁回 Solaris/NFS。Ousterhout 转去做 Tcl/Tk,1999 年加入 Sun。
  • 2010 年代:Ousterhout 在 Stanford 重启分布式系统研究,做出 RAMCloud;2018 年出版《A Philosophy of Software Design》,第 1 章直接讲 Sprite 的工程教训。

学到什么

  1. 抽象比性能更重要:Sprite 的进程迁移在当时性能并不出色,但”一屋机器 = 一台机器”的抽象影响了之后 30 年的分布式系统设计。今天讲 K8s 的 PPT 第一页”集群即一台机器”,源头在这里。
  2. 强一致 vs 最终一致:1988 年 Sprite 选强一致并真做出来;NFS 选最终一致更简单。两条路并行至今——Sprite 路线的后裔是 AFS / Coda,NFS 路线的后裔是 S3 / DynamoDB。
  3. 时代红利会消失:Sprite 的核心假设(机器贵、共享有意义)被 PC 普及绕过去。好系统也会因外部条件变化而失去舞台。这件事在今天看 ChatGPT、看 LLM 集群也成立——架构选择和硬件经济一起浮沉。
  4. 副产品可能比主项目更影响深远:Sprite 本身没活下来,但它孕育了 LFS、训练了 Rosenblum / Ousterhout 一代人。VMware 的早期工程师里有相当一部分 Sprite 出身。
  5. 透明性是双刃剑:Sprite 让进程”不知道自己被搬过”,对程序员友好;但出了 bug 调试时,看不见迁移发生过反而难定位。今天 K8s 也面临一样的张力——抽象越好,故障排查越像考古。

反思:今天还能从 Sprite 学到什么

读完这篇 1988 年的论文,最有价值的不是技术细节(很多被新方案替代了),而是做系统设计时的方法论

  • 先盯硬件经济:Ousterhout 是因为看到”机器空闲 60%“才决定造 Sprite,不是因为”想做分布式系统”。今天看 LLM 集群的 GPU 利用率,逻辑是同一条。
  • 先做透明再谈优化:进程迁移先保证应用不知道、不用改,再去优化迁移速度。“对开发者无感”比”快”更优先。
  • 接受局部不完美:home machine 这个设计明显”不优雅”,但它换来了”绝大部分系统调用直接在本地处理”的高性能。理论纯净度让位于工程实用。
  • 写论文要带数字:Sprite 论文里反复出现具体数字——60-80% 空闲率、迁移开销 50ms、缓存命中率 80%。一篇好的系统论文要让读者能复现实验、能比较权衡,光讲思想不给数字会被同行怀疑。

延伸阅读

关联

  • nfs-1985 —— 同时代的”无状态、弱一致”对比方案,Sprite 选了反方向
  • mach-1986 —— 同时代”微内核”路线,Sprite 走宏内核
  • coda-1990 —— Sprite FS 思想 + 离线工作能力的下一代
  • barrelfish-2009 —— 多核时代重新审视”单一系统映像”
  • afs-1988 —— Andrew File System,同年的另一条强一致路线
  • mccarthy-lisp —— 时序更早的”分时共享”思想源头,Sprite 把它从主机搬到了网络