【转载】zfs文件系统架构解读

本文转载自:http://www.lupaworld.com/26540/viewspace-115379.html 

 

05年时,第一次接触到ZFS,直觉感到这个文件系的架构新颖,有探究的愿望,可随着时间的流逝,回到Linux世界后,又把它抛在脑后了,再次看到ZFS,就无法释然了(据说Linus眼馋ZFS好久了,想把ZFS移植到Linux,取代EXT3,成为下一代Linux内核默认的文件系统)。

    ZFS中的这个Z就是Zettabyte”,也就是说存储量级是Zetta级,1Z=10243次方个T,而一个T又等于1024G,我们可以看出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 其他例程

你可能感兴趣的:(【转载】zfs文件系统架构解读)