Linux 数据去重

Lessfs 提供了一种灵活的解决方案,可以在经济实惠的商用硬件上使用数据去重。

近年来,存储行业一直致力于为其客户提供一些最先进的功能,包括数据去重。数据去重是一种独特的数据压缩技术,用于消除冗余数据并减少启用去重功能的存储卷上消耗的总容量。卷可以指磁盘设备、分区或一组磁盘设备,所有这些设备都表示为单个设备。在去重过程中,冗余数据被删除,只留下数据的单个副本存储在存储卷上。

一个理想的用例场景是,当大型电子邮件消息的多个副本被分发并存储在邮件服务器上时。大小仅为几兆字节的电子邮件消息似乎不算太糟糕,但如果它被发送并转发给 100 多个收件人,那就是超过 200MB 的相同文件副本。

另一个很好的例子是在主机虚拟化领域。近年来,虚拟化已成为服务器管理中最热门的趋势。如果您正在跨网络部署可能共享相同通用操作系统映像的多个虚拟机,数据去重可以显著减少消耗的总容量,仅保留单个副本,并在需要时引用差异。

同样,这项技术的主要重点是识别可以包括整个文件或文件的大部分相同部分的庞大数据段,并仅存储一个副本。其他好处包括降低额外存储设备容量的成本,这反过来可以用于增加卷大小或保护大量现有卷(例如 RAID、存档等)。使用更少的存储设备还可以降低能源、空间和冷却成本。

数据去重有两种类型:后处理去重和在线去重。每种都有其优点和缺点。总结来说,后处理去重发生在数据写入存储卷之后,在一个单独的过程中进行。虽然您在计算必要的去重时不会损失性能,但在后处理去重完成之前,单个文件的多个副本将被多次写入,如果可用容量变低,这可能会成为问题。在在线去重期间,所需的存储空间更少,因为所有去重都在数据写入存储卷时实时处理,尽管您会注意到性能下降,因为该过程会尝试识别传入数据的冗余副本。

存储技术制造商一直在提供这项技术,作为其专有和外部存储解决方案的一部分,但在 Linux 中,也可以在商用且非常经济实惠的硬件上使用相同的技术。这些存储技术制造商提供的解决方案在某些情况下仅在物理设备级别(即块级别)可用,并且只能处理冗余的数据块流,而不能处理单个文件,因为逻辑无法识别最常用的协议(如 SCSI、串行连接 SCSI (SAS)、光纤通道、InfiniBand 甚至串行 ATA (SATA))上的单独文件。这被称为分块方法。我在这里介绍的文件系统是 Lessfs,一个基于块级别去重且启用 FUSE 的 Linux 文件系统。

FUSE 或用户空间文件系统是类 UNIX 操作系统上常见的内核模块,它使用户能够在不接触内核代码的情况下创建自己的文件系统。它旨在用户空间中运行文件系统代码,而 FUSE 模块充当与内核接口通信的桥梁。

为了使用这些文件系统,需要在系统上安装 FUSE。大多数主流 Linux 发行版(如 Ubuntu 和 Fedora)很可能已经预装了模块和用户空间工具,最有可能用于支持 ntfs-3g 文件系统。

Lessfs

Lessfs 是一个为 Linux 编写的高性能在线数据去重文件系统,目前已获得 GNU 通用公共许可证版本 3 的许可。它还支持 LZO、QuickLZ 和 BZip 压缩(以及其他几种),以及数据加密。在撰写本文时,最新的稳定版本是 1.3.3.1,可以从 SourceForge 项目页面下载:http://sourceforge.net/projects/lessfs/files/lessfs

在安装 lessfs 软件包之前,请确保安装了它的所有已知依赖项。其中一些(如果不是大多数)依赖项可能在您的发行版的软件包存储库中可用。您需要手动安装一些,包括 mhash、tokyocabinet 和 fuse(如果尚未安装)。

您的发行版可能具有 mhash2 的库(可用或已安装),但 lessfs 仍然需要 mhash。这也可以从 SourceForge 下载:http://sourceforge.net/projects/mhash/files/mhash。在撰写本文时,最新的稳定版本是 0.9.9.9。下载、构建并安装软件包


$ tar xvzf mhash-0.9.9.9.tar.gz
$ cd mhash-0.9.9.9/
$ ./configure
$ make
$ sudo make install

Lessfs 还需要 tokyocabinet,因为它是它所依赖的主要数据库。最新的稳定版本是 1-4.47。要构建 tokyocabinet,您需要预先安装 zlib1g-dev 和 libbz2-dev,它们通常由大多数(如果不是全部)主流 Linux 发行版提供。

使用与之前相同的 configuremakesudo make install 命令下载、构建并安装软件包。在 32 位系统上,您需要将 --enable-off64 附加到 configure 命令。未能使用 --enable-off64 会将数据库限制为 2GB 文件大小。

如果尚未安装 FUSE,或者您想使用最新、最稳定的 FUSE 版本,请从 SourceForge 下载:http://sourceforge.net/projects/fuse。在撰写本文时,最新的稳定版本是 2.8.5。使用与之前相同的 configuremakesudo make install 命令下载、构建并安装软件包。

在解决了所有更晦涩的依赖项之后,您就可以构建和安装 lessfs 软件包了。使用与之前相同的 configuremakesudo make install 命令下载、构建并安装软件包。

现在您已准备就绪,但在执行任何操作之前,需要进行一些准备。在 lessfs 源代码目录中,有一个名为 etc/ 的子目录,其中包含一个配置文件。将配置文件复制到系统的 /etc 目录路径


$ sudo cp etc/lessfs.cfg /etc/

此文件定义了数据库的位置以及一些其他详细信息(我将在本文后面讨论,但现在让我们专注于启动并运行文件系统)。您将需要为文件数据(默认为 /data/dta)以及元数据(默认为 /data/mta)创建目录路径,用于发送到/从 lessfs 文件系统的所有文件 I/O 操作。创建目录路径


$ sudo mkdir -p /data/{dta,mta}

使用 mklessfs 命令初始化目录路径中的数据库


$ sudo mklessfs -c /etc/lessfs.cfg

-c 选项用于指定配置文件的路径和名称。该命令没有手册页,但您仍然可以使用 -h 命令选项调用在线菜单。

现在数据库已初始化,您可以挂载启用 lessfs 的文件系统了。在以下示例中,让我们将其挂载到 /mnt 路径


$ sudo lessfs /etc/lessfs.cfg /mnt

挂载后,文件系统假定它是挂载到的文件系统的总容量。在我的例子中,它是 /dev/sda1 上的文件系统


$ df -t fuse.lessfs
Filesystem        1K-blocks      Used Available Use% Mounted on
lessfs              5871080   3031812   2541028  55% /mnt

$ df -t ext4
Filesystem        1K-blocks      Used Available Use% Mounted on
/dev/sda1           5871080   3031812   2541028  55% /

目前,当列出新挂载的 lessfs 卷的内容时,您应该只会看到一个隐藏的 .lessfs 子目录


$ ls -a /mnt/
.  ..  .lessfs

挂载后,可以像卸载任何其他卷一样卸载 lessfs 卷


$ sudo umount /mnt

让我们测试一下卷。将文件数据写入 lessfs 卷与写入任何其他文件系统没有什么不同。在下面的示例中,我使用 dd 命令将大约 100MB 的全零数据写入 /mnt/test.dat


$ sudo dd if=/dev/zero of=/mnt/test.dat bs=1M count=100
100+0 records in
100+0 records out
104857600 bytes (105 MB) copied, 5.05418 s, 20.7 MB/s

考虑到文件系统旨在消除所有冗余数据副本,并且填充全零的文件可以作为这方面的主要示例,您可以观察到仅消耗了 48KB 的容量,这可能仅仅是将必要数据同步到数据库所需的数据


$ df -t fuse.lessfs
Filesystem        1K-blocks      Used Available Use% Mounted on
lessfs              5871080   3031860   2540980  55% /mnt

如果您在启用 lessfs 的目录中列出同一文件的详细列表,则会显示已写入所有 100MB。利用其嵌入式逻辑,当对文件启动额外的读取和写入操作时,lessfs 会动态重建所有数据


$ ls -l
total 102400
-rw-r--r-- 1 root root 104857600 2011-02-26 13:57 test.dat

现在,让我们处理一些更复杂的东西——一些包含大量随机数据的东西。对于此示例,我决定从 https://linuxkernel.org.cn 下载最新的 Linux 内核源代码稳定候选版本,但在执行此操作之前,我列出了 lessfs 卷上可用的总消耗容量作为参考点


$ df -t fuse.lessfs
Filesystem        1K-blocks      Used Available Use% Mounted on
lessfs              5871080   3031896   2540944  55% /mnt

$ sudo wget https://linuxkernel.org.cn/pub/linux/kernel/v2.6/
↪testing/linux-2.6.38-rc6.tar.bz2

列出内容,您可以看到软件包大约为 75MB


$ ls -l linux-2.6.38-rc6.tar.bz2 
-rw-r--r-- 1 root root 74783787 2011-02-21 19:50 
 ↪linux-2.6.38-rc6.tar.bz2

列出用于存储 Linux 内核源代码存档的容量,得出大约 75MB 的差异


$ df -t fuse.lessfs
Filesystem        1K-blocks      Used Available Use% Mounted on
lessfs              5871080   3106440   2466400  56% /mnt

现在,让我们创建存档内核源代码的副本


$ sudo cp linux-2.6.38-rc6.tar.bz2 linux-2.6.38-rc6.tar.bz2-bak

$ ls -l linux-2.6.38-rc6.tar.bz2*
-rw-r--r-- 1 root root 74783787 2011-02-21 19:50 
 ↪linux-2.6.38-rc6.tar.bz2
-rw-r--r-- 1 root root 74783787 2011-02-26 14:43 
 ↪linux-2.6.38-rc6.tar.bz2-bak

通过拥有同一文件的冗余副本,额外消耗了 44KB——远不及额外的 75MB


$ df -t fuse.lessfs
Filesystem        1K-blocks      Used Available Use% Mounted on
lessfs              5871080   3106484   2466356  56% /mnt

而且,由于数据库包含实际文件和元数据,如果发生意外或有意的系统重启,或者如果由于任何原因您需要卸载文件系统,物理数据都不会丢失。您所需要做的就是调用相同的挂载命令,一切都会恢复


$ sudo umount /mnt/
$ sudo lessfs /etc/lessfs.cfg /mnt
$ ls
linux-2.6.38-rc6.tar.bz2  linux-2.6.38-rc6.tar.bz2-bak

在系统遭受意外重启(可能是由于断电)的情况下,从 1.0.4 版本开始,lessfs 支持事务,这消除了崩溃后进行 fsck 的需要。

将焦点转回 lessfs 准备工作,请注意,用户可以在挂载时定义 lessfs 卷的选项。例如,您可以为 big_write、max_read 和 max_write 定义所需的选项。big_write 提高了用于备份目的时的吞吐量,并且必须同时定义 max_read 和 max_write 才能使用它。max_read 和 max_write 选项必须始终彼此相等,并定义 lessfs 要使用的块大小:4、8、16、32、64 和 128KB。

块大小的定义可用于调整文件系统。例如,较大的块大小(如 128KB (131072))提供更快的性能,但不幸的是,以降低去重效果为代价(请记住,lessfs 使用块级去重)。所有其他选项都是 FUSE 文档中定义的 FUSE 通用选项。支持的挂载选项的使用示例可以在 lessfs 手册页中找到


$ man 1 lessfs

以下示例给出了如何以 128KB 块大小挂载 lessfs


$ sudo lessfs /etc/lessfs.cfg /fuse -o negative_timeout=0,\
        entry_timeout=0,attr_timeout=0,use_ino,\
        readdir_ino, default_permissions,allow_other,big_writes,\
        max_read=131072,max_write=131072

数据库的其他可配置选项存在于您的 lessfs.cfg 文件中(您之前复制到 /etc 目录路径的同一文件)。块大小也可以在此处定义,甚至可以在去重数据上使用的额外数据压缩方法等等。以下是配置文件包含内容的摘录。为了清楚地定义各种选项的新值,只需取消注释所需的选项,反过来,注释掉所有其他选项


BLKSIZE=131072
#BLKSIZE=65536
#BLKSIZE=32768
#BLKSIZE=16384
#BLKSIZE=4096
#COMPRESSION=none
COMPRESSION=qlz
#COMPRESSION=lzo
#COMPRESSION=bzip
#COMPRESSION=deflate
#COMPRESSION=disabled

此摘录将默认块大小定义为 128KB,默认压缩方法定义为 QuickLZ。如果默认值不符合您的喜好,您还可以在此文件中定义提交到磁盘的间隔(默认为 30 秒)或数据库的新路径,但请确保在使用前初始化数据库;否则,当您尝试挂载 lessfs 文件系统时,您将收到错误。

总结

现在,Linux 不仅限于单一的数据去重解决方案。还有 SDFS,一个文件级去重文件系统,它也在 FUSE 模块上运行。SDFS 是一个由 Opendedup 项目提供的免费跨平台解决方案(Linux 和 Windows)。在其官方网站上,该项目强调了文件系统的可扩展性(它可以去重 PB 级或更多的数据);速度,以 290MB/s 及以上的线速执行去重/再重;支持 VMware,同时还提及其在 Xen 和 KVM 中的使用;存储的灵活性,因为去重数据可以本地存储、在跨多个节点(NFS/CIFS 和 iSCSI)的网络上存储或在云中存储;在线和批处理模式去重(一种后处理去重方法);以及文件和文件夹快照支持。该项目似乎正在将自己推向企业级解决方案,并且凭借这些功能,Opendedup 的确是认真的。

自 2008 年以来,数据去重一直是 Btrfs(下一代 Linux 文件系统)的请求功能,这也就不足为奇了。尽管这也可能是对 Sun Microsystem(现在的 Oracle)将其数据去重开发到其高级 ZFS 文件系统中的回应。不幸的是,目前尚不清楚 Btrfs 何时以及是否会引入数据去重支持,尽管它已经包含对各种类型数据压缩(如 zlib 和 LZO)的支持。

目前,lessfs2 版本正在开发中,它应该会引入快照支持、快速 inode 克隆、除 tokyocabinet 之外的新数据库(包括 hamsterdb 和可能的 BerkeleyDB)、自愈 RAID(以修复损坏的块)等等。

如您所见,只需花费少量时间和精力,就可以相对简单地利用最近的数据去重趋势来减少存储卷上消耗的总容量,方法是删除所有冗余的数据副本。我建议不仅在服务器管理中使用它,甚至在个人使用中使用它,主要是因为对于像 lessfs 这样的实现,即使没有太多冗余数据,额外的数据压缩也将有助于减小文件最终写入磁盘时的总大小。还值得一提的是,启用 lessfs 的卷不需要保持在本地主机系统上,但也可以通过 NFS 甚至 iSCSI 导出到网络上,并供同一网络内的其他设备使用,从而提供更灵活的解决方案。

资源

Lessfs 项目官方网站:http://www.lessfs.com

Lessfs SourceForge 项目:http://sourceforge.net/projects/lessfs

Opendedup (SDFS) 项目:http://www.opendedup.org

维基百科:数据去重:http://en.wikipedia.org/wiki/Data_deduplication

关于将 Lessfs 集成到 Fedora 15 的说明:http://fedoraproject.org/wiki/Features/LessFS

Lessfs 与 SCST 使用方法:http://www.lessfs.com/wordpress/?page_id=577

Petros Koutoupis,LJ 特约编辑,目前是 Cray 公司 Lustre 高性能文件系统部门的高级性能软件工程师。他还是 RapidDisk 项目的创建者和维护者。Petros 在数据存储行业工作了十多年,并帮助开创了当今广泛应用的许多技术。

加载 Disqus 评论