我听说 ZFS 具有重复数据删除功能,因此您可以将同一文件保存在多个位置,但仅使用约 1 个副本的空间。我注意到我倾向于以音乐/图像/等结束。随着时间的推移,我的硬盘驱动器上的多个位置都出现了这种情况,我认为最好创建一个 ZFS 分区并将我的媒体移动到该分区。我很难找到如何做到这一点,或者是否可能。大多数教程都会说,“拿 3 个磁盘并将它们与 ZFS 一起进行 RAID”,但我使用的是带有单个磁盘的笔记本电脑,并且我不打算删除预先存在的操作系统。我看到有关 ZFS 分区的评论(https://serverfault.com/questions/628632/should-i-create-zfs-zpools-with-whole-disks-or-partitions),但我还没有找到任何解释如何将单个 ZFS 分区添加到现有磁盘的内容。这样的事可以做吗? (我的磁盘分区表类型是 msdos,顺便说一句,我运行的是 Ubuntu。)
答案1
如果您的目标是最大化媒体组织,同时保持节省的空间,则可以通过为媒体库布置目录树,然后明智地使用cp
命令(复制数据)和ln
命令(创建硬或硬数据)来实现这一目标。软[如果-s
使用]链接)来访问或复制参考数据,即使只是为了方便在不同的目录中以不同的名称提供相同的文件。仍然是同一个文件,只是指向它的硬链接或软链接不同。
在手动层面上,从非常简单的角度来看,在重复的ln
同时进行去重cp
。
添加 ZFS 提供了直接的好处,即您不必ln
在要使用时才记住使用cp
.有很多用例,例如当媒体被故意分段、修改、编辑、排序等时,存储单独的媒体“剪辑”可以从 ZFS 重复数据删除中受益。
ZFS 的成本是重复数据删除相当消耗 RAM。内核必须将每个块的校验和或哈希存储在磁盘上,并在块写回池时实时访问该阵列。因此,当您的磁盘填满(写入更多 ZFS 块)时,更多的 RAM 会被填满,因为内核会缓存每个块数据的哈希值。根据您的笔记本电脑有多少 RAM 和多少磁盘,这可能会也可能不会成为问题,但最好要注意,重复数据删除的主要成本是拥有足够的 RAM 来存储整个磁盘的哈希数组。它可以用更少的 RAM 来完成,但是当内核试图在没有足够 RAM 来一次保存整个哈希数组的系统上将哈希数组分块换入和换出 RAM 时,写访问尤其会受到影响。
但话虽如此,尝试小型 ZFS 池的一种方法可能是:
创建虚拟块设备
我在这里使用 FreeBSD 命令,但步骤在 Ubuntu 上是类似的。我的示例块设备的大小为 10G,但如果有可用空间,您可以使用更大的大小。
ztest.dat
创建一个10G大小的文件:# truncate -s 10G ztest.dat
并创建一个由该文件支持的虚拟块设备:
# mdconfig -f ztest.dat
md0
那么我们的虚拟设备就是/dev/md0
。
创建简单的 ZPOOL 并启用重复数据删除
# zpool create ztest md0
# zfs set dedup=on ztest
# zpool status ztest
pool: ztest
state: ONLINE
config:
NAME STATE READ WRITE CKSUM
ztest ONLINE 0 0 0
md0 ONLINE 0 0 0
errors: No known data errors
这会将ztest
文件系统挂载在/ztest
。我们还制作一个简单的 shell 函数,它将快速显示/ztest
目录、文件系统和 ZFS 池的一些基本统计信息:
zlist() {
zfs list ztest
echo
zfs get all ztest | egrep 'used|refer'
echo
zpool get dedupratio ztest
}
然后,使用这些工具,您可以在下面创建所需的媒体层次结构/ztest
并开始将一些示例媒体文件复制到/ztest
文件系统中:
# ls -l /ztest; echo; zlist
total 0
NAME USED AVAIL REFER MOUNTPOINT
ztest 114K 9.20G 24K /ztest
ztest used 114K -
ztest referenced 24K -
ztest usedbysnapshots 0B -
ztest usedbydataset 24K -
ztest usedbychildren 90K -
ztest usedbyrefreservation 0B -
ztest logicalused 42K -
ztest logicalreferenced 12K -
NAME PROPERTY VALUE SOURCE
ztest dedupratio 1.00x -
Adedupratio
为1.00表示没有进行重复数据删除;文件系统中数据的逻辑大小是池中存储的物理数据大小的 1.00 倍。
但我们还没有在其中复制任何内容!我们现在就这样做:
# cp -vp ~jim/my-fave-dvd.iso /ztest/copy1.iso
/home/jim/my-fave-dvd.iso -> /ztest/copy1.iso
并检查结果:
# ls -l /ztest; echo; zlist
total 3271173
-rw-r--r-- 1 jim jim 3347775488 Jul 1 2014 copy1.iso
NAME USED AVAIL REFER MOUNTPOINT
ztest 3.13G 6.08G 3.12G /ztest
ztest used 3.13G -
ztest referenced 3.12G -
ztest usedbysnapshots 0B -
ztest usedbydataset 3.12G -
ztest usedbychildren 7.18M -
ztest usedbyrefreservation 0B -
ztest logicalused 3.12G -
ztest logicalreferenced 3.12G -
NAME PROPERTY VALUE SOURCE
ztest dedupratio 1.00x -
重复数据删除率仍然是 1.00,因为我们只存储了第一个媒体文件的一个副本。让我们创建一个副本:
# cp -vp /ztest/copy1.iso /ztest/copy2.iso
/ztest/copy1.iso -> /ztest/copy2.iso
# ls -l /ztest; echo; zlist
total 6542345
-rw-r--r-- 1 jim jim 3347775488 Jul 1 2014 copy1.iso
-rw-r--r-- 1 jim jim 3347775488 Jul 1 2014 copy2.iso
NAME USED AVAIL REFER MOUNTPOINT
ztest 6.25G 6.07G 6.24G /ztest
ztest used 6.25G -
ztest referenced 6.24G -
ztest usedbysnapshots 0B -
ztest usedbydataset 6.24G -
ztest usedbychildren 10.6M -
ztest usedbyrefreservation 0B -
ztest logicalused 6.24G -
ztest logicalreferenced 6.24G -
NAME PROPERTY VALUE SOURCE
ztest dedupratio 2.00x -
现在的重复数据删除率为2.00,因为文件系统引用的逻辑数据比池中实际存储的数据大2.00倍。但请注意, 的输出zfs list
显示,尽管该USED
值已上升至6.25G
,但该AVAIL
值几乎没有变化,为6.07G
。让我们创建更多的副本:
# cp -vp /ztest/copy1.iso /ztest/copy3.iso
/ztest/copy1.iso -> /ztest/copy3.iso
# cp -vp /ztest/copy1.iso /ztest/copy4.iso
/ztest/copy1.iso -> /ztest/copy4.iso
# ls -lh /ztest; echo; zlist
total 13084690
-rw-r--r-- 1 jim jim 3.1G Jul 1 2014 copy1.iso
-rw-r--r-- 1 jim jim 3.1G Jul 1 2014 copy2.iso
-rw-r--r-- 1 jim jim 3.1G Jul 1 2014 copy3.iso
-rw-r--r-- 1 jim jim 3.1G Jul 1 2014 copy4.iso
NAME USED AVAIL REFER MOUNTPOINT
ztest 12.5G 6.07G 12.5G /ztest
ztest used 12.5G -
ztest referenced 12.5G -
ztest usedbysnapshots 0B -
ztest usedbydataset 12.5G -
ztest usedbychildren 10.6M -
ztest usedbyrefreservation 0B -
ztest logicalused 12.5G -
ztest logicalreferenced 12.5G -
NAME PROPERTY VALUE SOURCE
ztest dedupratio 4.00x -
现在,du
认为我们存储了 12G 的文件:
# du -h /ztest
12G /ztest
Yetzpool
显示我们只在池中分配了 3.14G 的数据,并且池中还有 6.36G 的未分配空间。
# zpool list ztest
NAME SIZE ALLOC FREE CKPOINT EXPANDSZ FRAG CAP DEDUP HEALTH ALTROOT
ztest 9.50G 3.14G 6.36G - - 0% 33% 4.00x ONLINE -
相当于使用ln
不带重复数据删除的
另一方面,缺乏重复数据删除的文件系统仍然可以明智地使用来实现相同的目的,并且可能在复杂性、RAM 要求和速度方面花费更少。
# zpool destroy ztest
# zpool create ztest md0
# cp -vp ~jim/my-fave-dvd.iso /ztest/copy1.iso
/home/jim/my-fave-dvd.iso -> /ztest/copy1.iso
# ln /ztest/copy1.iso /ztest/copy2.iso
# ln /ztest/copy1.iso /ztest/copy3.iso
# ln -s /ztest/copy1.iso /ztest/copy4.iso
所以现在我们仍然有一个文件,可以从四个不同的位置访问(主副本copy1.iso
和副本copy2
- copy4.iso
)。
du
显示我们存储了 3.1G 的文件:
# du -h /ztest
3.1G /ztest
ls
向我们展示了许多 inode 编号是相同的(硬链接),并且一个文件是符号链接。使用ln
允许我们将同一文件放置在多个位置,而不会产生任何额外的存储开销。
# ls -lih /ztest
total 9813518
2 -rw-r--r-- 3 jim jim 3.1G Jul 1 2014 copy1.iso
2 -rw-r--r-- 3 jim jim 3.1G Jul 1 2014 copy2.iso
2 -rw-r--r-- 3 jim jim 3.1G Jul 1 2014 copy3.iso
128 lrwxr-xr-x 1 root wheel 16B Oct 7 13:25 copy4.iso -> /ztest/copy1.iso
zfs 文件系统显示已使用 3.1G,可用 6.1G:
# zlist
NAME USED AVAIL REFER MOUNTPOINT
ztest 3.12G 6.08G 3.12G /ztest
ztest used 3.12G -
ztest referenced 3.12G -
ztest usedbysnapshots 0B -
ztest usedbydataset 3.12G -
ztest usedbychildren 189K -
ztest usedbyrefreservation 0B -
ztest logicalused 3.12G -
ztest logicalreferenced 3.12G -
NAME PROPERTY VALUE SOURCE
ztest dedupratio 1.00x -
同样zpool
显示我们已经分配了 3.12G 并且有 6.38G 可用。
# zpool list ztest
NAME SIZE ALLOC FREE CKPOINT EXPANDSZ FRAG CAP DEDUP HEALTH ALTROOT
ztest 9.50G 3.12G 6.38G - - 0% 32% 1.00x ONLINE -
我希望这个示例能够鼓励您开发自己的测试框架来试验 ZFS 重复数据删除,并看看成本/效益比是否适合您。
回避问题
文件支持的虚拟设备上的 ZFS 池实验框架并不是将 ZFS 池添加到现有系统的长期解决方案。但它可以帮助您确定当前的硬件是否可以提供必要的资源,以及特定用例中的数据和数据处理实践是否可以利用 ZFS 提供的优势。
如果您发现添加 ZFS 池是一个理想的目标,那么每当您使用新的磁盘分区和文件系统时,您就需要考虑以下通常的先决条件:
- 您最近备份过吗?现在就这样做!
- 您的磁盘上已有空分区吗?非常便利。
- 没有可用的空分区?那么,您当前的文件系统中是否有足够的未使用空间,您可以对其进行备份、调整大小到较小的分区并恢复数据,从而将新腾出的空间可用于专用于 ZFS 的新分区?
- 您可以购买一个新的、更大的驱动器并在那里创建大小合适的分区来保存当前的文件系统以及新的 ZFS 分区吗?
一旦你拥有:
- 备份您现有的文件系统
- 用于 ZFS 的专用分区(我们称之为
/dev/sda3
) - 决定您希望将 ZFS 池安装在
/tank
您可以使用以下命令将 ZFS 池添加到现有系统:
# zpool create tank /dev/sda3
如果需要,您可以通过以下方式启用重复数据删除:
# zfs set dedup=on tank
请记住,这将是一个非冗余池:如果您的驱动器出现故障,您的数据就会丢失。 zpool scrub
操作将能够检测数据损坏,但无法纠正发现的任何错误。
享受!