存储数据的管理通常涉及两个方面:对一个或多个块存储设备(如硬盘驱动器和SD卡)进行物理卷管理,并将它们组织成操作系统所看到的逻辑块设备(通常涉及卷管理器、RAID控制器、阵列管理器或合适的设备驱动程序),以及对存储在这些逻辑块设备(文件系统或其他数据存储)上的数据和文件进行管理。
与其他文件系统不同的是zfs充当着卷管理和文件系统的角色,这意味着ZFS可以创建一个跨越池和硬盘的文件系统,可以通过添加硬盘来增大池的存储容量
zpool是支撑zfs的最高层结构,由vdev组成
存储vdev
-
single:最简单的vdev类型,就是给定数量的硬盘
-
mirror:对于每一个写入的vdev都有一个副本
-
raidz1:1磁盘奇偶校验,类似于raid-5
-
raidz2:2磁盘奇偶校验,类似于raid-6
-
raidz3:3磁盘奇偶校验
支持vdev
-
log:作为防止崩溃的日志。在写入时会先写入log,然后到主存
-
cache:用于拓展zfs的内存缓存
-
special:允许存储系统元数据与主存分开,采用非常快的ssd,对于延迟敏感的操作(如小的数据库操作)更好
但这也意味着如果special坏了,那就全坏。此类型在zfs0.8之后支持
-
spare:备用空间。用于驱动器发生故障时进行更换,但不能替换缓存、日志vdev
读写效率与保障
效率
zfs采用以下策略自动在pool中所有vdev分配存储数据
- 尽可能写入相对较少数据的vdev,从而保证当池被更多地使用时,不会出现某些vdev被填满的情况。
- 读取时从尽可能多的磁盘读取数据的不同部分,从而提供更高的读取性能
写时拷贝
在重写时将会将新数据写到不同块,在写完成之后,更新文件系统元数据使之指向新数据块。那么即使在写的时候系统崩溃,那么原数据也会被保存下来
快照
追踪文件系统的更改
数据完整性
数据完整性是通过在整个文件系统树中使用基于fletcher的校验和或SHA-256哈希来实现的。
- 对每个数据块进行校验和,然后将校验和值保存在指向该块的指针中,而不是保存在实际块本身中。
- 对块指针进行校验和,并将值保存在其指针处。
- 这个校验和继续沿着文件系统的数据层次结构一直到根节点,根节点也被校验和,从而创建了一个Merkle树。
大多数文件系统无法检测到运行中的数据损坏或幻读/写(数据写/读的校验和是正确的,但实际上是错误的),因为它们将校验和与数据一起存储。ZFS将每个块的校验和存储在它的父块指针中,这样整个池就可以自我验证了
在写入数据时会创建校验和,若读取时不匹配就会尝试通过冗余的数据自动修复错误
当然这种冗余带来的后果就是实际可用储存容量将会大幅下降
RAID-Z
RAID-Z是RAID-5变种,属于ZFS的RAID实现。允许更好地分配奇偶性,并消除了raid-5的”write hole“问题
wire hole问题指的是由于写过程的非原子性,系统崩溃或写操作的其他中断可能导致奇偶校验与数据不一致的状态,这样在磁盘故障的情况下,奇偶校验不能用于恢复。
RAID- z与RAID-5类似,是一种数据/校验分布方案,但使用了动态条带宽度。每个块都是自己的RAID条带,而不管块大小,因此每次RAID- z写操作都是全条带写。当与ZFS的写时复制事务语义结合使用时,可以消除write hole错误。RAID- z也比传统的RAID 5快,因为它不需要执行通常的读-修改-写序列
形形色色的不同大小,raid - z重建必须遍历文件系统元数据来确定实际的raid - z几何。如果文件系统和RAID阵列是两个独立的产品,这是不可能的,但如果数据的逻辑和物理结构有一个完整的视图,这是可行的。通过元数据意味着ZFS可以验证每个块的256位校验和,而传统的RAID产品通常不能这样做
除了处理全磁盘故障,RAID-Z还可以检测和纠正无声的数据损坏,提供“自修复数据”:当读取RAID-Z块时,ZFS将其与其校验和进行比较,如果数据磁盘没有返回正确的答案,ZFS读取校验,然后计算出哪个磁盘返回了坏数据。然后对受损数据进行修复,并将完好数据返回给请求者
RAID- z有五种不同的模式:striping(类似于RAID 0,没有冗余),RAID- z1(类似于RAID 5,允许一个硬盘故障),RAID- z2(类似于RAID 6,允许两个硬盘故障),RAID- z3 (RAID 7[a]配置,允许三个硬盘故障),镜像(类似于RAID 1,允许一个硬盘故障)
恢复
zfs没有fsck(标准unix文件系统数据检查和修复工具),而是存在一个内置的scrub用于周期性检查并修复。与fsck主要区别在于
-
fsck必须运行在脱机文件系统,这就意味着文件系统不能被挂载。而scrub则用于已经挂载的、活动的文件系统
-
FSCK通常只检查元数据(如日志日志),但从不检查数据本身。这意味着,在执行fsck之后,数据可能仍然与存储的原始数据不匹配。
Scrub检查所有内容,包括元数据和数据
大储存
设计为128bit文件系统,这意味着每个zpool可以提供 3 ∗ 1 0 24 3*10^{24} 3∗1024TB
Ref
- https://en.wikipedia.org/wiki/ZFS
- https://itsfoss.com/what-is-zfs/
- https://en.wikipedia.org/wiki/RAID
- https://zfs.m-jay.cn/understand-zfs
- https://www.reddit.com/r/zfs/comments/fn5ugg/zfs_topology_faq_whats_a_zpool_whats_a_vdev/