ZFS

ZFS是一个拥有逻辑卷轴管理功能的档案系统，最早源自于太阳微系统在2001年开始为Solaris操作系统开发的文件系统。ZFS具有可扩展性，并且包括大量保护措施防止数据损坏，支持高存储容量、高效数据压缩、集成文件系统、卷管理、快照和写入时复制、连续完整性检查与自动修复、RAID-Z、原生NFSv4 ACL等功能，并且能被精确配置。ZFS有两个主要实现，分别来自Oracle和OpenZFS，它们之间极度相似，这使得ZFS在类Unix系统中广泛可用。

ZFS这一名字本身没有含义，也不是某种缩写，曾被认为表示Zettabyte File System。ZFS最初是专有软件，被Sun内部开发作为Solaris的一部分，由Sun存储部门的CTO、研究员Jeff Bonwick带领团队开发。在2005年，Solaris的大部分组件，包括ZFS成为采用通用开发与散布许可证的开源软件，作为OpenSolaris项目。在2006年，ZFS成为Solaris的一项标准特性。

在2010年，Sun被Oracle收购，ZFS成为Oracle的注册商标。Oracle停止为OpenSolaris和ZFS项目提供更新的源代码，使得ZFS转为闭源软件。因此，有人成立了illumos项目，去维护已经存在的开源的Solaris代码，并且在2013年成立OpenZFS项目以配合ZFS的开源发展。OpenZFS团队维护管理核心ZFS代码，还有一些使用ZFS的组织维护特定的代码和必要的验证流程，以集成到他们的系统。OpenZFS在类Unix系统中被广泛使用。

## 历史

ZFS的设计与开发由Sun公司的Jeff Bonwick所领导的一支团队完成。最早宣布于2004年9月14日，于2005年10月31日并入了Solaris开发的主干源代码。并在2005年11月16日作为OpenSolaris build 27的一部分发布。Sun在OpenSolaris社区开张1年后的2006年六月，将ZFS整合进了Solaris 10 6/06版本更新。

ZFS的命名来源发想于"Zettabyte File System"的首字母缩写。但ZFS本身并不具备任何的缩写意涵，只是作者想阐述做为一个具备高扩充容量档案系统且还有支援许多延伸功能的一个产品。

## 存储池

不同于传统文件系统需要驻留于单独设备或者需要一个卷管理系统去使用一个以上的设备，ZFS建立在虚拟的，被称为“zpools”的存储池之上（存储池最早在AdvFS实现，并且加到后来的Btrfs）。每个存储池由若干虚拟设备（virtual devices，vdevs）组成。这些虚拟设备可以是原始磁盘，也可能是一个RAID1镜像设备，或是非标准RAID等级的多磁盘组。于是zpool上的文件系统可以使用这些虚拟设备的总存储容量。

可以使用磁盘限额以及设置磁盘预留空间来限制存储池中单个文件系统所占用的空间。

## 容量

ZFS是一个128位的文件系统，这意味着它能存储1800京（1.84×1019）倍于当前64位文件系统的数据。ZFS的设计如此超前以至于这个极限就当前现实实际可能永远无法遇到。项目领导Bonwick曾说：“要填满一个128位的文件系统，将耗尽地球上所有存储设备。除非你拥有煮沸整个海洋的能量，不然你不可能将其填满。”

以下是ZFS的一些理论极限：

- 248—任意文件系统的快照数量（2×1014）
- 248—任何单独文件系统的文件数（2×1014）
- 16 EiB (264 字节)—文件系统最大尺寸
- 16 EiB (264 字节)—最大单个文件尺寸
- 16 EiB (264 字节)—最大属性大小
- ~2.88×1015 ZiB (2128 字节)—最大zpool大小
- 256—单个文件的属性数量（受ZFS文件数量的约束，实际为248）
- 256—单个目录的文件数（受ZFS文件数量的约束，实际为248）
- 264—单一zpool的设备数
- 264—系统的zpools数量
- 264—单一zpool的文件系统数量

作为对这些数字的感性认识，假设每秒钟创建1,000个新文件，达到ZFS文件数极限需要大约9,000年。

在辩解填满ZFS与煮沸海洋的关系时，Bonwick写到：

尽管我们都希望摩尔定律永远延续，但是量子力学给定了任何物理设备上计算速率（computation rate）与信息量的理论极限。举例而言，一个zh-hans;zh-hant|质量为1公斤，体积为1升的物体，每秒至多在1031位信息上进行1051次运算。一个完全的128位存储池将包含2128个块`=` 2137字节`=` 2140位；应此，保存这些数据位至少需要(2140位) / (1031位/公斤) `=` 1360亿公斤的物质。

## 写入时复制事务模型

ZFS采用写入时复制事务对象模型。文件系统中的所有块指向都包含目标块的256位校验和或hash值（目前有Fletcher-2、 Fletcher-4与SHA-2供选择）。在读取块时会对这些参数加以验证。包含活动数据的块不会被覆盖，而是给修改过的数据分配一个新块，任何引用此块的元数据块都被重新读取、重新分配和重写。为减少该过程的开销，多次读写更新会被归纳为一个事件组，在需要同步写入语义时会使用ZIL（目的日志）写入缓存，而这些块会与校验和一同编入Merkle 树中。

利用写入时复制使ZFS的快照和事务功能的实现变得更简单和自然，快照功能更灵活，但严重碎片化问题是其缺点之一。对于通过顺序写生成的大文件，如果以后随机的对其中的一部分进行了更改，那么这个文件在硬盘上的物理地址就变得不再连续，未来的顺序读会变得性能比较差。

## 快照与克隆

当ZFS写入新数据时，可以保留包含旧数据的块，因而能够维护文件系统的快照版本。ZFS快照具备一致性（快照基于单个时间点反映整个数据）。而因为组合快照的所有数据都会被储存，且整个存储池通常每小时会进行几次快照，所以快照的创建速度非常快。任何未变动的数据会在文件系统及其快照之间进行共享，因此也具备空间高效性。快照本质上是只读的，确保在创建后快照不会被修改。快照可以被整个恢复，也可以恢复快照中的某些文件或目录。

ZFS也可以创建可写快照（“克隆”），让两个独立的文件系统共享一组块。对克隆文件系统的修改都会创建新的数据块以反映这些更改。但是无论存在多少个克隆，未变动的块仍然会被共享。这是写入时复制原则的实施方式。

## 动态条带化

ZFS能动态条带化所有设备以最大化吞吐量。当额外的设备被加入到zpool中的时候，条带宽度会自动zh-hans;zh-hant|扩展以包含这些设备。这使得存储池中的所有磁盘都被用到，同时负载被平摊到所有的磁盘上。

## 可变块尺寸

ZFS使用可变大小的块，最大可至128 KB。现有的代码允许管理员调整最大块大小，这在大块效果不好的时候有用。未来也许能做到自动调整适合工作量的块大小。需要引用

ZFS的可变大小的块与BtrFS和Ext4的extent不同。在ZFS中，在一个文件中所有数据块的逻辑长度必须是相同的，不同文件之间的块大小可以不同，因此ZFS可以用直接映射（direct map）的方式（同ufs/ffs/ext2/ext3）来来搜索间接块的数据指针数组（blkptr）。BtrFS和Ext4的extent方式在同一个文件中每个数据块的大小都可以不相同，因此需要用B+树或者类B树的方式来组织间接块的数据。

虽然直接映射方式比B+树的查找速度快，但是这种方式的缺点也非常明显，如：元数据开销过大、顺序IO的大文件性能不好、删除比较慢等等，因此在现代文件系统中映射方式逐渐被extent变长块取代。

如果数据压缩（LZJB）被启用，可变块大小需要被用到。如果一个数据块可被压缩至一个更小的数据块，则小的数据块将使用更少的存储和提高吞吐量（代价是增加CPU压缩和解压缩的负担）。

## 轻量化文件系统创建

在ZFS中，存储池中文件系统的操作相比传统文件系统的卷管理更加便捷。创建ZFS文件系统或者改变一个ZFS文件系统的大小接近于传统技术中的管理目录而非管理卷。

## 限制

ZFS的最新beta版已支持透明加密。

## 专利争端

NetApp指控Sun的ZFS文件系统侵犯了它WAFL的七项专利，Sun 反诉NetApp侵犯了12项专利，其中包括NFS协议等。后来专利争端以和解告终。

## 对其支持的操作系统

- Sun Solaris
- OpenSolaris
- Illumos发行版
- OpenIndiana
- FreeBSD
- Mac OS X Server 10.5
- NetBSD
- Linux（通过用户空间文件系统或原生第三方内核可载入核心模组支持）

## 外部链接

- ZFS主页
- ZFS on Linux - 美国劳伦斯利福摩尔国家实验室的ZFS on Linux开源计划

## 基本资料

- 开发者：甲骨文公司
- 发布：OpenSolaris
- 发布：2005年11月
- 目录内容：可扩展哈希表
- 最长文件名：255字节
- 最大文件数量：248
- 最大卷容量：264字节（16 exabytes）
- max_capacity：256 UB（2128 bytes)
- 最大文件尺寸：264字节（16 Exabytes)
- 岔流：是（称作扩展文件属性）
- 属性：POSIX
- 文件系统权限：POSIX、NFSv4 ACLs
- 透明压缩：是
- 重复数据删除：是
- 透明加密：是
- 操作系统：见下