本文转载自:http://www.lupaworld.com/26540/viewspace-115379.html
05年时,第一次接触到ZFS,直觉感到这个文件系的架构新颖,有探究的愿望,可随着时间的流逝,回到Linux世界后,又把它抛在脑后了,再次看到ZFS,就无法释然了(据说Linus眼馋ZFS好久了,想把ZFS移植到Linux,取代EXT3,成为下一代Linux内核默认的文件系统)。
ZFS中的这个Z就是“Zettabyte”,也就是说存储量级是Zetta级,1Z=1024的3次方个T,而一个T又等于1024个G,我们可以看出zfs是一个海量级的文件系统。为什么需要海量级?想想未来的网络存储,企业和科学研究的数据量,现在的32位文件系统远难以承载了。ZFS这个128位的文件系统,估计存储整个地球的信息都没有问题了。FreeBSD社区的牛人,已经着手对ZFS进行了移植。
在ZFS的架构里,最底层的是存储池,所有的存储介质都放在这个存储介质里面,然后再在这个存储池上面部署ZFS的文件系统,下面这个图是zfs的整体架构,摘自http://www.opensolaris.org/os/community/zfs/source/ 的首页:该页对此图给予了解释:
三个主要组件:ZPL(ZFS POSIX Layer,ZFS POSIX 层)、DMU(Data Management Unit,数据管理单元)和 SPA( Storage Pool Allocator,存储池分配器)。
三个基本层:Interface Layer(接口层,与ZPL对应),Transactional Object Layer(事物对象层,与DMU对应),Pooled Storage Layer(存储池层,与SPA组件对应)。
从用户角度看:
文件系统使用者(Filesystem Consumers)
这些应用程序是基本的应用程序,可通过 POSIX 文件系统 API 单独与 ZFS 交互。实际上,每个应用程序都可归为此类别。系统调用是通过 OpenSolaris VFS 层传递到 ZPL的。
设备使用者(Device Consumers)
ZFS 提供了一种创建“仿真卷”的方式。对这些卷的备份通过存储池中的存储进行的,但在 /dev下显示为一个普通设备。这并不是典型的使用案例,不过有一些例子充分说明了这种功能的有用之处。有少量应用程序直接与这些设备交互,但对设备使用最多的还是,位于设备层之上的内核文件系统或目标驱动程序。
基于GUI的管理
Solaris 在内部版本 28 中提供了基于 Web 的 ZFS GUI。虽然还不是 OpenSolaris 的组成部分,但它是位于 JNI 层之上基于 Java 的 GUI 的一个示例。< /p>
管理程序
这些应用程序是管理 ZFS 文件系统或存储池的(包括检查属性和数据集分层结构)。尽管还有一些分散的程序(如zoneadm、zoneadmd、fstyp),但两个主要的应用程序还是 zpool(1M) 和 zfs(1M)。
zpool(1M)
此命令负责创建和管理 ZFS 存储池。其主要目的是分析命令行输入,将其转换为 libzfs 调用,并顺带处理出现的任何错误。此命令的源代码可在 usr/src/cmd/zpool 中找到。它包含以下文件:
zpool_main.c | 命令的主体,负责处理所有的参数和子命令 |
zpool_vdev.c | 负责将一系列 vdev 转换成 libzfs 中的 nvlist |
zpool_iter.c | 对系统中中一些或全部存储池进行循环处理 |
zpool_util.c | 其他实用程序 |
zfs(1M)
此命令负责创建和管理 ZFS 文件系统。与 zpool(1M) 类似,其目的实际上只是分析命令行参数并将处理结果传递到 libzfs。此命令的源代码可在 usr/src/cmd/zfs 中找到。它包含以下文件:
zfs_main.c | 命令的主体,负责处理所有的参数和子命令 |
zfs_iter.c | 对系统中一些或全部数据集进行循环处理 |
ZFS被InfoWorld 评选为 Best File System of 2008。
这里,重点讨论用户层的JNI和libzfs
JNI (Java Native Interface)是Java本地接口,本地方法被编译进动态链接库,在运行时由Java虚拟机载入。
在上面的图中,libzfs是Solaris中实现ZFS的本地库,而JNI是libzfs的Java封装,其目的是让用户以更加友好的方式使用ZFS。有了这个库,用户就可以方便地创建一个新的文件系统:
LibZFS zfs = new LibZFS();
ZFSObject newFS = zfs.create("rpool/kohsuke/test", ZFSType.FILESYSTEM);
newFS.mount();
... 或者撤销:
ZFSObject fs = zfs.open("rpool/kohsuke/test");fs.unmount();fs.destory();
当然,基于libzfs,所做的事情远不止这些,还可以查询文件系统信息,创建快照,回滚(roll back等等)。
更多的信息参看:https://zfs.dev.java.net/
它是应用程序与 ZFS 内核模块打交道的主要接口。此库为访问和处理存储池和文件系统提供了一种统一的、基于对象的机制(想象一下把用户解放出来的感觉)。其中与内核通信的基础机制是系统调用调用 ioctl(2)。libzfs的源代码可以在 usr/src/lib/libzfs 中找到。它包含以下文件:
libzfs_dataset.c | 用于处理数据集的主要接口 |
libzfs_pool.c | 处理存储池的主要接口 |
libzfs_changelist.c | 在子级中传播属性改变的实用程序 |
libzfs_config.c | 读取和处理存储池配置信息 |
libzfs_graph.c | 为数据集构建相关列表 |
libzfs_import.c | 搜索和导入存储池 |
libzfs_mount.c | 挂载、取消挂载和共享数据集。 |
libzfs_status.c | 根据存储池状态链接到 FMA 知识库文章 |
libzfs_util.c | 其他例程 |