核心结论

  • 邦威克 1994 年关于 slab allocator 的论文把内核对象视为具有类型的、可复用的结构,而不是匿名的内存块,影响了后来多个操作系统的实现。
  • 他与 Jonathan Adams 在 2001 年提出的每 CPU magazines 和 vmem 分配器,把这一思路扩展到多处理器系统和内存之外的资源。
  • 邦威克与 Matt Ahrens 共同启动了 ZFS,并在 Sun 领导了一个更大的团队,整合了存储池、写时复制、端到端校验、快照与修复;不能把他描述为唯一的发明者。
  • EMC 收购 DSSD 后又终止其独立产品,以及邦威克现任 iodyne 联合 CEO,都说明设计质量、交易价值和产品在市场上的延续是彼此分离的。

存储系统可能在未报错的情况下返回错误的数据块

存储的基本承诺很简单:当程序稍后请求数据时,它应该得到写入的内容。在传统架构中,职责分散在文件系统、卷管理器、控制器和磁盘之间。每一层都可能报告成功,而整条链路却返回陈旧的数据、指向错误位置的数据或已损坏的数据。

ZFS 把子数据块的校验和存储在父数据块中,因此预期标识沿着指针树传递,与它所校验的内容相互独立。读取时,系统会比较结果与预期,即使设备报告操作成功。如果在镜像或 RAID-Z 中存在正确副本,系统可以读取替代副本并加以校验,返回正确数据并修复损坏副本。而 scrub 则会遍历已分配的数据,在应用程序需要之前发现潜在损坏。

这套机制解释了 ZFS 在数据完整性方面的声誉,也划定了它的边界。校验和能发现差异,但如果所有副本都是错的,它无法重建数据。冗余并不能替代独立的备份、经过演练的恢复或良好的物理分布。管理错误、拥有合法权限的勒索软件、灾难和关联性故障都可能超出设计范围。

邦威克的贡献是让静默故障变得可观测,并把校验和修复引入常规路径。他没有消除数据丢失的风险。良好架构的价值在于它说明了保障在哪里结束。

在 ZFS 之前,他先降低了创建内核对象的成本

内核不断为文件、连接、进程和虚拟内存创建结构。这些对象有类型、大小、常量和初始化成本。每次都请求原始内存再构建并销毁对象,会把一个微小的操作放大为整个系统层面的开销。

邦威克在 1994 年描述的 slab allocator 把内存组织成 slabs,并按对象类别维护缓存。构造函数负责初始化所需状态,析构函数负责释放,空闲对象保留下来供复用。这样,内核保留了类型和生命周期信息,可以优化局部性、碎片、调试和记账。

最初的实现是 SunOS 和 Solaris 特有的。Linux、FreeBSD 等系统发展出了自己的实现和取舍,因此不能把所有现代分配器都归功于邦威克。缓存会消耗内存,可能保留陈旧状态,并需要在压力下进行平衡。持久的贡献是把创建成本、锁竞争、局部性和生命周期纳入同一个设计。

每 CPU 的 magazines 让分配器适应多处理器

当大量处理器争夺同一把锁时,全局缓存就会成为瓶颈。在 2001 年的Magazines and Vmem中,邦威克和 Jonathan Adams 提出了每 CPU 的本地小集合。常见操作在本地完成,与共享储库的交换按批进行。

vmem 把这种分层方法扩展到地址范围、标识符和其他资源。arenas 从更底层的分配器导入资源,系统管理的不再是逐个对象的集中同步,而是集合与所有权关系。

局部性有代价:对象可能堆积在一个 CPU 上,而另一个 CPU 正需要它们;平衡和内存压力依然必须处理。当时的基准结果与特定硬件和负载绑定。持久的思路是保留原本会丢失在通用接口之外的信息。

ZFS 起源于重建存储层的团队决定

邦威克和 Matt Ahrens 于 2001 年在 Sun 启动 ZFS,随后 Bill Moore 和大量工程师加入。邦威克领导了这个项目,也是最突出的公开讲解者,但一个生产级文件系统包含磁盘格式、缓存、工具、驱动程序、测试以及多年集体修复。

传统做法要求先创建 RAID 或卷、预先划分空间,再基于僵硬的增长假设建立文件系统。ZFS 围绕 pool 把文件系统和卷管理整合在一起。vdevs 添加容量,datasets 动态消耗容量,并配合 quotas、reservations、snapshots 和各种属性,处于同一个模型之中。

日常操作的简化使初始 topology 的选择更加敏感。vdev 的构成决定了冗余、性能、扩展和故障行为,事后无法随意重塑。Sun 于 2004 年宣布该系统,2005 年进入 OpenSolaris,2006 年随 Solaris 10 交付。

其历史意义不在于某一项特性,而在于 pool、copy-on-write、checksums、snapshots、RAID-Z、缓存和管理在同一个完整安全模型中的结合。

copy-on-write 让整棵树成为提交单元

在原位置写入,可能在断电时使元数据停留在两个状态之间。ZFS 把新数据块写入新位置,更新父节点,然后原子地转移到交易组的新 root。旧版本在完成之前保持一致。

snapshots 保留对旧数据块的引用,clones 先共享数据,随后随写入而分叉。代价在于额外写入、碎片和被占用的空间。这些保障也依赖硬件和控制器对写入顺序和持久性的遵守。

系统花费额外的结构来换取知识:哪个版本是完整的,哪个数据块应该是什么,以及哪一种状态可以采纳。这种知识并不能消除物理层。

checksums 与修复改变了“成功读取”的含义

ZFS 甚至校验设备报告成功的操作。如果校验和不一致,它会尝试另一个副本,并在找到正确副本时修复损坏的副本。scrub 把这一点变成周期性维护,只要冗余仍然存在,就能发现损坏。

检测、修复和完整恢复是不同的能力。勒索软件可以写入校验和正确的加密数据。多个副本可能同时失效。处于同一故障范围内的备份并不独立。运维人员必须知道副本在哪里,以及当设计好的冗余耗尽后还剩下什么手段。

RAID-Z、ARC 和 scrub 把安全带入日常操作

RAID-Z 利用写时复制和校验条带来避免传统的 write hole,但小写入的成本、重建时间和关联故障依然存在。磁盘越大,修复期间发生第二次故障的暴露时间越长。

ARC 在最近使用和高频使用的数据之间进行平衡,二级缓存可以延长这个层级。任何 cache 都不会在所有负载下把慢速介质变成快速介质,必须测量内存压力和元数据压力。

scrubs、resilvering、删除 snapshots 和 replication 都消耗 I/O、CPU 和网络资源。维护余量是容量的一部分,不是浪费。一个始终运行在极限的 pool,可能恰恰是在需要恢复时最脆弱的。

邦威克还帮助推广了一套可理解的操作语言:pool、vdev、transaction group、scrub。这种语言促进了采纳,但也可能变成与其条件脱节的口号。

OpenSolaris 结束了,但设计走出了创建它的公司

Oracle 于 2010 年收购 Sun,封闭的 Solaris ZFS 路线与开放代码分道扬镳。OpenZFS 于 2013 年成立,用于协调 illumos、FreeBSD、Linux 等平台。现在的项目源自 Sun 的工作,但已发生巨大变化,不再受邦威克支配。

这种延续性证明设计可以超越创建它的机构,但过程并非没有摩擦。CDDL 与 Linux 内核的 GPL 并不直接兼容,各平台在不同时间采纳特性,feature flags 影响 pool 的迁移。

只有开放仓库是不够的,还需要维护者、测试、资金和发布。治理本身就是一种机构性故障域。OpenZFS 是邦威克遗产的一部分,但现在的责任属于它的管理者。

DSSD 证明了雄心勃勃的架构可能输掉产品之战

邦威克与 Mike Shapiro、Bill Moore 共同创立 DSSD,为数据库和分析构建机架级 flash 系统。EMC 于 2014 年收购该公司,并于 2017 年停止 D5 作为独立产品。

这终结了一个必然成功的故事。速度、独创性和资金并不保证持久的位置。迁移、成本、认证、支持、销售渠道、买方优先事项,以及 NVMe 或云的经济学,都可能像 benchmark 一样左右结果。

现有证据无法确定单一原因,也无法估算创始人的财富。它们只能证明收购和产品终止。DSSD 把技术价值、交易价值和商业延续分离开来。

iodyne 把同样的问题应用于专业媒体,而不是重建 ZFS

邦威克和 Shapiro 于 2018 年创立 iodyne,两人担任联合 CEO。公司为视频和音频团队构建快速、加密、冗余的 NVMe 存储。

延续性是理念上的:在真实工作流中实现性能、保护和修复。iodyne 不是「盒装 ZFS」,也不是 DSSD 的直接延续;规模、接口、市场和机制都不同。

产品页面证明了所宣称的功能,而不是经过审计的可靠性、收入或市场份额。在媒体制作中,故障会阻断剪辑和交付,加密保护资产,而如果用户的工作无法持续,速度就没有价值。集成简化了支持,但把依赖集中到单一供应商。

管理本身成为可靠性模型的一部分

ZFS 的 pool 减少了曾经产生错误的行政边界。datasets、quotas、reservations、snapshots 和 replication 共享同一策略,而不是一串相互独立的工具。

但责任仍然存在。一个 dataset 可能消耗 pool 空间,snapshots 可能保留数据块,而 replication 只有在目的地和恢复都有效时才有用。两个逻辑副本可能共享同一块控制器、电源或固件缺陷。逻辑模型必须与真实故障域关联。

来自zfs list的整齐输出并不能证明企业能够恢复应用程序、保持其数据库的一致性,或找到解密所需的凭证。逻辑视图简化了管理,但不能替代恢复演练,也不能替代对物理依赖和应用依赖的理解。

分配器与文件系统把维护变成一等负担

缓存需要填充和平衡,pools 需要检查、重建和复制。这些工作与用户争夺资源,却决定信任能否持续。未使用的资源可能正是允许在下一次故障之前完成修复的余量。

这对软件同样适用。OpenZFS 需要测试、兼容性和发布,iodyne 需要售后对固件、主机软件和硬件的维护。发明创造建立系统,维护才把它变成基础设施。

技术领导力意味着划定他人能够在其内工作的边界

邦威克的领导是重要且集体性的。Ahrens、Moore、Adams、Sun 团队以及后来的维护者必须保持可见。caches、arenas、pools、datasets 和 transaction groups 之类的 abstractions 使分工成为可能,同时保持共同模型。

历史权威不能替代当前责任。OpenZFS 的维护者决定现在的代码,iodyne 的领导权与 Shapiro 共享。点名参与者能说明决策、维护和承诺现在在哪里。

许可证与治理成为另一种形式的故障隔离

公司可能改变战略。开放代码让其他群体在 Sun 之后继续跟进 ZFS,但这种机构冗余之所以成功,是因为它同时拥有权利、知识和实际发布能力。

没有维护者的两个分支,不会比同一控制器后面的两个磁盘更稳健。企业和志愿者提供资源,同时也制造依赖。OpenZFS 在技术上和机构上都存活了下来。

反复出现的方法:保留被薄弱层丢弃的信息

通用分配器只看到一个大小,而 slab 看到类型和生命周期。一个层看到成功读取,而 ZFS 看到带有预期标识的数据块。产品宣传 throughput,而运维面对的是修复、加密和持续运行。

额外信息有成本,也可能扩大共同故障范围。好的设计不在于隐藏尽可能多的组件,而在于让企业能够理解和修复的边界变得可见。

ZFS 改变了存储市场的比较单位

通过把 volumes、filesystem、checksums、snapshots 和修复整合起来,ZFS 迫使人们比较整条路径。面对 XFS、Btrfs、APFS、ReFS、Ceph 或商业阵列,关键在于安全模型、拓扑、支持和退出路径,而不只是功能清单。

没有全球赢家。商业产品提供经过验证的硬件和合同;开放代码提供透明和可移植性;分布式系统提供规模和对网络的依赖;专用设备改善 workflow,但可能增加 lock-in。

故障范围的概念把内存、存储和企业存续联系起来

故障范围可能是一块磁盘、一个 rack、一把全局锁、一家公司或一个供应商。magazines 减少了对单把 lock 的争夺,checksums 减少了对设备的盲目信任,OpenZFS 减少了对单一公司的依赖。

冗余必须存在于风险层。同一 controller 后面的磁盘、同一把丢失密钥下的副本、没有维护者的 branches,都只提供稳健的表象。简单可能隐藏共同命运;必须绘制关联并测试独立恢复。

诚实的遗产是更好的问题,而不是绝对的保障

slab allocator 影响了内核对象,magazines 和 vmem 扩展了分配,ZFS 整合了操作与安全,OpenZFS 跨越了一次机构转变,DSSD 显露了商业极限,iodyne 则在另一个市场继续这条论题。

把邦威克描述为共同创建者、项目负责人和架构师是准确的,而不是唯一的作者或当前 OpenZFS 的统治者。ZFS 能发现很多损坏,但需要一份正确副本;copy-on-write 依赖硬件;RAID-Z 不能替代 backup;scrub 不保证下一次读取。

真正的检验是:当前系统是否回答了他的工作使其成为必要的问题:allocator 对实体知道什么?block 的预期校验值存储在哪里?哪种 state 是完整的?副本是否真正独立?冗余耗尽后谁来恢复?同时,必须把缺乏完整统计、ZFS 贡献的精确分布,以及关于 iodyne 的经审计数据保留在结论之外。这种精确本身就是同一纪律的一部分。