Red Hat Training

A Red Hat training course is available for RHEL 8

重复数据删除和压缩存储

Red Hat Enterprise Linux 8

使用 VDO 优化 RHEL 8 中的存储容量

Red Hat Customer Content Services

摘要

本文档集合提供了如何使用 Virtual Data Optimizer(VDO)来管理 Red Hat Enterprise Linux 8 中去除重复数据和压缩的存储池的说明。

使开源包含更多

红帽承诺替换我们的代码、文档和网页属性中存在问题的语言。我们从这四个术语开始: master、slave、blacklist 和 whitelist。这些更改将在即将发行的几个发行本中逐渐实施。如需了解更多详细信息,请参阅 CTO Chris Wright 信息

对红帽文档提供反馈

我们感谢您对我们文档的反馈。让我们了解如何改进它。

通过 Jira 提交反馈(需要帐户)

  1. 登录到 Jira 网站。
  2. 单击顶部导航栏中的 Create
  3. Summary 字段中输入描述性标题。
  4. Description 字段中输入您对改进的建议。包括文档相关部分的链接。
  5. 点对话框底部的 Create

第 1 章 部署 VDO

作为系统管理员,您可以使用 VDO 创建去除重复数据的和压缩的存储池。

1.1. VDO 简介

Virtual Data Optimizer(VDO)以重复数据删除(deduplication)、压缩和精简置备的形式为 Linux 提供内联数据降低。当您设置 VDO 卷时,您可以指定一个块设备来构建 VDO 卷以及您要存在的逻辑存储量。

  • 当托管活动的虚拟机或容器时,红帽建议按 10:1 的逻辑与物理比例配置存储:也就是说,如果您使用 1TB 的物理存储,则将其显示为 10TB 的逻辑存储。
  • 对于对象存储,如 Ceph 提供的类型,红帽建议使用 3:1 的逻辑与物理比例:1TB 的物理存储将显示为 3TB 的逻辑存储。

在这两种情况下,您只需将文件系统放在 VDO 提供的逻辑设备之上,然后直接使用它,或将其作为分布式云存储架构的一部分。

由于 VDO 是迅速置备的,所以文件系统和应用程序只会看到使用中的逻辑空间,且不知道可用的实际物理空间。使用脚本来监控实际的可用空间,并在使用超过阈值时产生一个报警:例如,当 VDO 卷已满 80% 时。

其它资源

1.2. VDO 部署场景

您可以使用各种方法部署 VDO,来为以下情况提供去除重复数据的存储:

  • 块和文件的访问
  • 本地和远程存储

因为 VDO 会将其去除重复数据的存储公开为标准 Linux 块设备,所以您可以在标准文件系统、iSCSI 和 FC 目标驱动程序或者统一存储中使用它。

注意

目前,支持在 Ceph RADOS 块设备(RBD)上部署 VDO 卷。但是,目前不支持在 VDO 卷上部署 Red Hat Ceph Storage 集群组件。

KVM

您可以在配置了直接附加存储的 KVM 服务器上部署 VDO。

使用 KVM 部署 VDO

文件系统

您可以在 VDO 上创建文件系统,并通过 NFS 服务器或 Samba 将其公开给 NFS 或 CIFS 用户。

去除重复数据的 NAS

在 iSCSI 上放置 VDO

您可以将整个 VDO 存储目标作为 iSCSI 目标导出到远程 iSCSI 启动器。

去除重复数据的块存储目标

在 iSCSI 上创建 VDO 卷时,您可以将 VDO 卷放在 iSCSI 层之上或之下。尽管需要考虑许多注意事项,但此处提供了一些准则,来帮助您选择最适合您环境的方法。

当将 VDO 卷放在 iSCSI 层下方的 iSCSI 服务器(目标)上时:

  • VDO 卷对启动器是透明的,与其他 iSCSI LUN 类似。对客户端隐藏精简配置和节省空间后,更易于监控和维护 LUN 。
  • 网络流量会减少,因为没有对 VDO 元数据的读或写,并且在网络上不会发生对去除重复建议的读验证。
  • 在 iSCSI 目标上使用的内存和 CPU 资源可以带来更好的性能。例如,能够托管越来越多的 hypervisor ,因为在 iSCSI 目标上发生了卷减少。
  • 如果客户端在启动器上实现了加密,且在目标下面有一个 VDO 卷,则不会实现任何空间节省。

当将 VDO 卷放在 iSCSI 层上面的 iSCSI 客户端(启动器)上时:

  • 如果要取得较高的空间节省率,则异步模式下的网络流量可能会降低。
  • 您可以直接查看和控制空间节省,并监控使用情况。
  • 如果要加密数据,例如使用 dm-crypt,您可以在加密之上实现 VDO,并充分利用空间效率。

LVM

在功能丰富的系统上,您可以使用 LVM 来提供多个逻辑单元号(LUN),这些 LUN 都由相同的去除重复数据的存储池支持。

在下图中,VDO 目标被注册为一个物理卷,这样它可以由 LVM 来管理。从去除重复数据的存储池中创建多个逻辑卷(LV1LV4)。这样 VDO 便可支持多协议统一块或者对底层的去除重复数据的存储池的文件进行访问。

去除重复数据的统一存储

去除重复数据的统一存储设计可使多个文件系统通过 LVM 工具共同使用相同的去除重复数据的域。另外,文件系统可以利用 LVM 快照、写时复制、缩小或增长的功能,所有这些都位于 VDO 之上。

加密

DM Crypt 等设备映射器(DM)机制与 VDO 兼容。加密 VDO 卷有助于确保数据安全,且任何 VDO 以上的文件系统仍会是删除重复数据的。

使用带加密的 VDO
重要

应用上述 VDO 加密层会导致较少的(甚至不会导致)数据重复。在 VDO 可以对它们进行重复数据删除前,加密会使重复数据块不同。

始终将加密层放在 VDO 下。

1.3. VDO 卷的组件

VDO 使用块设备作为后备存储,它包括由一个或多个磁盘、分区甚至平面文件组成的物理存储聚合。当存储管理工具创建 VDO 卷时,VDO 为 UDS 索引和 VDO 卷保留卷空间。UDS 索引和 VDO 卷会一起交互,以提供重复的块存储。

图 1.1. VDO 磁盘机构

VDO 磁盘机构

VDO 解决方案包括以下组件:

kvdo

载入 Linux 设备映射器层的内核模块提供去除重复数据的、压缩的和精简配置的块存储卷。

kvdo 模块公开一个块设备。对于块存储,您可以直接访问块存储或通过 Linux 文件系统(如 XFS 或 ext4)呈现它。

kvdo 收到一个读取 VDO 卷中数据的逻辑块的请求时,它会将请求的逻辑块映射到底层的物理块上,然后读取并返回请求的数据。

kvdo 收到一个向 VDO 卷写数据块的请求时,它首先检查请求是 DISCARD 还是 TRIM 请求,或者数据是否统一为零。如果其中任何一个条件为真,则 kvdo 会更新其块映射,并确认请求。否则,VDO 会处理并优化数据。

uds

与卷上通用的去除重复数据服务(UDS)索引通信的内核模块,并分析数据的重复内容。对于每个新的数据,UDS 可以快速地判断该数据是否与之前存储的数据相同。如果索引发现匹配项,则存储系统可在内部引用现有项,以避免多次保存相同的信息。

UDS 索引作为 uds 内核模块运行在内核中。

命令行工具
用于配置和管理优化的存储。

1.4. VDO 卷的物理和逻辑大小

VDO 通过以下方法使用物理、可用物理和逻辑大小:

物理大小

这与底层块设备的大小相同。VDO 使用这个存储用于:

  • 用户数据,这些数据可能会进行重复数据删除和压缩
  • VDO 元数据,如 UDS 索引
可用物理大小

这是 VDO 可用于用户数据的物理大小的一部分

它等同于物理大小减去元数据的大小,再减去将卷根据指定的 slab 的大小分为 slab 后剩余的值。

逻辑大小

这是 VDO 卷在应用程序中的置备大小。它通常大于可用的物理大小。如果没有指定 --vdoLogicalSize 选项,则逻辑卷的调配现在被配置为 1:1 的比率。例如,如果将 VDO 卷放在 20GB 块设备之上,则为 UDS 索引保留 2.5 GB(如果使用默认索引大小)。剩余的 17.5 GB 为 VDO 元数据和用户数据提供。因此,要消耗的可用存储不超过 17.5 GB,且可能会因为组成实际 VDO 卷的元数据而减少。

VDO 目前支持任意逻辑卷大小最多为物理卷的 254 倍,但不能超过 4PB。

图 1.2. VDO 磁盘机构

VDO 磁盘机构

在这个图表中,VDO 重复数据删除存储对象完全位于块设备之上,这意味着 VDO 卷的物理大小与基本块设备大小相同。

其它资源

1.5. VDO 中的 Lab 大小

VDO 卷的物理存储被分成几个 slab。每个 slab 都是物理空间的连续区域。给定卷的所有 slab 的大小相同,可以是基于 128 MB 的 2 的指数的任何值,最大值为 32 GB。

默认的 slab 大小为 2 GB,以便于在较小的测试系统上评估 VDO。单个 VDO 卷最多可有 8192 个 slabs。因此,在使用 2GB slab 的默认配置中,允许的最大物理存储为 16 TB。当使用 32GB 的 slab 时,允许的最大物理存储为 256 TB。VDO 总是保留至少一个整个 slab 来保存元数据,因此预留 slab 无法用于存储用户数据。

slab 大小不影响 VDO 卷的性能。

表 1.1. 根据物理卷大小推荐的 VDO slab 大小

物理卷大小推荐的 slab 大小

10–99 GB

1 GB

100 GB – 1 TB

2 GB

2–256 TB

32 GB

注意

使用默认设置的 2 GB slab 和 0.25 密集索引的 VDO 卷的最小磁盘使用量大约需要 4.7 GB。这以 0% 去除重复数据或压缩的比率提供了略低于 2 GB 的物理数据的写入。

这里,最小的磁盘用量是默认 slab 大小和密度索引的总和。

您可以通过向 lvcreate 命令提供 --config 'allocation/vdo_slab_size_mb=size-in-megabytes' 选项来控制 slab 的大小。

1.6. VDO 要求

VDO 对其放置和系统资源有一定要求。

1.6.1. VDO 内存要求

每个 VDO 卷有不同的内存要求:

VDO 模块

VDO 需要固定的 38 MB RAM 和几个变化的量:

  • 配置的每 1 MB 的块映射缓存需要 1.15 MB 的 RAM。块映射缓存至少需要 150MB RAM。
  • 每 1 TB 的逻辑空间需要 1.6 MB 的 RAM。
  • 卷管理的每 1 TB 的物理存储需要 268 MB 的 RAM。
UDS 索引

通用去除重复数据服务(UDS)至少需要 250 MB 的 RAM,这也是去除重复数据所使用的默认数量。您可以在格式化 VDO 卷时配置值,因为该值也会影响索引所需的存储量。

UDS 索引所需的内存由索引类型和重复数据删除窗口所需大小决定:

索引类型重复数据删除窗口备注

密度

每 1 GB RAM 为 1 TB

1GB 密度索引一般足以满足 4TB 物理存储空间。

稀疏

每 1 GB RAM 为 10 TB

1 GB 稀疏索引一般足以满足40TB 物理存储空间。

注意

使用默认设置的 2 GB slab 和 0.25 密集索引的 VDO 卷的最小磁盘使用量大约需要 4.7 GB。这以 0% 去除重复数据或压缩的比率提供了略低于 2 GB 的物理数据的写入。

这里,最小的磁盘用量是默认 slab 大小和密度索引的总和。

UDS 稀疏索引功能是 VDO 推荐的模式。它依赖于数据的时间局部性,并尝试只在内存中保留最重要的索引条目。使用稀疏索引,UDS 维护一个重复数据删除窗口,它是密度的10 倍,但使用相同数量的内存。

稀疏索引提供了最高的覆盖,但密度索引提供了更多的重复数据删除建议。对于大多数工作负载,如果内存量相同,则密度和稀疏索引间的重复数据删除率的不同会微不足道。

1.6.2. VDO 存储空间要求

您可以将 VDO 卷配置为使用最多 256TB 物理存储。只有物理存储的某个部分可用来存储数据。本节提供了计算 VDO 管理的卷的可用空间大小的方法。

VDO 需要为两种类型的 VDO 元数据和 UDS 索引进行存储:

  • 第一类 VDO 元数据对于每 4GB 物理贮存使用 1 MB,再加上每个 slab 的额外的 1 MB。
  • 第二类 VDO 元数据对于每 1GB 逻辑存储使用 1.25 MB,并舍入到最近的 slab。
  • UDS 索引所需的存储量取决于索引类型以及分配给索引的 RAM 量。对于每 1 GB RAM,密度 UDS 索引使用 17GB 存储,稀疏 UDS 索引使用 170 GB 存储。

1.6.3. 将 VDO 放置到存储堆栈中

将存储层放在 Virtual Data Optimizer (VDO)之上或之下,以符合放置要求。

VDO 卷是一个精简配置的块设备。您可以通过将卷放在之后可以进行扩展的存储层上来防止耗尽物理空间。这种可扩展存储的示例是逻辑卷管理器(LVM)卷,或多设备冗余廉价阵列或独立磁盘(MD RAID)阵列。

您可以将厚置备层放在 VDO 之上。您必须考虑厚置备的层的两个方面:

  • 将新数据写入厚设备上未使用的逻辑空间。当使用 VDO 或其他精简置备存储时,设备可能会报告在这类写入过程中空间不足。
  • 使用新数据覆盖厚设备上使用的逻辑空间。使用 VDO 时,覆盖数据也会导致设备不足的报告。

这些限制会影响 VDO 层以上的所有层。如果不监控 VDO 设备,您可能会意外耗尽 VDO 之上厚置备卷上的物理空间。

请参阅以下支持和不支持的 VDO 卷配置示例。

图 1.3. 支持的 VDO 卷配置

支持的 vdo 放置

图 1.4. 不支持的 VDO 卷配置

不支持 vdo 放置

其它资源

  • 有关具有 LVM 层的堆栈 VDO 的详情,请参考 堆栈 LVM 卷 文章。

1.6.4. 按物理大小的 VDO 要求示例

下表根据基础卷的物理大小提供 VDO 的最大系统要求。每个表列出了适合预期部署的需求,如主存储或备份存储。

具体数量取决于您的 VDO 卷的配置。

主存储部署

在主存储中,UDS 索引是物理大小的 0.01% 到 25%。

表 1.2. 主存储的存储和内存要求

物理大小RAM 使用量:UDSRAM 使用量:VDO磁盘用量索引类型

10GB–1TB

250MB

472MB

2.5GB

密度

2–10TB

1GB

3GB

10GB

密度

250MB

22GB

稀疏

11–50TB

2GB

14GB

170GB

稀疏

51-100TB

3GB

27GB

255GB

稀疏

101–256TB

12GB

69GB

1020GB

稀疏

备份存储部署

在备份存储中,UDS 索引覆盖了备份组的大小,但小于物理大小。如果您预期备份集或物理大小在以后会增大,则需要把这个值加到索引大小中。

表 1.3. 备份存储的存储和内存要求

物理大小RAM 使用量:UDSRAM 使用量:VDO磁盘用量索引类型

10GB–1TB

250MB

472MB

2.5 GB

密度

2–10TB

2GB

3GB

170GB

稀疏

11–50TB

10GB

14GB

850GB

稀疏

51-100TB

20GB

27GB

1700GB

稀疏

101–256TB

26GB

69GB

3400GB

稀疏

1.7. 安装 VDO

此流程安装创建、挂载和管理 VDO 卷所需的软件。

流程

  • 安装 VDO 软件:

    # yum install lvm2 kmod-kvdo vdo

1.8. 创建 VDO 卷

此流程在块设备中创建 VDO 卷。

先决条件

流程

在以下步骤中,将 vdo-name 替换为您要用于 VDO 卷的标识符,例如:vdo1。您必须为系统中的每个 VDO 实例使用不同的名称和设备。

  1. 找到您要创建 VDO 卷的块设备的持久名称。有关持久性名称的更多信息,请参阅 第 6 章 持久性命名属性概述

    如果您使用非持久性设备名称,则如果设备名称改变了,VDO 将来可能无法正常启动。

  2. 创建 VDO 卷:

    # vdo create \
          --name=vdo-name \
          --device=block-device \
          --vdoLogicalSize=logical-size
    • 使用您要创建 VDO 卷的块设备的持久性名称替换 block-device。例如:/dev/disk/by-id/scsi-3600508b1001c264ad2af21e903ad031f
    • 用 VDO 卷使用的逻辑存储数量替换 logical-size

      • 对于活动的虚拟机或容器存储,请使用逻辑大小,即您的块设备物理大小的 10 倍。例如,如果您的块设备大小为 1TB,请在这里使用 10T
      • 对于对象存储,使用逻辑大小,即您的块设备物理大小的 倍。例如,如果您的块设备大小为 1TB,请在这里使用 3T
    • 如果物理块设备大于 16TiB,请添加 --vdoSlabSize=32G 选项,将卷上的 slab 大小增加到 32GiB。

      在大于 16TiB 的块设备上使用 2GiB 的默认 slab 大小会导致 vdo create 命令失败,并显示以下错误:

      vdo: ERROR - vdoformat: formatVDO failed on '/dev/device': VDO Status: Exceeds maximum number of slabs supported

    例 1.1. 为容器存储创建 VDO

    例如,要为 1TB 块设备上的容器存储创建一个 VDO 卷,您可以使用:

    # vdo create \
          --name=vdo1 \
          --device=/dev/disk/by-id/scsi-3600508b1001c264ad2af21e903ad031f \
          --vdoLogicalSize=10T
    重要

    如果在创建 VDO 卷时发生故障,请删除要清理的卷。详情请查看 第 2.10.2 节 “删除失败创建的 VDO 卷”

  3. 在 VDO 卷之上创建一个文件系统:

    • 对于 XFS 文件系统:

      # mkfs.xfs -K /dev/mapper/vdo-name
    • 对于 ext4 文件系统:

      # mkfs.ext4 -E nodiscard /dev/mapper/vdo-name
      注意

      在新创建的 VDO 卷上使用 -K-E nodiscard 选项的目的是不在发送请求上花费时间,因为它对未分配的块没有影响。新 VDO 卷从 100% 未分配开始。

  4. 使用以下命令等待系统注册新设备节点:

    # udevadm settle

后续步骤

  1. 挂载文件系统。详情请查看 第 1.9 节 “挂载 VDO 卷”
  2. 为 VDO 设备上的文件系统启用 丢弃 功能。详情请查看 第 1.10 节 “启用定期块丢弃”

其它资源

  • The vdo(8) 手册页

1.9. 挂载 VDO 卷

这个过程会在 VDO 卷中手动挂载文件系统,也可以永久挂载文件系统。

先决条件

流程

  • 要手动将文件系统挂载到 VDO 卷中,请使用:

    # mount /dev/mapper/vdo-name mount-point
  • 要将文件系统配置为在引导时自动挂载,请在 /etc/fstab 文件中添加一行:

    • 对于 XFS 文件系统:

      /dev/mapper/vdo-name mount-point xfs defaults 0 0
    • 对于 ext4 文件系统:

      /dev/mapper/vdo-name mount-point ext4 defaults 0 0

    如果 VDO 卷位于需要网络的块设备上,如 iSCSI,请添加 _netdev 挂载选项。

其它资源

  • The vdo(8) 手册页。
  • 有关 iSCSI 和其它需要网络的块设备,请查看 systemd.mount (5) 手册页的有关_netdev 挂载选项的信息。

1.10. 启用定期块丢弃

您可以启用 systemd 计时器来定期丢弃所有支持的文件系统上未使用的块。

流程

  • 启用并启动 systemd 计时器:

    # systemctl enable --now fstrim.timer
    Created symlink /etc/systemd/system/timers.target.wants/fstrim.timer → /usr/lib/systemd/system/fstrim.timer.

验证

  • 验证计时器的状态:

    # systemctl status fstrim.timer
    fstrim.timer - Discard unused blocks once a week
       Loaded: loaded (/usr/lib/systemd/system/fstrim.timer; enabled; vendor preset: disabled)
       Active: active (waiting) since Wed 2023-05-17 13:24:41 CEST; 3min 15s ago
      Trigger: Mon 2023-05-22 01:20:46 CEST; 4 days left
         Docs: man:fstrim
    
    May 17 13:24:41 localhost.localdomain systemd[1]: Started Discard unused blocks once a week.

1.11. 监控 VDO

此流程描述了如何从 VDO 卷获取使用效率的信息。

先决条件

流程

  • 使用 vdostats 工具来获取有关 VDO 卷的信息:

    # vdostats --human-readable
    
    Device                   1K-blocks    Used     Available    Use%    Space saving%
    /dev/mapper/node1osd1    926.5G       21.0G    905.5G       2%      73%
    /dev/mapper/node1osd2    926.5G       28.2G    898.3G       3%      64%

其它资源

  • vdostats(8) 手册页。

第 2 章 维护 VDO

部署 VDO 卷后,您可以执行某些任务来维护或优化它。以下一些任务是 VDO 卷正常工作所必需的。

先决条件

2.1. 管理 VDO 卷的空闲空间

VDO 是一个精简配置的块存储目标。因此,您必须主动监控和管理 VDO 卷中的空间使用情况。

2.1.1. VDO 卷的物理和逻辑大小

VDO 通过以下方法使用物理、可用物理和逻辑大小:

物理大小

这与底层块设备的大小相同。VDO 使用这个存储用于:

  • 用户数据,这些数据可能会进行重复数据删除和压缩
  • VDO 元数据,如 UDS 索引
可用物理大小

这是 VDO 可用于用户数据的物理大小的一部分

它等同于物理大小减去元数据的大小,再减去将卷根据指定的 slab 的大小分为 slab 后剩余的值。

逻辑大小

这是 VDO 卷在应用程序中的置备大小。它通常大于可用的物理大小。如果没有指定 --vdoLogicalSize 选项,则逻辑卷的调配现在被配置为 1:1 的比率。例如,如果将 VDO 卷放在 20GB 块设备之上,则为 UDS 索引保留 2.5 GB(如果使用默认索引大小)。剩余的 17.5 GB 为 VDO 元数据和用户数据提供。因此,要消耗的可用存储不超过 17.5 GB,且可能会因为组成实际 VDO 卷的元数据而减少。

VDO 目前支持任意逻辑卷大小最多为物理卷的 254 倍,但不能超过 4PB。

图 2.1. VDO 磁盘机构

VDO 磁盘机构

在这个图表中,VDO 重复数据删除存储对象完全位于块设备之上,这意味着 VDO 卷的物理大小与基本块设备大小相同。

其它资源

2.1.2. VDO 中的精简置备

VDO 是一个精简配置的块存储目标。VDO 卷使用的物理空间量可能与为存储用户显示的卷大小有所不同。您可以使用它来节约存储成本。

没有可用空间的条件

如果写入的数据没有达到预期的性能率,请小心会意外出现存储空间耗尽的问题。

每当逻辑块(虚拟存储)的数量超过物理块(实际存储)的数量时,文件系统和应用程序可能会意外地遇到空间耗尽的问题。因此,使用 VDO 的存储系统必须为您提供一个监控 VDO 卷中空闲池大小的方法。

您可以使用 vdostats 工具来确定此空闲池的大小。这个工具的默认输出会列出所有运行 VDO 卷的信息,其格式与 Linux df 工具列出的格式类似。例如:

Device                1K-blocks   Used        Available   Use%
/dev/mapper/vdo-name  211812352   105906176   105906176   50%

当 VDO 卷的物理存储容量接近满时,VDO 在系统日志中报告警告,如下所示:

Oct  2 17:13:39 system lvm[13863]: Monitoring VDO pool vdo-name.
Oct  2 17:27:39 system lvm[13863]: WARNING: VDO pool vdo-name is now 80.69% full.
Oct  2 17:28:19 system lvm[13863]: WARNING: VDO pool vdo-name is now 85.25% full.
Oct  2 17:29:39 system lvm[13863]: WARNING: VDO pool vdo-name is now 90.64% full.
Oct  2 17:30:29 system lvm[13863]: WARNING: VDO pool vdo-name is now 96.07% full.
注意

这些警告消息只有在 lvm2-monitor 服务运行时才会出现。它会被默认启用。

如何防止没有空间的问题

如果可用池的大小低于一定级别,可以执行以下操作:

  • 删除数据。当删除的数据不再被重复时,可能重新获得可用空间。只有发出了签发后,删除数据才可以释放空间。
  • 添加物理存储
重要

监控 VDO 卷的物理空间,以防止出现空间不足的情况。物理块不足可能会导致 VDO 卷中最近写入的数据丢失。

精简配置以及 TRIM 和 DISCARD 命令

要从精简配置节省的存储中受益,物理存储层需要知道数据何时被删除的。与精简配置存储一起工作的文件系统会发送 TRIMDISCARD 命令,来在不再需要逻辑块时通知存储系统。

有几种发送 TRIM 或 DISCARD 命令的方法:

  • 通过 discard 挂载选项,文件系统可以在删除块时发送这些命令。
  • 您可以通过使用 fstrim 等工具以受控的方式发送命令。这些工具告诉文件系统检测哪些逻辑块未使用,并以 TRIMDISCARD 命令的形式向存储系统发送信息。

对未使用的块使用 TRIM 或 DISCARD 并不是 VDO 独有的。任何精简置备的存储系统也会遇到同样的问题。

2.1.3. 监控 VDO

此流程描述了如何从 VDO 卷获取使用效率的信息。

先决条件

流程

  • 使用 vdostats 工具来获取有关 VDO 卷的信息:

    # vdostats --human-readable
    
    Device                   1K-blocks    Used     Available    Use%    Space saving%
    /dev/mapper/node1osd1    926.5G       21.0G    905.5G       2%      73%
    /dev/mapper/node1osd2    926.5G       28.2G    898.3G       3%      64%

其它资源

  • vdostats(8) 手册页。

2.1.4. 在文件系统中为 VDO 回收空间

此流程在托管文件系统的 VDO 卷中回收存储空间。

除非文件系统使用 DISCARDTRIMUNMAP 命令告知块是空闲的,否则 VDO 无法回收空间。

流程

  • 如果 VDO 卷中的文件系统支持丢弃(discard)操作,请启用它们。请参阅 第 5 章 丢弃未使用块
  • 对于不使用 DISCARDTRIMUNMAP 的文件系统,您可以手动回收空闲空间。保存由二进制 0 组成的文件,以便占据空闲空间,然后删除该文件。

2.1.5. 在没有文件系统的情况下为 VDO 回收空间

此流程回收 VDO 卷上的存储空间,该卷用作没有文件系统的块存储目标。

流程

  • 使用 blkdiscard 工具。

    例如,可以通过在其上部署 LVM ,可以将单个 VDO 卷划分为多个子卷。在取消配置的逻辑卷前,请使用 blkdiscard 工具释放该逻辑卷之前使用的空间。

    LVM 支持 REQ_DISCARD 命令,并在适当的逻辑块地址上将请求转发到 VDO,以便释放空间。如果您使用其他卷管理器,则它们也需要支持 REQ_DISCARD,或者等效地支持用于 SCSI 设备的 UNMAP 或用于 ATA 设备的 TRIM

其它资源

  • The blkdiscard(8) 手册页

2.1.6. 在光纤通道或以太网网络中为 VDO 回收空间

此流程回收配置到光纤通道存储结构上的主机的 VDO 卷(或部分卷)上的存储空间,或使用 SCSI 目标框架的以太网空间,如 LIO 或 SCST。

流程

  • SCSI 启动器可以使用 UNMAP 命令在精简配置的存储目标上释放空间,但需要配置 SCSI 目标框架来公布对此命令的支持。这通常是通过在这些卷上启用精简置备来完成的。

    通过运行以下命令,来在基于 Linux 的 SCSI 启动器上验证对 UNMAP 的支持:

    # sg_vpd --page=0xb0 /dev/device

    在输出中,验证 Maximum unmap LBA count 的值大于零。

2.2. 启动或停止 VDO 卷

您可以启动或停止给定的 VDO 卷,或所有 VDO 卷及其关联的 UDS 索引。

2.2.1. 已启动并激活的 VDO 卷

在系统引导过程中,vdo systemd 单元会自动 启动 所有配置为 激活的 VDO 设备。

安装 vdo 软件包时,默认会安装并启用 vdo systemd 单元。此单元会在系统启动时自动运行 vdo start --all 命令来启动所有激活的 VDO 卷。

您还可以通过在 vdo create 命令中添加 --activate=disabled 选项来创建不自动启动的 VDO 卷。

启动顺序

有些系统可能会将 LVM 卷放在 VDO 卷之上,或它们之下。在这些系统中,需要以正确顺序启动服务:

  1. 必须首先启动 LVM 的下层。在大多数系统中,当安装 LVM 软件包时会自动启动这个层。
  2. 然后,vdo systemd 单元必须启动。
  3. 最后,必须运行其他脚本以启动正在运行的 VDO 卷上的 LVM 卷或其他服务。

停止卷所需的时间

停止 VDO 卷需要根据存储设备速度以及卷需要写入的数据量而有所不同:

  • 卷总是为每 1GiB UDS 索引写入大约 1GiB。
  • 卷还写入与块映射缓存大小相等的数据量,再加上每个 slab 最多 8MiB。
  • 卷必须完成处理所有未完成的 IO 请求。

2.2.2. 启动 VDO 卷

此流程启动给定 VDO 卷或系统中的所有 VDO 卷。

流程

  • 要启动给定的 VDO 卷,请使用:

    # vdo start --name=my-vdo
  • 要启动所有 VDO 卷,请使用:

    # vdo start --all

其它资源

  • The vdo(8) 手册页

2.2.3. 停止 VDO 卷

此流程停止给定 VDO 卷或系统中的所有 VDO 卷。

流程

  1. 停止卷。

    • 要停止给定的 VDO 卷,请使用:

      # vdo stop --name=my-vdo
    • 要停止所有 VDO 卷,请使用:

      # vdo stop --all
  2. 等待卷完成向磁盘写入数据。

其它资源

  • The vdo(8) 手册页

2.3. 系统引导时自动启动 VDO 卷

您可以配置 VDO 卷以便在系统引导时自动启动。您还可以禁用自动启动。

2.3.1. 已启动并激活的 VDO 卷

在系统引导过程中,vdo systemd 单元会自动 启动 所有配置为 激活的 VDO 设备。

安装 vdo 软件包时,默认会安装并启用 vdo systemd 单元。此单元会在系统启动时自动运行 vdo start --all 命令来启动所有激活的 VDO 卷。

您还可以通过在 vdo create 命令中添加 --activate=disabled 选项来创建不自动启动的 VDO 卷。

启动顺序

有些系统可能会将 LVM 卷放在 VDO 卷之上,或它们之下。在这些系统中,需要以正确顺序启动服务:

  1. 必须首先启动 LVM 的下层。在大多数系统中,当安装 LVM 软件包时会自动启动这个层。
  2. 然后,vdo systemd 单元必须启动。
  3. 最后,必须运行其他脚本以启动正在运行的 VDO 卷上的 LVM 卷或其他服务。

停止卷所需的时间

停止 VDO 卷需要根据存储设备速度以及卷需要写入的数据量而有所不同:

  • 卷总是为每 1GiB UDS 索引写入大约 1GiB。
  • 卷还写入与块映射缓存大小相等的数据量,再加上每个 slab 最多 8MiB。
  • 卷必须完成处理所有未完成的 IO 请求。

2.3.2. 激活 VDO 卷

此流程激活 VDO 卷使其自动启动。

流程

  • 激活一个特定卷:

    # vdo activate --name=my-vdo
  • 激活所有卷:

    # vdo activate --all

其它资源

  • The vdo(8) 手册页

2.3.3. 取消激活 VDO 卷

此流程取消激活 VDO 卷以防止自动启动。

流程

  • 取消激活一个特定卷:

    # vdo deactivate --name=my-vdo
  • 取消激活所有卷:

    # vdo deactivate --all

其它资源

  • The vdo(8) 手册页

2.4. 选择 VDO 写入模式

您可以根据基础块设备的要求,为 VDO 卷配置写入模式。默认情况下,VDO 选择自动写入模式。

2.4.1. VDO 写入模式

VDO 支持以下写入模式:

sync

当 VDO 处于 sync 模式时,其上的层会假定写入命令将数据写入持久性存储。因此,文件系统或应用程序不需要发出 FLUSH 或强制单元访问(FUA)请求来使数据在关键点上变为持久。

只有在底层的存储保证数据在写命令完成后写入持久性存储时,才必须将 VDO 设为 sync 模式。也就是说,存储必须没有易变的写缓存,或者不通过缓存进行写入操作。

async

当 VDO 处于 async 模式时,VDO 不能保证在确认写命令时数据会被写入持久性存储。文件系统或应用程序必须发出 FLUSH 或 FUA 请求,来确保每次事务中数据在关键点上的持久性。

如果底层存储不能保证在写命令完成后数据被写入到持久性存储,必须将 VDO 设为 async 模式;也就是说当存储具有易失性写回缓存时。

async-unsafe

这个模式与 async 具有同样的属性,但它与原子性、一致性、隔离、持久性(ACID)不兼容。与 async 相比,async-unsafe 具有更好的性能。

警告

当假设 ACID 合规的应用程序或文件系统在 VDO 卷上运行时,sync-unsafe 模式可能会导致意外的数据丢失。

auto
auto 模式根据每个设备的特性自动选择 syncasync。这是默认选项。

2.4.2. VDO 写入模式的内部处理

VDO 的写入模式是 syncasync。以下信息描述了这些模式的操作。

如果 kvdo 模块在同步(同步)模式下运行:

  1. 它会在请求中临时将数据写入分配块中,然后确认请求。
  2. 确认完成后,会尝试通过计算块数据的 MurmurHash-3 签名来去除重复的块,该签名发送给 VDO 索引。
  3. 如果 VDO 索引包含具有相同签名的块的条目,kvdo 会读取指定的块,并对这两个块进行逐字节的比较,以验证它们是否相同。
  4. 如果它们确实相同,则 kvdo 会更新其块映射,以便逻辑块指向相应的物理块,并释放分配的物理块。
  5. 如果 VDO 索引没有包含正在写入的块的签名的条目,或者指定的块实际上没有包含相同的数据,则 kvdo 会更新其块映射,以使临时物理块持久。

如果 kvdo 以异步(async)模式运行:

  1. 它将立即确认请求而不是写数据。
  2. 然后它会尝试使用与上述步骤相同的方法来复制块。
  3. 如果块是重复的,则 kvdo 会更新其块映射,并释放分配的块。否则,它会将请求中的数据写入分配的块,并更新块映射使物理块持久化。

2.4.3. 检查 VDO 卷中的写入模式

此流程列出了所选 VDO 卷中的主动写入模式。

流程

  • 使用以下命令查看 VDO 卷使用的写入模式:

    # vdo status --name=my-vdo

    输出列表:

    • 配置的写入策略,它是从 syncasyncauto 中选择的选项
    • 写入策略,其是 VDO 应用的特定的写模式,即 syncasync

2.4.4. 检查易变的缓存

这个过程决定块设备是否有易变的缓存。您可以使用这些信息在 syncasync VDO 写模式之间进行选择。

流程

  1. 使用以下方法之一确定某个设备是否有写回缓存:

    • 阅读 /sys/block/block-device /device/scsi_disk/标识符/cache_type sysfs 文件。例如:

      $ cat '/sys/block/sda/device/scsi_disk/7:0:0:0/cache_type'
      
      write back
      $ cat '/sys/block/sdb/device/scsi_disk/1:2:0:0/cache_type'
      
      None
    • 另外,你可以在内核引导日志中找到上述设备是否有写缓存:

      sd 7:0:0:0: [sda] Write cache: enabled, read cache: enabled, doesn't support DPO or FUA
      sd 1:2:0:0: [sdb] Write cache: disabled, read cache: disabled, supports DPO and FUA
  2. 在上例中:

    • 设备 sda 表示它 一个回写缓存。对其使用 async 模式。
    • 设备 sdb 表示 它没有 一个回写缓存。对其使用 sync 模式。

    如果 cache_type 的值是 Nonewritethrough,您应该将 VDO 配置为使用 sync 写模式。

2.4.5. 设置 VDO 写入模式

此流程为 VDO 卷设置了写模式,可以是对现有卷,也可以是在创建新卷时。

重要

使用不正确的写模式可能会在电源故障、系统崩溃或与磁盘意外失去联系后导致数据丢失。

先决条件

流程

  • 您可以在现有 VDO 卷上或创建新卷时设置写入模式:

    • 要修改现有的 VDO 卷,请使用:

      # vdo changeWritePolicy --writePolicy=sync|async|async-unsafe|auto \
                              --name=vdo-name
    • 要在创建 VDO 卷时指定写模式,请在 vdo create 命令中添加 --writePolicy=sync|async|async-unsafe|auto 选项。

2.5. 在未清除关闭后恢复 VDO 卷

您可以在不干净的关机后恢复 VDO 卷,使其可以继续运行。任务通常是自动的。另外,由于过程中的故障,您可以在 VDO 卷创建失败后进行清理。

2.5.1. VDO 写入模式

VDO 支持以下写入模式:

sync

当 VDO 处于 sync 模式时,其上的层会假定写入命令将数据写入持久性存储。因此,文件系统或应用程序不需要发出 FLUSH 或强制单元访问(FUA)请求来使数据在关键点上变为持久。

只有在底层的存储保证数据在写命令完成后写入持久性存储时,才必须将 VDO 设为 sync 模式。也就是说,存储必须没有易变的写缓存,或者不通过缓存进行写入操作。

async

当 VDO 处于 async 模式时,VDO 不能保证在确认写命令时数据会被写入持久性存储。文件系统或应用程序必须发出 FLUSH 或 FUA 请求,来确保每次事务中数据在关键点上的持久性。

如果底层存储不能保证在写命令完成后数据被写入到持久性存储,必须将 VDO 设为 async 模式;也就是说当存储具有易失性写回缓存时。

async-unsafe

这个模式与 async 具有同样的属性,但它与原子性、一致性、隔离、持久性(ACID)不兼容。与 async 相比,async-unsafe 具有更好的性能。

警告

当假设 ACID 合规的应用程序或文件系统在 VDO 卷上运行时,sync-unsafe 模式可能会导致意外的数据丢失。

auto
auto 模式根据每个设备的特性自动选择 syncasync。这是默认选项。

2.5.2. VDO 卷恢复

当在一个非干净的关闭后重启一个 VDO 卷时,VDO 会执行以下操作:

  • 验证卷元数据的一致性。
  • 重建一部分元数据以便在需要时进行修复。

重建是自动的,不需要用户干预。

VDO 可能会重建不同的写入模式,具体取决于活跃的写入模式:

sync
如果 VDO 在同步存储上运行,且写策略被设为 sync,则写到卷的所有数据都可以被完全恢复。
async
如果写策略是 async 的,如果一些写不是持久化的,则它们可能无法被恢复。这可以通过发送 VDO FLUSH 命令或带有 FUA(强制单元访问)标记的写 I/O 来实现。您可以通过调用 fsyncfdatasyncsyncumount 等数据完整性操作来在用户模式下实现这一点。

在任何一种模式下,某些未被确认或未刷新的写也可能被重新构建。

自动和手动恢复

当 VDO 卷进入到 recovering 操作模式时,VDO 会在其重新上线后自动重建不干净的 VDO 卷。这叫做 在线恢复

如果 VDO 无法成功恢复 VDO 卷,它会将卷置于只读 操作模式下,该模式在卷重新启动时仍然有效。您需要强制重新构建来手动解决这个问题。

其它资源

2.5.3. VDO 操作模式

本节描述了指示 VDO 卷是否在正常运行或者正在从错误中恢复的模式。

您可以使用 vdostats --verbose device 命令显示 VDO 卷的当前操作模式。请参阅输出中的 Operating mode 属性。

normal
这是默认的操作模式。VDO 卷始终处于 normal 模式,除非以下其中一种状态强制使用不同的模式。新创建的 VDO 卷以 normal 模式启动。
recovering

当 VDO 卷在关闭前没有保存其所有元数据时,它会在下次启动时自动进入 recovering 模式。进入这个模式的典型原因是电源丢失或者基础存储设备出现问题。

recovering 模式下,VDO 将修复设备上每个物理块的引用数。恢复通常不需要非常长。时间取决于 VDO 卷的大小、基础存储设备的速度以及其它请求 VDO 同时处理的速度。VDO 卷通常具有以下例外:

  • 最初,在卷中写入请求的空间量可能会有所限制。当恢复了更多元数据后,更多的可用空间就会可用。
  • 如果数据位于尚未恢复的卷的一部分中,则在 VDO 卷恢复过程中的数据写入可能对崩溃前写入的数据不能去除重复数据。VDO 可在恢复卷时压缩数据。您仍然可以读取或覆盖压缩的块。
  • 在在线恢复过程中,某些统计数据不可用:例如,blocks in useblocks free。重建完成后就可使用这些统计数据。
  • 由于正在进行恢复工作,读取和写入的响应时间可能比通常要慢

您可以在 recovering 模式下安全地关闭 VDO 卷。如果恢复在关闭前没有完成,则设备将在下一次启动时再次进入 recovering 模式。

当 VDO 卷修复了所有引用数时,VDO 卷会自动退出 recovering 模式,并进入到 normal 模式。不需要管理员操作。详情请查看 第 2.5.4 节 “在线恢复 VDO 卷”

read-only

当 VDO 卷遇到严重的内部错误时,它会进入 read-only 模式。可能导致 read-only 模式的事件包括元数据崩溃或支持的存储设备变为只读。这个模式是一个错误状态。

read-only 模式下,数据读取通常会正常进行,但数据写入会始终失败。VDO 卷会一直处于 read-only 模式,直到管理员解决了问题。

您可以在 read-only 模式下安全地关闭 VDO 卷。VDO 卷重启后通常会保留这个模式。在个别情况下,VDO 卷无法将 read-only 状态记录到支持的存储设备中。在这种情况下,VDO 会尝试进行恢复。

当一个卷处于只读模式后,就无法保证卷中的数据不会被丢失或损坏。在这种情况下,红帽建议从只读卷中复制数据,并可能从备份中恢复卷。

如果数据崩溃的风险可以接受,则可以强制离线重新构建 VDO 卷元数据,以便将该卷重新在线并可用。无法保证重建数据的完整性。详情请查看 第 2.5.5 节 “强制 VDO 卷元数据离线重建”

2.5.4. 在线恢复 VDO 卷

此流程在一个 VDO 卷上执行在线恢复,以在未清除关闭后恢复元数据。

流程

  1. 如果 VDO 卷还没有启动,请启动它:

    # vdo start --name=my-vdo

    不需要额外的步骤。恢复在后台运行。

  2. 如果您依赖卷统计,比如 使用中的块 和块空闲,请等待这些数据可用。

2.5.5. 强制 VDO 卷元数据离线重建

此流程对 VDO 卷元数据执行强制离线重新构建,以便在不干净的关闭后进行恢复。

警告

此过程可能会导致卷的数据丢失。

先决条件

  • 已启动 VDO 卷。

流程

  1. 检查卷是否处于只读模式。查看命令输出中的 操作模式 属性:

    # vdo status --name=my-vdo

    如果卷不处于只读模式,则不需要强制离线重建。执行在线恢复,如 第 2.5.4 节 “在线恢复 VDO 卷” 中所述。

  2. 如果卷正在运行,请停止它:

    # vdo stop --name=my-vdo
  3. 使用 --forceRebuild 选项重启卷:

    # vdo start --name=my-vdo --forceRebuild

2.5.6. 删除失败创建的 VDO 卷

此流程清理处于中间状态的 VDO 卷。如果在创建卷时发生故障,则卷处于中间状态。这可能会在以下情况发生,例如:

  • 系统崩溃
  • 电源失败
  • 管理员中断了运行的 vdo create 命令

流程

  • 要进行清理,请使用 --force 选项删除创建失败的卷:

    # vdo remove --force --name=my-vdo

    需要 --force 选项,由于卷创建失败,管理员可能会由于更改了系统配置而导致冲突。

    如果没有 --force 选项,vdo remove 命令会失败,并显示以下信息:

    [...]
    A previous operation failed.
    Recovery from the failure either failed or was interrupted.
    Add '--force' to 'remove' to perform the following cleanup.
    Steps to clean up VDO my-vdo:
    umount -f /dev/mapper/my-vdo
    udevadm settle
    dmsetup remove my-vdo
    vdo: ERROR - VDO volume my-vdo previous operation (create) is incomplete

2.6. 优化 UDS 索引

您可以配置特定的 UDS 索引设置以便在您的系统中优化它。

重要

创建 VDO 卷后,您无法更改 UDS 索引的属性。

2.6.1. VDO 卷的组件

VDO 使用块设备作为后备存储,它包括由一个或多个磁盘、分区甚至平面文件组成的物理存储聚合。当存储管理工具创建 VDO 卷时,VDO 为 UDS 索引和 VDO 卷保留卷空间。UDS 索引和 VDO 卷会一起交互,以提供重复的块存储。

图 2.2. VDO 磁盘机构

VDO 磁盘机构

VDO 解决方案包括以下组件:

kvdo

载入 Linux 设备映射器层的内核模块提供去除重复数据的、压缩的和精简配置的块存储卷。

kvdo 模块公开一个块设备。对于块存储,您可以直接访问块存储或通过 Linux 文件系统(如 XFS 或 ext4)呈现它。

kvdo 收到一个读取 VDO 卷中数据的逻辑块的请求时,它会将请求的逻辑块映射到底层的物理块上,然后读取并返回请求的数据。

kvdo 收到一个向 VDO 卷写数据块的请求时,它首先检查请求是 DISCARD 还是 TRIM 请求,或者数据是否统一为零。如果其中任何一个条件为真,则 kvdo 会更新其块映射,并确认请求。否则,VDO 会处理并优化数据。

uds

与卷上通用的去除重复数据服务(UDS)索引通信的内核模块,并分析数据的重复内容。对于每个新的数据,UDS 可以快速地判断该数据是否与之前存储的数据相同。如果索引发现匹配项,则存储系统可在内部引用现有项,以避免多次保存相同的信息。

UDS 索引作为 uds 内核模块运行在内核中。

命令行工具
用于配置和管理优化的存储。

2.6.2. UDS 索引

VDO 使用名为 UDS 的高性能 deduplication 索引来检测正在存储的数据重复块。

UDS 索引提供了 VDO 产品的基础。对于每个新数据段,它会快速确定该数据段是否与之前存储的任何数据段相同。如果索引发现匹配项,则存储系统可在内部引用现有项,以避免多次保存相同的信息。

UDS 索引作为 uds 内核模块运行在内核中。

去除重复数据窗口 是索引记住的之前写入的块的数量。可配置去除重复数据窗口窗口的大小。对于给定的窗口大小,索引需要特定数量的 RAM 以及特定数量的磁盘空间。窗口的大小通常通过使用 --indexMem=size 选项指定索引内存的大小来决定。然后,VDO 决定自动使用的磁盘空间量。

UDS 索引由两个部分组成:

  • 在内存中使用紧凑表示,每个唯一块最多包含一个条目。
  • 记录在索引发生时的相关块名称的磁盘组件,按顺序记录。

UDS 在内存中平均每个条目使用 4 个字节,包括缓存。

磁盘上的组件维护传递给 UDS 的数据的相关历史记录。UDS 为属于这个去除重复数据窗口中的数据提供去除重复数据建议,其中包括最近看到的块的名称。去除重复数据窗口允许 UDS 尽可能高效地索引数据,同时限制索引大型数据存储库所需的内存量。尽管去除重复数据窗口具有局限性,但大部分具有大量去除重复数据的数据集也表现出高度的时间局部性 - 换句话说,大多数去除重复数据发生在几乎同时写入的块集合中。另外,通常要写入的数据通常可能会与最近写入的数据重复。因此,对于给定时间间隔的工作负载,去除重复数据比率通常相同,无论 UDS 仅索引了最新的数据还是所有数据。

由于重复数据往往会表现出时间局部性,因此很少需要对存储系统中的每个块进行索引。否则,索引内存的成本会耗尽导致复制性能降低的存储成本。索引大小要求与数据刷新率紧密相关。例如,假设存储系统的总容量为 100 TB,但每周的摄取率为 1 TB 。UDS 窗口的 deduplication 窗口为 4TB,UDS 可探测到上个月写入的数据的最大冗余度。

2.7. 在 VDO 中启用或禁用 deduplication

在某些情况下,您可能希望临时禁用写入 VDO 卷的删除重复数据功能,同时仍可保留从卷读取和写入的功能。禁用 deduplication 可防止后续写入操作被删除重复数据,但已经删除重复数据的数据会一直保留。

2.7.1. VDO 中的删除重复数据

删除重复数据(Deduplication)是通过删除重复块的多个副本来减少存储资源消耗的技术。

VDO 检测每个重复块,并将其记录为对原始块的引用,而不是多次写相同的数据。VDO 维护一个从逻辑块地址(由 VDO 上面的存储层使用)到物理块地址(被 VDO 下的存储层使用)的映射。

在进行删除重复数据后,可将多个逻辑块地址映射到相同的物理块地址。这些被称为共享块。块共享对存储用户是不可见的,用户会像 VDO 不存在一样读写块。

当共享块被覆盖时,VDO 为保存新块数据分配一个新的物理块,以确保映射到共享物理块的其他逻辑块地址不会被修改。

2.7.2. 在 VDO 卷中启用 deduplication

此流程重启关联的 UDS 索引,并通知 VDO 卷再次激活了 deduplication。

注意

默认启用 deduplication。

流程

  • 要在 VDO 卷上重启 deduplication,请使用以下命令:

    # vdo enableDeduplication --name=my-vdo

2.7.3. 在 VDO 卷上禁用 deduplication

此流程停止关联的 UDS 索引,并通知 VDO 卷 deduplication 不再处于活动状态。

流程

  • 要在 VDO 卷上停止 deduplication,请使用以下命令:

    # vdo disableDeduplication --name=my-vdo
  • 您还可以通过在 vdo create 命令中添加 --deduplication=disabled 选项,在创建新 VDO 卷时禁用 deduplication。

2.8. 在 VDO 中启用或禁用压缩

VDO 提供数据压缩。禁用它可最大化性能并加快了不太可能压缩的数据处理。重新启用它可增加空间节省。

2.8.1. VDO 中的压缩

除了块级 deduplication 外,VDO 还提供使用 HIOPS 压缩™ 技术的内联块级压缩。

VDO 卷压缩默认是 on。

虽然 deduplication 对虚拟机环境和备份应用程序是最佳解决方案,但压缩非常适合结构化和非结构化的文件格式,这些文件格式通常不会展示块级冗余,如日志文件和数据库。

压缩对未识别为重复的块进行操作。当 VDO 首次看到唯一数据时,它会压缩数据。已存储的数据的后续副本会复制,而无需额外的压缩步骤。

压缩功能基于一种基于并行的打包算法,其允许一次处理许多压缩操作。在首先存储块并响应请求者后,最佳打包算法会找到多个块,当压缩时,这些块可以放入一个物理块中。确定特定的物理块不太可能保存其他压缩块后,它将被写入存储,并且未压缩块的被释放并被重复使用。

在已经响应请求者后执行压缩和打包操作,使用压缩会带来最小的延迟损失。

2.8.2. 在 VDO 卷中启用压缩

此流程启用了 VDO 卷的压缩来提高空间节能。

注意

默认启用压缩。

流程

  • 要再次启动它,请使用以下命令:

    # vdo enableCompression --name=my-vdo

2.8.3. 禁用 VDO 卷上的压缩

此流程停止 VDO 卷的压缩,以最大化性能或加快对数据进行压缩的速度。

流程

  • 要停止在现有 VDO 卷中压缩,请使用以下命令:

    # vdo disableCompression --name=my-vdo
  • 另外,在创建新卷时,您可以在 vdo create 命令中添加 --compression=disabled 选项来禁用压缩。

2.9. 增大 VDO 卷的大小

您可以增加 VDO 卷的物理大小,以利用更多的底层存储容量,或者增加逻辑大小以在卷上提供更多的容量。

2.9.1. VDO 卷的物理和逻辑大小

VDO 通过以下方法使用物理、可用物理和逻辑大小:

物理大小

这与底层块设备的大小相同。VDO 使用这个存储用于:

  • 用户数据,这些数据可能会进行重复数据删除和压缩
  • VDO 元数据,如 UDS 索引
可用物理大小

这是 VDO 可用于用户数据的物理大小的一部分

它等同于物理大小减去元数据的大小,再减去将卷根据指定的 slab 的大小分为 slab 后剩余的值。

逻辑大小

这是 VDO 卷在应用程序中的置备大小。它通常大于可用的物理大小。如果没有指定 --vdoLogicalSize 选项,则逻辑卷的调配现在被配置为 1:1 的比率。例如,如果将 VDO 卷放在 20GB 块设备之上,则为 UDS 索引保留 2.5 GB(如果使用默认索引大小)。剩余的 17.5 GB 为 VDO 元数据和用户数据提供。因此,要消耗的可用存储不超过 17.5 GB,且可能会因为组成实际 VDO 卷的元数据而减少。

VDO 目前支持任意逻辑卷大小最多为物理卷的 254 倍,但不能超过 4PB。

图 2.3. VDO 磁盘机构

VDO 磁盘机构

在这个图表中,VDO 重复数据删除存储对象完全位于块设备之上,这意味着 VDO 卷的物理大小与基本块设备大小相同。

其它资源

2.9.2. VDO 中的精简置备

VDO 是一个精简配置的块存储目标。VDO 卷使用的物理空间量可能与为存储用户显示的卷大小有所不同。您可以使用它来节约存储成本。

没有可用空间的条件

如果写入的数据没有达到预期的性能率,请小心会意外出现存储空间耗尽的问题。

每当逻辑块(虚拟存储)的数量超过物理块(实际存储)的数量时,文件系统和应用程序可能会意外地遇到空间耗尽的问题。因此,使用 VDO 的存储系统必须为您提供一个监控 VDO 卷中空闲池大小的方法。

您可以使用 vdostats 工具来确定此空闲池的大小。这个工具的默认输出会列出所有运行 VDO 卷的信息,其格式与 Linux df 工具列出的格式类似。例如:

Device                1K-blocks   Used        Available   Use%
/dev/mapper/vdo-name  211812352   105906176   105906176   50%

当 VDO 卷的物理存储容量接近满时,VDO 在系统日志中报告警告,如下所示:

Oct  2 17:13:39 system lvm[13863]: Monitoring VDO pool vdo-name.
Oct  2 17:27:39 system lvm[13863]: WARNING: VDO pool vdo-name is now 80.69% full.
Oct  2 17:28:19 system lvm[13863]: WARNING: VDO pool vdo-name is now 85.25% full.
Oct  2 17:29:39 system lvm[13863]: WARNING: VDO pool vdo-name is now 90.64% full.
Oct  2 17:30:29 system lvm[13863]: WARNING: VDO pool vdo-name is now 96.07% full.
注意

这些警告消息只有在 lvm2-monitor 服务运行时才会出现。它会被默认启用。

如何防止没有空间的问题

如果可用池的大小低于一定级别,可以执行以下操作:

  • 删除数据。当删除的数据不再被重复时,可能重新获得可用空间。只有发出了签发后,删除数据才可以释放空间。
  • 添加物理存储
重要

监控 VDO 卷的物理空间,以防止出现空间不足的情况。物理块不足可能会导致 VDO 卷中最近写入的数据丢失。

精简配置以及 TRIM 和 DISCARD 命令

要从精简配置节省的存储中受益,物理存储层需要知道数据何时被删除的。与精简配置存储一起工作的文件系统会发送 TRIMDISCARD 命令,来在不再需要逻辑块时通知存储系统。

有几种发送 TRIM 或 DISCARD 命令的方法:

  • 通过 discard 挂载选项,文件系统可以在删除块时发送这些命令。
  • 您可以通过使用 fstrim 等工具以受控的方式发送命令。这些工具告诉文件系统检测哪些逻辑块未使用,并以 TRIMDISCARD 命令的形式向存储系统发送信息。

对未使用的块使用 TRIM 或 DISCARD 并不是 VDO 独有的。任何精简置备的存储系统也会遇到同样的问题。

2.9.3. 增大 VDO 卷的逻辑卷大小

这个过程会增加给定 VDO 卷的逻辑大小。它允许您首先创建具有逻辑大小足够小的 VDO 卷,使其安全而无法耗尽空间。一段时间后,您可以评估实际的数据减少率,如果足够的话,您可以增大 VDO 卷的逻辑大小以利用节省的空间。

不可能缩小 VDO 卷的逻辑卷大小。

流程

  • 要增大逻辑大小,请使用:

    # vdo growLogical --name=my-vdo \
                      --vdoLogicalSize=new-logical-size

    当逻辑卷增大时,VDO 会报告有新的大小卷上的任何设备或文件系统。

2.9.4. 增加 VDO 卷的物理大小

此流程增加 VDO 卷可以使用的物理存储量。

不可能以这种方式缩小 VDO 卷。

先决条件

  • 基础块设备的容量大于 VDO 卷的当前物理大小。

    如果不是这样,您可以尝试增加设备的大小。确切的流程取决于设备的类型。例如:要调整 MBR 或 GPT 分区的大小,请参阅 管理存储设备 指南中的 重新调整分区大小 部分。

流程

  • 为 VDO 卷添加新物理存储空间:

    # vdo growPhysical --name=my-vdo

2.10. 删除 VDO 卷

您可以删除系统中的现有 VDO 卷。

2.10.1. 删除一个有效的 VDO 卷

此流程移除 VDO 卷及其关联的 UDS 索引。

流程

  1. 卸载文件系统并停止使用 VDO 卷中的存储的应用程序。
  2. 要从您的系统中删除 VDO 卷,请使用:

    # vdo remove --name=my-vdo

2.10.2. 删除失败创建的 VDO 卷

此流程清理处于中间状态的 VDO 卷。如果在创建卷时发生故障,则卷处于中间状态。这可能会在以下情况发生,例如:

  • 系统崩溃
  • 电源失败
  • 管理员中断了运行的 vdo create 命令

流程

  • 要进行清理,请使用 --force 选项删除创建失败的卷:

    # vdo remove --force --name=my-vdo

    需要 --force 选项,由于卷创建失败,管理员可能会由于更改了系统配置而导致冲突。

    如果没有 --force 选项,vdo remove 命令会失败,并显示以下信息:

    [...]
    A previous operation failed.
    Recovery from the failure either failed or was interrupted.
    Add '--force' to 'remove' to perform the following cleanup.
    Steps to clean up VDO my-vdo:
    umount -f /dev/mapper/my-vdo
    udevadm settle
    dmsetup remove my-vdo
    vdo: ERROR - VDO volume my-vdo previous operation (create) is incomplete

第 3 章 测试 VDO 空间节省

您可以执行一系列测试来确定可以使用 VDO 保存多少存储空间。

先决条件

  • 一个或多个物理块设备可用。
  • 目标块设备大于 512 GiB。
  • 已安装 VDO。

3.1. 测试 VDO 的目的和结果

红帽提供的 VDO 测试可评估 VDO 整合到现有存储设备中。它们是为了提高而不是替换您的内部评估。

测试结果可帮助您了解特定存储环境中的 VDO 行为。原始设备制造商(OEM)能了解如何设计其去除重复数据和压缩功能设备,以及他们的客户如何为这些设备调优他们的应用程序。

目标

  • 识别来自测试设备的优化响应的配置设置。
  • 解释基本调优参数,以帮助避免产品错误配置。
  • 创建性能结果参考与实际使用案例进行比较。
  • 识别不同的工作负载对性能和数据效率的影响。
  • 缩短了实施 VDO 的时间。

测试计划和测试条件

VDO 测试提供了可最大程度评估 VDO 的条件。更改测试步骤或参数可能会导致结果无效。红帽销售工程师可在修改测试计划时为您提供指导。

要有效的测试计划,您必须检查 VDO 架构并探索这些项目:

  • 高负载环境中的性能
  • 用于性能调优终端用户应用程序的 VDO 的可配置属性
  • VDO 的影响是一个原生 4 KiB 块设备
  • 对 deduplication 和压缩的访问模式和发行的响应
  • 特定应用程序的成本和容量值和性能

3.2. VDO 中的精简置备

VDO 是一个精简配置的块存储目标。VDO 卷使用的物理空间量可能与为存储用户显示的卷大小有所不同。您可以使用它来节约存储成本。

没有可用空间的条件

如果写入的数据没有达到预期的性能率,请小心会意外出现存储空间耗尽的问题。

每当逻辑块(虚拟存储)的数量超过物理块(实际存储)的数量时,文件系统和应用程序可能会意外地遇到空间耗尽的问题。因此,使用 VDO 的存储系统必须为您提供一个监控 VDO 卷中空闲池大小的方法。

您可以使用 vdostats 工具来确定此空闲池的大小。这个工具的默认输出会列出所有运行 VDO 卷的信息,其格式与 Linux df 工具列出的格式类似。例如:

Device                1K-blocks   Used        Available   Use%
/dev/mapper/vdo-name  211812352   105906176   105906176   50%

当 VDO 卷的物理存储容量接近满时,VDO 在系统日志中报告警告,如下所示:

Oct  2 17:13:39 system lvm[13863]: Monitoring VDO pool vdo-name.
Oct  2 17:27:39 system lvm[13863]: WARNING: VDO pool vdo-name is now 80.69% full.
Oct  2 17:28:19 system lvm[13863]: WARNING: VDO pool vdo-name is now 85.25% full.
Oct  2 17:29:39 system lvm[13863]: WARNING: VDO pool vdo-name is now 90.64% full.
Oct  2 17:30:29 system lvm[13863]: WARNING: VDO pool vdo-name is now 96.07% full.
注意

这些警告消息只有在 lvm2-monitor 服务运行时才会出现。它会被默认启用。

如何防止没有空间的问题

如果可用池的大小低于一定级别,可以执行以下操作:

  • 删除数据。当删除的数据不再被重复时,可能重新获得可用空间。只有发出了签发后,删除数据才可以释放空间。
  • 添加物理存储
重要

监控 VDO 卷的物理空间,以防止出现空间不足的情况。物理块不足可能会导致 VDO 卷中最近写入的数据丢失。

精简配置以及 TRIM 和 DISCARD 命令

要从精简配置节省的存储中受益,物理存储层需要知道数据何时被删除的。与精简配置存储一起工作的文件系统会发送 TRIMDISCARD 命令,来在不再需要逻辑块时通知存储系统。

有几种发送 TRIM 或 DISCARD 命令的方法:

  • 通过 discard 挂载选项,文件系统可以在删除块时发送这些命令。
  • 您可以通过使用 fstrim 等工具以受控的方式发送命令。这些工具告诉文件系统检测哪些逻辑块未使用,并以 TRIMDISCARD 命令的形式向存储系统发送信息。

对未使用的块使用 TRIM 或 DISCARD 并不是 VDO 独有的。任何精简置备的存储系统也会遇到同样的问题。

3.3. 在每个 VDO 测试前记录的信息

您必须在每次测试开始时记录以下信息以确保测试环境被完全理解。您可以使用 sosreport 工具捕获大量所需的信息。

所需信息

  • 使用的 Linux 构建,包括内核构建号
  • 可以从 rpm -qa 命令获取安装的软件包的完整列表
  • 完整的系统规格

    • CPU 类型和数量; 可在 /proc/cpuinfo 文件中获得
    • 安装的内存以及 rase OS 运行后可用的内存量 ; 可在 /proc/meminfo 文件中获得
    • 已使用的驱动器控制器类型
    • 已使用磁盘的类型和数量
  • 运行的进程的完整列表;可通过 ps aux 命令或类似的列表获得
  • 物理卷的名称以及为使用 VDO 而创建的卷组名称;可通过 pvsvgs 命令获得
  • 格式化 VDO 卷时使用的文件系统(若有)
  • 挂载的目录的权限
  • /etc/vdoconf.yaml 文件的内容
  • VDO 文件的位置

3.4. 创建 VDO 测试卷

此流程在 512 GiB 物理卷中创建了大小为 1 TiB 的 VDO 卷,用于测试目的。

流程

  1. 创建 VDO 卷:

    # vdo create --name=vdo-test \
                 --device=/dev/sdb \
                 --vdoLogicalSize=1T \
                 --writePolicy=policy \
                 --verbose
    • 使用块设备的路径替换 /dev/sdb
    • 要在异步存储之上测试 VDO async 模式,请使用 --writePolicy=async 选项创建一个异步卷。
    • 要在同步存储之上测试 VDO sync 模式,请使用 --writePolicy=sync 选项创建一个同步卷。
  2. 使用 XFS 或者 ext4 文件系统格式化新卷。

    • 对于 XFS:

      # mkfs.xfs -K /dev/mapper/vdo-test
    • 对于 ext4:

      # mkfs.ext4 -E nodiscard /dev/mapper/vdo-test
  3. 挂载格式化的卷:

    # mkdir /mnt/vdo-test
    
    # mount /dev/mapper/vdo-test /mnt/vdo-test && \
      chmod a+rwx /mnt/vdo-test

3.5. 测试 VDO 测试卷

此流程测试 VDO 测试卷的读取和写入是否正常工作。

先决条件

流程

  1. 将随机数据的 32 GiB 写入 VDO 卷:

    $ dd if=/dev/urandom of=/mnt/vdo-test/testfile bs=4096 count=8388608
  2. 从 VDO 卷中读取数据并将其写入另一个卷:

    $ dd if=/mnt/vdo-test/testfile of=another-location/testfile bs=4096
    • 使用您在 VDO 测试卷上有写权限的任何目录替换 another-location。例如,您可以使用您的主目录。
  3. 比较这两个文件:

    $ diff --report-identical-files /mnt/vdo-test/testfile another-location/testfile

    命令应该报告这些文件是相同的。

  4. 将文件复制到 VDO 卷中的新位置:

    $ dd if=another-location/testfile of=/mnt/vdo-test/testfile2 bs=4096
  5. 将第三个文件与第二个文件进行比较:

    $ diff --report-identical-files /mnt/vdo-test/testfile2 another-location/testfile

    命令应该报告这些文件是相同的。

清理步骤

3.6. 清理 VDO 测试卷

此流程移除了用于从系统中测试 VDO 效率的 VDO 卷。

先决条件

  • 挂载 VDO 测试卷。

流程

  1. 卸载在 VDO 卷中创建的文件系统:

    # umount /mnt/vdo-test
  2. 从系统中删除 VDO 测试卷:

    # vdo remove --name=vdo-test

验证步骤

  • 验证卷是否已被删除:

    # vdo list --all | grep vdo-test

    这个命令不应该列出 VDO 测试分区。

3.7. 测量 VDO 复制

此流程测试 VDO 数据重复在 VDO 测试卷中的效率。

先决条件

流程

  1. 准备可记录测试结果的表:

    统计裸机文件系统seed 后10 个副本后

    文件系统使用大小

       

    使用 VDO 数据

       

    使用 VDO 逻辑

       
  2. 在 VDO 卷中创建 10 个目录存放测试数据集的 10 个副本:

    $ mkdir /mnt/vdo-test/vdo{01..10}
  3. 检查文件系统报告的磁盘用量:

    $ df --human-readable /mnt/vdo-test

    例 3.1. 磁盘用量

    Filesystem            Size  Used Avail Use% Mounted on
    /dev/mapper/vdo-test  1.5T  198M  1.4T   1% /mnt/vdo-test
  4. 记录以下值:

    # vdostats --verbose | grep "blocks used"

    例 3.2. 使用的块

    data blocks used                : 1090
    overhead blocks used            : 538846
    logical blocks used             : 6059434
    • data blocks used 的值是在 VDO 下运行的物理设备优化后用户数据所使用的块数。
    • logical blocks used 的值是优化前使用的块数。它将作为测量的起点。
  5. 在 VDO 卷中创建数据源文件:

    $ dd if=/dev/urandom of=/mnt/vdo-test/sourcefile bs=4096 count=1048576
    
    4294967296 bytes (4.3 GB) copied, 540.538 s, 7.9 MB/s
  6. 重新定义已使用的物理磁盘空间量:

    $ df --human-readable /mnt/vdo-test

    例 3.3. 使用数据源文件磁盘用量

    Filesystem            Size  Used Avail Use% Mounted on
    /dev/mapper/vdo-test  1.5T  4.2G  1.4T   1% /mnt/vdo-test
    # vdostats --verbose | grep "blocks used"

    例 3.4. 数据源文件使用的块

    data blocks used                : 1050093  # Increased by 4GiB
    overhead blocks used            : 538846   # Did not significantly change
    logical blocks used             : 7108036  # Increased by 4GiB

    这个命令应该显示使用的块数量增加,与写入文件的大小相对应。

  7. 将文件复制到 10 个子目录中的每个子目录中:

    $ for i in {01..10}; do
      cp /mnt/vdo-test/sourcefile /mnt/vdo-test/vdo$i
      done
  8. 重新定义已使用的物理磁盘空间量:

    $ df -h /mnt/vdo-test

    例 3.5. 复制文件后磁盘用量

    Filesystem            Size  Used Avail Use% Mounted on
    /dev/mapper/vdo-test  1.5T   45G  1.3T   4% /mnt/vdo-test
    # vdostats --verbose | grep "blocks used"

    例 3.6. 复制文件后使用的块

    data blocks used                : 1050836   # Increased by 3 MiB
    overhead blocks used            : 538846
    logical blocks used             : 17594127  # Increased by 41 GiB

    data blocks used 的值应当与先前列表的结果相似,只是由于文件系统日志和元数据而稍有增加。

  9. 从写测试数据之前找到的值中减去文件系统所使用的空间的新值。从文件系统的角度来看,这是此测试所使用的空间量。
  10. 观察您记录统计中的空间节能:

    例 3.7. 记录的值

    统计裸机文件系统seed 后10 个副本后

    文件系统使用大小

    198 MiB

    4.2 GiB

    45 GiB

    使用 VDO 数据

    4 MiB

    4.1 GiB

    4.1 GiB

    使用 VDO 逻辑

    23.6 GiB (1.6 TiB 格式驱动器的文件系统开销)

    27.8 GiB

    68.7 GiB

    注意

    在下表中,值已转换为 MiB 或 GiB。vdostats 输出中的大小为 4,096 B。

清理步骤

3.8. 测量 VDO 压缩

此流程在 VDO 测试卷中测试 VDO 数据压缩的效率。

先决条件

流程

  1. 禁用 deduplication 并在 VDO 测试卷中启用压缩:

    # vdo disableDeduplication --name=vdo-test
    # vdo enableCompression --name=vdo-test
  2. 同步 VDO 卷以完成所有未完成压缩:

    # sync && dmsetup message vdo-test 0 sync-dedupe
  3. 在传输前检查 VDO 统计:

    # vdostats --verbose | grep "blocks used"

    记下 data blocks usedlogical blocks used 的值。

  4. VDO 优化文件系统开销以及实际的用户数据。计算为空文件系统压缩而节省的 4 KiB 块的数量,来作为 logical blocks used 减去 data blocks used
  5. /lib 目录的内容复制到 VDO 卷中:

    # cp --verbose --recursive /lib /mnt/vdo-test
    
    ...
    sent 152508960 bytes  received 60448 bytes  61027763.20 bytes/sec
    total size is 152293104  speedup is 1.00

    记录复制数据的总大小。

  6. 同步 Linux 缓存和 VDO 卷:

    # sync && dmsetup message vdo-test 0 sync-dedupe
  7. 再次检查 VDO 统计:

    # vdostats --verbose | grep "blocks used"

    观察 logical blocks useddata blocks used 的值。

  8. 使用以下公式计算压缩保存的字节数:

    saved_bytes = (logical_blocks_used - data_blocks_used) * 4096

清理步骤

3.9. 测量 VDO 空间总耗

此流程测试 VDO 数据变异以及在 VDO 测试卷中压缩的效率。

流程

  1. 创建并挂载 VDO 卷,如 第 3.4 节 “创建 VDO 测试卷” 中所述。
  2. 在同一卷上执行测试,如 测量 VDO 去除重复数据测量 VDO 压缩 中所述,而不删除它。观察 vdostats 输出中空间节省的变化。
  3. 使用您自己的数据集进行测试。

3.10. 测试 TRIM 和 DISCARD 对 VDO 的影响

此流程测试 TRIMDISCARD 命令是否能正确地从 VDO 测试卷上已删除的文件中释放块。它演示了,丢弃告知 VDO 不再使用空间。

先决条件

流程

  1. 准备可记录测试结果的表:

    步骤已使用的文件空间(MB)已使用的数据块使用的逻辑块

    初始空间

       

    添加 1 GiB 文件

       

    运行 fstrim

       

    删除 1 GiB 文件

       

    运行 fstrim

       
  2. 清理文件系统来删除不需要的块:

    # fstrim /mnt/vdo-test

    该命令可能需要很长时间。

  3. 记录文件系统中初始空间的使用情况:

    $ df -m /mnt/vdo-test
  4. 请查看 VDO 卷使用的物理和逻辑数据块数:

    # vdostats --verbose | grep "blocks used"
  5. 使用 VDO 卷上的非重复数据创建一个 1 GiB 文件:

    $ dd if=/dev/urandom of=/mnt/vdo-test/file bs=1M count=1K
  6. 再次记录空间使用量:

    $ df -m /mnt/vdo-test
    
    # vdostats --verbose | grep "blocks used"

    文件系统应使用额外的 1 GiB。data blocks usedlogical blocks used 的值应该同样增加。

  7. 再次执行文件系统:

    # fstrim /mnt/vdo-test
  8. 再次检查空间用量,确认清除操作不会影响物理卷的使用:

    $ df -m /mnt/vdo-test
    
    # vdostats --verbose | grep "blocks used"
  9. 删除 1 GiB 文件:

    $ rm /mnt/vdo-test/file
  10. 检查并记录空间使用情况:

    $ df -m /mnt/vdo-test
    
    # vdostats --verbose | grep "blocks used"

    文件系统知道已删除了某个文件,但是由于没有指向底层存储,物理或逻辑块的数量不会改变。

  11. 再次执行文件系统:

    # fstrim /mnt/vdo-test
  12. 检查并记录空间使用情况:

    $ df -m /mnt/vdo-test
    
    # vdostats --verbose | grep "blocks used"

    fstrim 工具在文件系统中查找空闲的块,并为未使用的地址向 VDO 卷发送 TRIM 命令,这会释放相关的逻辑块。VDO 处理 TRIM 命令以释放底层物理块。

其它资源

第 4 章 测试 VDO 性能

您可以执行一系列测试来测量 VDO 的性能,使用 VDO 获取系统性能配置文件,并确定哪些应用程序在使用 VDO 时表现良好。

先决条件

  • 一个或多个 Linux 物理块设备可用。
  • 目标块设备(如 /dev/sdb)大于 512 GiB。
  • 灵活的 I/O 测试器(fio)已安装。
  • 已安装 VDO。

4.1. 为 VDO 性能测试准备环境

在测试 VDO 性能前,您必须考虑主机系统配置、VDO 配置以及测试过程中使用的工作负载。这些选择会影响空间效率、带宽和延迟程度基准测试。

要防止一个测试影响另一个测试的结果,您必须为每个测试的迭代创建一个新的 VDO 卷。

4.1.1. 测试 VDO 性能前的注意事项

以下条件和配置会影响 VDO 测试结果:

系统配置

  • 可用 CPU 内核数和类型。您可以使用 taskset 工具列出此信息。
  • 可用内存和总安装内存
  • 存储设备配置
  • 活跃磁盘调度程序
  • Linux 内核版本
  • 安装的软件包

VDO 配置

  • 分区方案
  • VDO 卷中使用的文件系统
  • 分配给 VDO 卷的物理存储大小
  • 创建的逻辑卷的大小
  • 稀疏或密度 UDS 索引
  • 内存大小的 UDS Index
  • VDO 线程配置

工作负载

  • 生成测试数据的工具类型
  • 并发客户端数
  • 写入数据中重复的 4 KiB 块的数量
  • 读和写的特征
  • 工作集大小

4.1.2. 测试 VDO 读取性能的特殊考虑

在测试 VDO 读取性能前,您必须考虑这些额外因素:

  • 如果从没有写入 4 KiB 块,VDO 不会从存储中读取,而是立即使用零块进行响应。
  • 如果写入了 4 KiB 块但包含所有的零,VDO 不会从存储中读取,并用零块立即响应。

当没有可读取数据时,读取性能会非常快。这是为什么读测试必须在卷前使用实际数据。

4.1.3. 准备系统测试 VDO 性能

此流程将系统设置配置为在测试过程中获得最佳 VDO 性能。

重要

测试超过特定测试中列出的范围可能会导致因为一般结果导致测试时间丢失。

例如,VDO 测试描述了一个测试,它对 100 GiB 地址范围执行随机读取。要测试一组 500 GiB,您必须相应地增加为 VDO 块映射缓存分配的 RAM 量。

流程

  1. 确定您的 CPU 在最高级别的性能设置中运行。
  2. 如果可能,使用 BIOS 配置或 Linux cpupower 工具禁用 CPU 频率扩展。
  3. 如果可能,请为 CPU 启用动态处理器频率调整(Turbo Boost 或者 Turbo Core)。此功能在测试结果中引入了一些变化,但提高了整体性能。
  4. 文件系统可能会对性能有唯一影响。它们通常会扭曲性能测量,使其更难隔离 VDO 对结果的影响。

    如果需要,测量原始块设备的性能。如果无法做到这一点,请格式化在目标实施中使用 VDO 所需文件系统的设备。

4.2. 创建用于性能测试的 VDO 卷

此流程在 512 GiB 物理卷中创建一个 VDO 卷,逻辑卷大小为 1 TiB,用于测试 VDO 性能。

流程

  • 创建 VDO 卷:

    # vdo create --name=vdo-test \
                 --device=/dev/sdb \
                 --vdoLogicalSize=1T \
                 --writePolicy=policy \
                 --verbose
    • 使用块设备的路径替换 /dev/sdb
    • 要在异步存储之上测试 VDO async 模式,请使用 --writePolicy=async 选项创建一个异步卷。
    • 要在同步存储之上测试 VDO sync 模式,请使用 --writePolicy=sync 选项创建一个同步卷。

4.3. 清理 VDO 性能测试卷

这个过程删除用于从系统中测试 VDO 性能的 VDO 卷。

先决条件

  • 系统中存在 VDO 测试卷。

流程

  • 从系统中删除 VDO 测试卷:

    # vdo remove --name=vdo-test

验证步骤

  • 验证卷是否已被删除:

    # vdo list --all | grep vdo-test

    这个命令不应该列出 VDO 测试分区。

4.4. 测试 I/O 深度对 VDO 性能的影响

这些测试为 VDO 配置决定了产生最佳吞吐量和最低延迟的 I/O 深度。I/O 深度代表 fio 工具一次提交的 I/O 请求数。

由于 VDO 使用 4 KiB 扇区大小,因此测试在 4 KiB I/O 操作以及 1、8、16、32、64、128、256、512 和 1024 的 I/O 深度时执行四角测试。

4.4.1. 测试 I/O 深度对 VDO 中顺序 100% 读的影响

此测试决定了在不同 I/O 深度值的 VDO 卷中顺序 100% 读操作如何执行。

流程

  1. 创建一个新的 VDO 卷。

    详情请查看 第 4.2 节 “创建用于性能测试的 VDO 卷”

  2. 通过对测试卷执行写 fio 作业来预先填充测试可能会访问的区域:

    # fio --rw=write \
          --bs=8M \
          --name=vdo \
          --filename=/dev/mapper/vdo-test \
          --ioengine=libaio \
          --thread \
          --direct=1 \
          --scramble_buffers=1
  3. 为顺序 100% 读记录报告的吞吐量和延迟:

    # for depth in 1 2 4 8 16 32 64 128 256 512 1024 2048; do
      fio --rw=read \
          --bs=4096 \
          --name=vdo \
          --filename=/dev/mapper/vdo-test \
          --ioengine=libaio \
          --numjobs=1 \
          --thread \
          --norandommap \
          --runtime=300 \
          --direct=1 \
          --iodepth=$depth \
          --scramble_buffers=1 \
          --offset=0 \
          --size=100g
      done
  4. 删除 VDO 测试卷。

    详情请查看 第 4.3 节 “清理 VDO 性能测试卷”

4.4.2. 测试 I/O 深度对 VDO 中顺序 100% 写的影响

此测试决定了在不同 I/O 深度值的 VDO 卷中顺序 100% 写操作如何执行。

流程

  1. 创建一个新的 VDO 测试卷。

    详情请查看 第 4.2 节 “创建用于性能测试的 VDO 卷”

  2. 通过执行写 fio 作业来预先填充测试可能会访问的区域:

    # fio --rw=write \
          --bs=8M \
          --name=vdo \
          --filename=/dev/mapper/vdo-test \
          --ioengine=libaio \
          --thread \
          --direct=1 \
          --scramble_buffers=1
  3. 为顺序 100% 写记录报告的吞吐量和延迟:

    # for depth in 1 2 4 8 16 32 64 128 256 512 1024 2048; do
      fio --rw=write \
          --bs=4096 \
          --name=vdo \
          --filename=/dev/mapper/vdo-test \
          --ioengine=libaio \
          --numjobs=1 \
          --thread \
          --norandommap \
          --runtime=300 \
          --direct=1 \
          --iodepth=$depth \
          --scramble_buffers=1 \
          --offset=0 \
          --size=100g
      done
  4. 删除 VDO 测试卷。

    详情请查看 第 4.3 节 “清理 VDO 性能测试卷”

4.4.3. 测试 I/O 深度对 VDO 中随机 100% 读取的影响

此测试决定了在不同 I/O 深度值的 VDO 卷中随机 100% 读取操作如何执行。

流程

  1. 创建一个新的 VDO 测试卷。

    详情请查看 第 4.2 节 “创建用于性能测试的 VDO 卷”

  2. 通过执行写 fio 作业来预先填充测试可能会访问的区域:

    # fio --rw=write \
          --bs=8M \
          --name=vdo \
          --filename=/dev/mapper/vdo-test \
          --ioengine=libaio \
          --thread \
          --direct=1 \
          --scramble_buffers=1
  3. 记录随机 100% 报告的吞吐量和延迟时间:

    # for depth in 1 2 4 8 16 32 64 128 256 512 1024 2048; do
      fio --rw=randread \
          --bs=4096 \
          --name=vdo \
          --filename=/dev/mapper/vdo-test \
          --ioengine=libaio \
          --numjobs=1 \
          --thread \
          --norandommap \
          --runtime=300 \
          --direct=1 \
          --iodepth=$depth \
          --scramble_buffers=1 \
          --offset=0 \
          --size=100g
      done
  4. 删除 VDO 测试卷。

    详情请查看 第 4.3 节 “清理 VDO 性能测试卷”

4.4.4. 在 VDO 中测试 I/O 深度对随机 100% 写入的影响

此测试决定了在不同 I/O 深度值的 VDO 卷中随机 100% 写入操作如何执行。

重要

您必须在每个 I/O 深度测试运行之间重新创建 VDO 卷。

流程

根据 1、2、4、8、16、32、64、128、256、512、1024 和 2048 的 I/O 深度值单独执行以下步骤:

  1. 创建一个新的 VDO 测试卷。

    详情请查看 第 4.2 节 “创建用于性能测试的 VDO 卷”

  2. 通过执行写 fio 作业来预先填充测试可能会访问的区域:

    # fio --rw=write \
          --bs=8M \
          --name=vdo \
          --filename=/dev/mapper/vdo-test \
          --ioengine=libaio \
          --thread \
          --direct=1 \
          --scramble_buffers=1
  3. 记录随机 100% 写的吞吐量和延迟时间:

    # fio --rw=randwrite \
          --bs=4096 \
          --name=vdo \
          --filename=/dev/mapper/vdo-test \
          --ioengine=libaio \
          --numjobs=1 \
          --thread \
          --norandommap \
          --runtime=300 \
          --direct=1 \
          --iodepth=depth-value
          --scramble_buffers=1 \
          --offset=0 \
          --size=100g
      done
  4. 删除 VDO 测试卷。

    详情请查看 第 4.3 节 “清理 VDO 性能测试卷”

4.4.5. 在不同 I/O 深度下分析 VDO 性能

以下示例采用以不同 I/O 深度值记录的 VDO 吞吐量和延迟。

观察整个范围内的行为和拐点,其中增加的 I/O 深度会降低吞吐量收益。顺序访问和随机访问的峰值可能不同,但对于所有类型的存储配置,峰值可能都有所不同。

例 4.1. I/O 深度分析

图 4.1. VDO 吞吐量分析

VDO 吞吐量分析

注意每个性能曲线中的"knee":

  • 标记 1 标识 X 点的峰值顺序吞吐量。此特定配置不从大于 X 的顺序 4 KiB I/O 深度中受益。
  • 标识 2 识别在 Z 点处的峰值随机 4 KiB 吞吐量。此特定配置不从大于 Z 的随机 4 KiB I/O 深度中受益。

除了点 XZ 处的 I/O 深度外,带宽收益在逐渐减少,每增加一个 I/O 请求,平均请求延迟就会增加 1:1。

下图显示了上图中在曲线的 "knee" 之后随机写入延迟的示例。您应该在这些点上测试导致最小响应时间损失的最大吞吐量。

图 4.2. VDO 延迟分析

VDO 延迟分析

最佳 I/O 深度

Z 标记最佳 I/O 深度。测试计划收集 I/O 深度等于 Z 的额外数据。

4.5. 测试 I/O 请求大小对 VDO 性能的影响

使用这些测试,您可以识别 VDO 在最佳 I/O 深度时获得最佳性能的块大小。

测试在固定 I/O 深度下执行四个测试,块大小为 8 KiB 到 1 MiB。

先决条件

4.5.1. 测试 I/O 请求大小对 VDO 中连续写入操作的影响

此测试决定了在不同 I/O 请求大小的 VDO 卷上如何执行后续写入操作。

流程

  1. 创建一个新的 VDO 卷。

    详情请查看 第 4.2 节 “创建用于性能测试的 VDO 卷”

  2. 通过对测试卷执行写 fio 作业来预先填充测试可能会访问的区域:

    # fio --rw=write \
          --bs=8M \
          --name=vdo \
          --filename=/dev/mapper/vdo-test \
          --ioengine=libaio \
          --thread \
          --direct=1 \
          --scramble_buffers=1
  3. 为后续写入测试记录报告的吞吐量和延迟:

    # for iosize in 4 8 16 32 64 128 256 512 1024; do
      fio --rw=write \
          --bs=${iosize}k \
          --name=vdo \
          --filename=/dev/mapper/vdo-test \
          --ioengine=libaio \
          --numjobs=1 \
          --thread \
          --norandommap \
          --runtime=300 \
          --direct=1 \
          --iodepth=optimal-depth \
          --scramble_buffers=1 \
          --offset=0 \
          --size=100g
      done
  4. 删除 VDO 测试卷。

    详情请查看 第 4.3 节 “清理 VDO 性能测试卷”

4.5.2. 测试 I/O 请求大小在 VDO 中随机写入时的影响

此测试决定了在不同 I/O 请求大小的 VDO 卷中随机写入操作如何执行。

重要

您必须在每个 I/O 请求大小测试运行之间重新创建 VDO 卷。

流程

针对大小为 4k8k16k32k64k128k256k512k1024k 的 I/O 请求大小分别执行以下系列步骤:

  1. 创建一个新的 VDO 卷。

    详情请查看 第 4.2 节 “创建用于性能测试的 VDO 卷”

  2. 通过对测试卷执行写 fio 作业来预先填充测试可能会访问的区域:

    # fio --rw=write \
          --bs=8M \
          --name=vdo \
          --filename=/dev/mapper/vdo-test \
          --ioengine=libaio \
          --thread \
          --direct=1 \
          --scramble_buffers=1
  3. 记录随机写入测试所报告吞吐量和延迟时间:

    # fio --rw=randwrite \
          --bs=request-size \
          --name=vdo \
          --filename=/dev/mapper/vdo-test \
          --ioengine=libaio \
          --numjobs=1 \
          --thread \
          --norandommap \
          --runtime=300 \
          --direct=1 \
          --iodepth=optimal-depth \
          --scramble_buffers=1 \
          --offset=0 \
          --size=100g
      done
  4. 删除 VDO 测试卷。

    详情请查看 第 4.3 节 “清理 VDO 性能测试卷”

4.5.3. 测试 I/O 请求大小对 VDO 中顺序读取的影响

此测试决定了在不同 I/O 请求大小的 VDO 卷上如何执行后续读操作。

流程

  1. 创建一个新的 VDO 卷。

    详情请查看 第 4.2 节 “创建用于性能测试的 VDO 卷”

  2. 通过对测试卷执行写 fio 作业来预先填充测试可能会访问的区域:

    # fio --rw=write \
          --bs=8M \
          --name=vdo \
          --filename=/dev/mapper/vdo-test \
          --ioengine=libaio \
          --thread \
          --direct=1 \
          --scramble_buffers=1
  3. 为后续读测试记录报告的吞吐量和延迟:

    # for iosize in 4 8 16 32 64 128 256 512 1024; do
      fio --rw=read \
          --bs=${iosize}k \
          --name=vdo \
          --filename=/dev/mapper/vdo-test \
          --ioengine=libaio \
          --numjobs=1 \
          --thread \
          --norandommap \
          --runtime=300 \
          --direct=1 \
          --iodepth=optimal-depth \
          --scramble_buffers=1 \
          --offset=0 \
          --size=100g
      done
  4. 删除 VDO 测试卷。

    详情请查看 第 4.3 节 “清理 VDO 性能测试卷”

4.5.4. 测试 VDO 中 I/O 请求大小对随机读取的影响

此测试决定了在不同 I/O 请求大小的 VDO 卷中随机读操作如何执行。

流程

  1. 创建一个新的 VDO 卷。

    详情请查看 第 4.2 节 “创建用于性能测试的 VDO 卷”

  2. 通过对测试卷执行写 fio 作业来预先填充测试可能会访问的区域:

    # fio --rw=write \
          --bs=8M \
          --name=vdo \
          --filename=/dev/mapper/vdo-test \
          --ioengine=libaio \
          --thread \
          --direct=1 \
          --scramble_buffers=1
  3. 记录随机读取测试所报告吞吐量和延迟时间:

    # for iosize in 4 8 16 32 64 128 256 512 1024; do
      fio --rw=read \
          --bs=${iosize}k \
          --name=vdo \
          --filename=/dev/mapper/vdo-test \
          --ioengine=libaio \
          --numjobs=1 \
          --thread \
          --norandommap \
          --runtime=300 \
          --direct=1 \
          --iodepth=optimal-depth \
          --scramble_buffers=1 \
          --offset=0 \
          --size=100g
      done
  4. 删除 VDO 测试卷。

    详情请查看 第 4.3 节 “清理 VDO 性能测试卷”

4.5.5. 分析不同 I/O 请求大小中的 VDO 性能

以下示例分析了对不同的 I/O 请求大小记录的 VDO 吞吐量和延迟。

例 4.2. I/O 请求大小分析

图 4.3. 请求大小与吞吐量分析,以及关键拐点

请求大小与吞吐量分析,以及关键拐点

分析示例结果:

  • 顺序写在请求大小 Y 处达到峰时吞吐量。

    此曲线演示了可配置或由特定请求大小自然主导的应用程序如何感知性能。较大的请求大小通常会提供更大的吞吐量,因为 4 KiB I/O 操作可能会从合并中受益。

  • 序列读取在 Z 点达到类似的峰值吞吐量。

    在达到这些峰值时,I/O 操作完成前的总体延迟会增加,且无额外的吞吐量。您应该调整该设备,使其不接受大于这个大小的 I/O 操作。

  • 随机读取在 X 点达到峰时吞吐量。

    当出现大的随机访问请求时,某些设备可能达到近似连续的吞吐率,但其他系统可能会在顺序访问时受到更多的损失。

  • 随机写入在 Y 点达到峰值吞吐量。

    随机写入主要涉及和 deduplication 设备的交互,VDO 会获得高性能,特别是请求的大小或者 I/O 深度较大时。

4.6. 测试混合 I/O 加载对 VDO 性能的影响

此测试决定了您的 VDO 配置在混合读和写 I/O 加载时的情况,并分析混合读取和写入在最优的随机队列深度和请求大小从 4KB 到 1 MB 时的影响。

这个过程使用固定 I/O 深度执行四级测试,块大小在 8 KB 到 256 KB 的范围内,读的百分比以 10% 增加,从 0% 开始。

先决条件

流程

  1. 创建一个新的 VDO 卷。

    详情请查看 第 4.2 节 “创建用于性能测试的 VDO 卷”

  2. 通过对测试卷执行写 fio 作业来预先填充测试可能会访问的区域:

    # fio --rw=write \
          --bs=8M \
          --name=vdo \
          --filename=/dev/mapper/vdo-test \
          --ioengine=libaio \
          --thread \
          --direct=1 \
          --scramble_buffers=1
  3. 记录所报告用于读取和写入输入的吞吐量和延迟时间:

    # for readmix in 0 10 20 30 40 50 60 70 80 90 100; do
        for iosize in 4 8 16 32 64 128 256 512 1024; do
          fio --rw=rw \
              --rwmixread=$readmix \
              --bs=${iosize}k \
              --name=vdo \
              --filename=/dev/mapper/vdo-test \
              --ioengine=libaio \
              --numjobs=1 \
              --thread \
              --norandommap \
              --runtime=300 \
              --direct=0 \
              --iodepth=optimal-depth \
              --scramble_buffers=1 \
              --offset=0 \
              --size=100g
        done
      done
  4. 删除 VDO 测试卷。

    详情请查看 第 4.3 节 “清理 VDO 性能测试卷”

  5. 图形化测试结果。

    例 4.3. 混合 I/O 负载分析

    以下镜像演示了 VDO 如何响应混合 I/O 负载的示例:

    图 4.4. 在不同读取和写入混合之间性能一致

    在不同读取和写入混合之间性能一致

    在读和写混合的范围内聚合性能和聚合延迟相对一致,趋势从较低的最大写吞吐量到较高的最大读吞吐量。

    此行为可能因不同的存储而异,但重要的观察是,性能在不同的负载下是一致的,或者您可以了解对演示特定的读写混合的应用程序的性能期望。

    注意

    如果您的系统没有显示类似的响应一致性,这可能代表还不是最佳配置。如果出现这种情况,请联络您的红帽销售工程师。

4.7. 测试应用程序环境对 VDO 性能的影响

这些测试决定了在混合的实际应用程序环境中部署 VDO 配置如何动作。如果您知道更多有关预期环境的详细信息,还要对其进行测试。

先决条件

  • 考虑在您的配置中限制允许的队列深度。
  • 如果可能,请调整应用程序以使用对 VDO 性能最有用的块大小的请求。

流程

  1. 创建一个新的 VDO 卷。

    详情请查看 第 4.2 节 “创建用于性能测试的 VDO 卷”

  2. 通过对测试卷执行写 fio 作业来预先填充测试可能会访问的区域:

    # fio --rw=write \
          --bs=8M \
          --name=vdo \
          --filename=/dev/mapper/vdo-test \
          --ioengine=libaio \
          --thread \
          --direct=1 \
          --scramble_buffers=1
  3. 记录所报告用于读取和写入输入的吞吐量和延迟时间:

    # for readmix in 20 50 80; do
        for iosize in 4 8 16 32 64 128 256 512 1024; do
          fio --rw=rw \
              --rwmixread=$readmix \
              --bsrange=4k-256k \
              --name=vdo \
              --filename=/dev/mapper/vdo-name \
              --ioengine=libaio \
              --numjobs=1 \
              --thread \
              --norandommap \
              --runtime=300 \
              --direct=0 \
              --iodepth=$iosize \
              --scramble_buffers=1 \
              --offset=0 \
              --size=100g
        done
      done
  4. 删除 VDO 测试卷。

    详情请查看 第 4.3 节 “清理 VDO 性能测试卷”

  5. 图形化测试结果。

    例 4.4. 应用程序环境分析

    以下镜像演示了 VDO 如何响应混合 I/O 负载的示例:

    图 4.5. 混合环境性能

    混合环境性能

4.8. 用于使用 fio 测试 VDO 性能的选项

VDO 测试使用 fio 工具来整合生成具有可重复特征的数据。在测试中,需要以下 fio 选项来模拟真实世界的工作负载:

表 4.1. 使用的 fio 选项

参数描述测试中使用的值

--size

fio 按作业发送给目标的数据量。

另请参阅 --numjobs 选项。

100 GiB

--bs

fio 生成的每个读写请求的块大小。

红帽建议使用 4 KiB 块大小匹配 4 KiB 默认 VDO。

4k

--numjobs

fio 为基准所创建的作业量。

每个作业发送由 --size 选项指定的数据量。第一个作业将数据发送到 --offset 选项指定的偏移处的设备。除非提供了 --offset_increment 选项,否则后续作业将覆盖磁盘的同一区域,这会使每个作业从上一个作业在该值开始的位置偏移。

为了在闪存磁盘(SSD)上达到峰值性能,红帽建议至少有两个作业。一个作业通常足以饱和旋转型磁盘(HDD)吞吐量。

1 代表 HDD,2 代表 SSD

--thread

指示 fio 作业在线程中运行,而不是 fork ,这可以通过限制上下文切换来提供更好的性能。

none

--ioengine

fio 用于基准测试的 I/O 引擎。

红帽测试使用名为 libaio 的异步非缓冲引擎测试一个或多个进程同时进行随机请求的工作负载。libaio 引擎可让单个线程在检索任何数据之前异步发出多个请求。这限制了同步引擎如果许多线程提供请求时所需的上下文切换数。

libaio

--direct

该选项允许提交到该设备的请求绕过内核页面缓存。

您必须将 libaio 引擎与 --direct 选项一起使用。否则,内核将同步 API 用于所有 I/O 请求。

1(libaio)

--iodepth

任意时刻的 I/O 缓冲数量。

高的值通常会提高性能,特别是用于随机读取和写入时。高值可确保控制器始终具有批处理请求。但是,设置这个值太大(通常大于 1K)可能会导致不必要的延迟。

红帽建议 128 到 512 之间的值。最终的值会是一个折中的选择,它取决于您的应用程序如何容忍延迟。

至少 128

--iodepth_batch_submit

当 I/O 深度缓冲池开始为空时创建的 I/O 请求数目。

这个选项限制任务从 I/O 操作切换为缓冲创建。

16

--iodepth_batch_complete

提交批处理前需要完成的 I/O 操作数目。

这个选项限制任务从 I/O 操作切换为缓冲创建。

16

--gtod_reduce

禁用日常调用来计算延迟。

如果启用,这个设置会降低吞吐量。启用此选项,除非您需要测量延迟。

1

第 5 章 丢弃未使用块

您可以在支持它们的块设备中执行或调度丢弃操作。块丢弃操作与底层存储进行通信,其中文件系统块不再被挂载的文件系统使用。块丢弃操作允许 SSD 优化垃圾回收例程,它们可以通知精简置备存储来重新使用未使用的物理块。

要求

  • 基本文件系统的块设备必须支持物理的丢弃(discard)操作。

    如果 /sys/block/<device>/queue/discard_max_bytes 文件中的值不为零,则支持物理丢弃操作。

5.1. 块丢弃操作的类型

您可以使用不同方法运行 discard 操作:

批量丢弃
由用户明确触发,并丢弃所选文件系统中所有未使用的块。
在线丢弃
在挂载时指定,并实时触发,而无需用户干预。在线丢弃操作只丢弃从 used 变为free 状态的块。
定期丢弃
systemd 服务定期运行的批处理操作。

XFS 和 ext4 文件系统支持所有类型。

建议

红帽建议您使用批处理或周期性丢弃。

仅在以下情况下使用在线丢弃:

  • 系统负载不允许使用批量丢弃,或者
  • 为了保持性能,需要在线丢弃操作。

5.2. 执行批块丢弃

您可以执行批量块丢弃操作,以丢弃挂载的文件系统上未使用的块。

先决条件

  • 挂载文件系统。
  • 文件系统底层的块设备支持物理忽略操作。

流程

  • 使用 fstrim 工具:

    • 要只在所选文件系统中执行丢弃,请使用:

      # fstrim mount-point
    • 要在所有挂载的文件系统中执行丢弃,请使用:

      # fstrim --all

如果您在以下设备上执行 fstrim 命令:

  • 不支持丢弃操作的设备,或者
  • 由多个设备组成的逻辑设备(LVM 或者 MD),其中任意设备不支持丢弃操作:

下面的信息将显示:

# fstrim /mnt/non_discard

fstrim: /mnt/non_discard: the discard operation is not supported

其它资源

  • fstrim(8) 手册页。

5.3. 启用在线块丢弃

您可以执行在线块丢弃操作,以自动丢弃所有支持的文件系统上未使用的块。

流程

  • 在挂载时启用在线丢弃:

    • 手动挂载文件系统时,请添加 -o discard 挂载选项:

      # mount -o discard device mount-point
    • 永久挂载文件系统时,请将 discard 选项添加到 /etc/fstab 文件中的挂载条目中。

其它资源

  • mount(8) 手册页。
  • fstab(5) 手册页。

5.4. 启用定期块丢弃

您可以启用 systemd 计时器来定期丢弃所有支持的文件系统上未使用的块。

流程

  • 启用并启动 systemd 计时器:

    # systemctl enable --now fstrim.timer
    Created symlink /etc/systemd/system/timers.target.wants/fstrim.timer → /usr/lib/systemd/system/fstrim.timer.

验证

  • 验证计时器的状态:

    # systemctl status fstrim.timer
    fstrim.timer - Discard unused blocks once a week
       Loaded: loaded (/usr/lib/systemd/system/fstrim.timer; enabled; vendor preset: disabled)
       Active: active (waiting) since Wed 2023-05-17 13:24:41 CEST; 3min 15s ago
      Trigger: Mon 2023-05-22 01:20:46 CEST; 4 days left
         Docs: man:fstrim
    
    May 17 13:24:41 localhost.localdomain systemd[1]: Started Discard unused blocks once a week.

第 6 章 持久性命名属性概述

作为系统管理员,您需要引用使用持久性命名属性的存储卷来构建比多个系统引导更可靠存储设置。

6.1. 非持久性命名属性的缺陷

Red Hat Enterprise Linux 提供识别存储设备的多种方法。使用选项时,务必使用正确的选项来识别每个设备,以避免无意中访问错误的设备,特别是在安装到驱动器或重新格式化驱动器时。

通常,在Linux 上以 /dev/sd(主号)(次号) 形式使用非持久化名称来指向存储设备。当检测设备时,会为每个设备分配主号和次号范围以及相关的 sd 名称。这意味着,如果设备的检测顺序发生了变化,主号和次号范围以及相关的 sd 名称之间的关联可能也会发生变化。

在以下情况下可能会在以下情况下更改排序:

  • 系统引导过程的并行化会根据每个系统引导的顺序检测到存储设备。
  • 磁盘无法启动或响应 SCSI 控制器。这会导致通常的设备探测不会检测到它。系统无法访问磁盘,后续设备将下移主号和次号范围,包括相关的 sd 名称。例如,如果没有检测到通常称为 sdb 的磁盘,则通常称为 sdc 的磁盘将显示为 sdb
  • SCSI 控制器(主机总线适配器或 HBA)无法初始化,从而导致没有检测到连接到该 HBA 的所有磁盘。任何连接到后续探测到的 HBA 的磁盘都会被分配不同的主号和次号范围,以及不同的相关 sd 名称。
  • 如果系统中存在不同类型的 HBA,则驱动初始化顺序会改变。这会导致连接到那些 HBA 的磁盘以不同顺序被检测到。当将 HBA 移动到系统的不同 PCI 插槽时也会出现这种情况。
  • 例如,由于存储阵列或干预交换机关机,通过光纤通道、iSCSI 或 FCoE 适配器连接到系统的磁盘可能在探测到存储设备时无法访问。如果存储阵列的在线需要比系统启动的时间更长,则系统在电源失败后重启时会出现这种情况。虽然某些光纤通道驱动程序支持一种指定持久性 SCSI 目标 ID 到 WWPN 映射的机制,但这不会导致保留主号和次号范围,以及相关的 sd 名称,它只提供一致的 SCSI 目标 ID 号。

这些原因使得在引用设备时,例如在 /etc/fstab 文件中,不希望使用主号和次号或相关的 sd 名称。可能挂载了错误的设备,并可能导致数据崩溃。

然而,偶尔仍需要引用 sd 名称,即使使用了其它机制,比如当设备报告错误时。这是因为 Linux 内核在有关设备的内核消息中使用了 sd 名称(以及 SCSI 主机/通道/目标/LUN 元组)。

6.2. 文件系统和设备识别符

这部分解释了识别文件系统和块设备的持久性属性之间的区别。

文件系统识别符

文件系统标识符与在块设备中创建的特定文件系统绑定。标识符也作为文件系统的一部分保存。如果您将文件系统复制到不同的设备中,它仍采用相同的文件系统识别符。另一方面,如果您重写设备,比如使用 mkfs 工具对其格式化,则设备会丢失属性。

文件系统识别符包括:

  • 唯一标识符(UUID)
  • 标签

设备识别符

设备标识符与块设备绑定:例如磁盘或者分区。如果您重写设备,比如使用 mkfs 工具对其格式化,则设备会保留属性,因为它不存储在文件系统中。

设备识别符包括:

  • World Wide Identifier (WWID)
  • 分区 UUID
  • 序列号

建议

  • 有些文件系统(比如逻辑卷)会跨越多个设备。红帽建议您使用文件系统识别符而不是设备标识符访问这些文件系统。

6.3. 使用 /dev/disk/ 中的 udev 机制管理的设备名称

udev 机制用于 Linux 中所有设备类型,不仅限于存储设备。它在 /dev/disk/ 目录中提供不同类型的持久性命名属性。对于存储设备,Red Hat Enterprise Linux 包含 udev 规则,该规则在 /dev/disk/ 目录中创建符号链接。这可让您使用以下方法指向存储设备:

  • 其内容
  • 唯一标识符
  • 它们的序列号。

虽然 udev 命名属性是持久的,但它们在系统重启后不会自行更改,有些部分还可配置。

6.3.1. 文件系统识别符

/dev/disk/by-uuid/ 中的 UUID 属性

此目录中的条目提供一个符号链接名称,其通过存储在设备上的内容(即数据)中的 唯一标识符 (UUID)来指向存储设备。例如:

/dev/disk/by-uuid/3e6be9de-8139-11d1-9106-a43f08d823a6

您可以使用以下语法,使用 UUID 来指向 /etc/fstab 文件中的设备:

UUID=3e6be9de-8139-11d1-9106-a43f08d823a6

您可以在创建文件系统时配置 UUID 属性,您也可以稍后修改它。

/dev/disk/by-label/ 中的 Label 属性

这个目录中的条目提供了一个符号链接名称,它们使用保存在该设备中的内容(即数据)的一个 label 指向存储设备。

例如:

/dev/disk/by-label/Boot

您可以使用以下语法,使用标签来指向 /etc/fstab 文件中的设备:

LABEL=Boot

您可以在创建文件系统时配置 Label 属性,您也可以稍后修改它。

6.3.2. 设备识别符

/dev/disk/by-id/ 中的 WWID 属性

全球识别符(WWID)是一个持久的、系统独立的标识符,SCSI 标准要求所有 SCSI 设备都使用它。WWID 标识符确保对每个存储设备都是唯一的,并且与用于访问设备的路径无关。标识符是设备的属性,但不存储在设备上的内容(即数据)中。

可通过发出 SCSI 查询来检索设备识别重要产品数据(第 0x83 页)或单元序列号(第 0x80 页)来获取此标识符。

Red Hat Enterprise Linux 自动维护系统上从基于 WWID 的设备名称到当前 /dev/sd 名称的正确映射。应用程序可以使用 /dev/disk/by-id/ 名称来引用磁盘上的数据,即使设备的路径改变了,即使从不同的系统访问设备。

例 6.1. WWID 映射

WWID 符号链接非持久性设备备注

/dev/disk/by-id/scsi-3600508b400105e210000900000490000

/dev/sda

具有页 0x83 标识符的设备

/dev/disk/by-id/scsi-SSEAGATE_ST373453LW_3HW1RHM6

/dev/sdb

具有页 0x80 标识符的设备

/dev/disk/by-id/ata-SAMSUNG_MZNLN256HMHQ-000L7_S2WDNX0J336519-part3

/dev/sdc3

磁盘分区

除了系统提供的这些持久名称外,您也可以使用 udev 规则来实现自己的持久名称,映射到存储的 WWID 。

/dev/disk/by-partuuid 中的分区 UUID 属性

分区 UUID(PARTUUID)属性标识 GPT 分区表定义的分区。

例 6.2. 分区 UUID 映射

PARTUUID 符号链接非持久性设备

/dev/disk/by-partuuid/4cd1448a-01

/dev/sda1

/dev/disk/by-partuuid/4cd1448a-02

/dev/sda2

/dev/disk/by-partuuid/4cd1448a-03

/dev/sda3

/dev/disk/by-path/ 中的 Path 属性

此属性提供一个符号链接名称,其通过用于访问设备的 硬件路径 指向存储设备。

如果硬件路径的任何部分(如 PCI ID、目标端口或 LUN 号)发生变化,Path 属性会失败。因此 Path 属性是不可靠的。但是 Path 属性在以下情况下可能有用:

  • 您需要识别您要替换的磁盘。
  • 您计划在特定位置的磁盘中安装存储服务。

6.4. 使用 DM 多路径的通用识别符

您可以配置设备映射器(DM)多路径,以在全局识别符(WWID)和非持久性设备名称之间进行映射。

如果系统中有多路径到某个设备,DM 多路径会使用 WWID 探测到这个设备。然后,DM 多路径会在 /dev/mapper/wwid 目录中显示一个"pseudo-device",如 /dev/mapper/3600508b400105df70000e00000ac0000

multipath -l 命令显示到非持久性标识符的映射:

  • Host:Channel:Target:LUN
  • /dev/sd 名称

例 6.3. 多路径配置中的 WWID 映射

multipath -l 命令的输出示例:

3600508b400105df70000e00000ac0000 dm-2 vendor,product
[size=20G][features=1 queue_if_no_path][hwhandler=0][rw]
\_ round-robin 0 [prio=0][active]
 \_ 5:0:1:1 sdc 8:32  [active][undef]
 \_ 6:0:1:1 sdg 8:96  [active][undef]
\_ round-robin 0 [prio=0][enabled]
 \_ 5:0:0:1 sdb 8:16  [active][undef]
 \_ 6:0:0:1 sdf 8:80  [active][undef]

DM 多路径自动维护系统上每个基于 WWID 的设备名称到对应的 /dev/sd 名称的正确映射。这些名称可在路径更改之间保留,在从不同系统访问该设备时会保持一致。

当使用 DM 多路径的 user_friendly_names 功能时,WWID 映射到形式 /dev/mapper/mpathN 的名称。默认情况下,此映射在文件 /etc/multipath/bindings 中维护。只要该文件得到维护,这些 mpathN 名称就会保持不变。

重要

如果使用 user_friendly_names,则需要额外的步骤来获得集群中的一致名称。

6.5. udev 设备命名规则的限制

以下是 udev 命名规则的一些限制:

  • 执行查询时可能无法访问该设备,因为 udev 机制可能依赖于对 udev 事件处理 udev 规则时查询存储设备的能力。当设备不在服务器机箱中时,这更可能会在光纤频道、iSCSI 或者 FCoE 存储设备中发生。
  • 内核可能会随时发送 udev 事件,从而导致规则被处理,并可能导致 /dev/disk/by-*/ 链接在设备无法访问时被删除。
  • 在生成 udev 事件和事件被处理时可能会有延迟,如检测到大量设备,以及用户空间 udevd 服务需要花费一些时间来处理每个事件的规则时。这可能会在内核检测到该设备和在 /dev/disk/by-*/ 名称可用之间造成延迟。
  • 规则调用的 blkid 等外部程序可能会打开设备一段时间,使设备无法用于其他用途。
  • /dev/disk/ 中 udev 机制管理的设备名称可能会在主版本之间有所变化,需要您更新链接。

6.6. 列出持久性命名属性

这个步骤描述了如何找到非持久性存储设备的持久命名属性。

流程

  • 要列出 UUID 和 Label 属性,请使用 lsblk 工具:

    $ lsblk --fs storage-device

    例如:

    例 6.4. 查看文件系统的 UUID 和标签

    $ lsblk --fs /dev/sda1
    
    NAME FSTYPE LABEL UUID                                 MOUNTPOINT
    sda1 xfs    Boot  afa5d5e3-9050-48c3-acc1-bb30095f3dc4 /boot
  • 要列出 PARTUUID 属性,请使用 lsblk 工具和 --output +PARTUUID 选项:

    $ lsblk --output +PARTUUID

    例如:

    例 6.5. 查看分区的 PARTUUID 属性

    $ lsblk --output +PARTUUID /dev/sda1
    
    NAME MAJ:MIN RM  SIZE RO TYPE MOUNTPOINT PARTUUID
    sda1   8:1    0  512M  0 part /boot      4cd1448a-01
  • 要列出 WWID 属性,请检查 /dev/disk/by-id/ 目录中符号链接的目标。例如:

    例 6.6. 查看系统中所有存储设备的 WWID

    $ file /dev/disk/by-id/*
    
    /dev/disk/by-id/ata-QEMU_HARDDISK_QM00001
    symbolic link to ../../sda
    /dev/disk/by-id/ata-QEMU_HARDDISK_QM00001-part1
    symbolic link to ../../sda1
    /dev/disk/by-id/ata-QEMU_HARDDISK_QM00001-part2
    symbolic link to ../../sda2
    /dev/disk/by-id/dm-name-rhel_rhel8-root
    symbolic link to ../../dm-0
    /dev/disk/by-id/dm-name-rhel_rhel8-swap
    symbolic link to ../../dm-1
    /dev/disk/by-id/dm-uuid-LVM-QIWtEHtXGobe5bewlIUDivKOz5ofkgFhP0RMFsNyySVihqEl2cWWbR7MjXJolD6g
    symbolic link to ../../dm-1
    /dev/disk/by-id/dm-uuid-LVM-QIWtEHtXGobe5bewlIUDivKOz5ofkgFhXqH2M45hD2H9nAf2qfWSrlRLhzfMyOKd
    symbolic link to ../../dm-0
    /dev/disk/by-id/lvm-pv-uuid-atlr2Y-vuMo-ueoH-CpMG-4JuH-AhEF-wu4QQm
    symbolic link to ../../sda2

6.7. 修改持久性命名属性

这个步骤描述了如何更改文件系统的 UUID 或 Label persistent naming 属性。

注意

更改 udev 属性发生在后台,可能需要很长时间。udevadm settle 命令会等待,直到更改被完全注册,这样可确保您的下一个命令能够正确使用新属性。

在以下命令中:

  • new-uuid 替换为您要设置的 UUID;例如,1cdfbc07-1c90-4984-b5ec-f61943f5ea50。您可以使用 uuidgen 命令生成 UUID。
  • 使用标签替换 new-label,如 backup_data

先决条件

  • 如果您要修改 XFS 文件系统的属性,首先卸载它。

流程

  • 要更改 XFS 文件系统的 UUID 或 Label 属性,请使用 xfs_admin 工具:

    # xfs_admin -U new-uuid -L new-label storage-device
    # udevadm settle
  • 要更改 ext4ext3ext2 文件系统的 UUID 或 Label 属性,请使用 tune2fs 工具:

    # tune2fs -U new-uuid -L new-label storage-device
    # udevadm settle
  • 要更改 swap 卷的 UUID 或 Label 属性,请使用 swaplabel 工具:

    # swaplabel --uuid new-uuid --label new-label swap-device
    # udevadm settle

第 7 章 使用 Web 控制台管理 Virtual Data Optimizer 卷

使用 RHEL 8 web 控制台配置 Virtual Data Optimizer(VDO)。

您将学习如何:

  • 创建 VDO 卷
  • 格式化 VDO 卷
  • 扩展 VDO 卷

先决条件

  • RHEL 8 web 控制台已安装并可以访问。详情请参阅安装 Web 控制台
  • cockpit-storaged 软件包已安装在您的系统上。

7.1. Web 控制台中的 VDO 卷

Red Hat Enterprise Linux 8 支持 Virtual Data Optimizer(VDO)。

VDO 是一个组合了以下功能的虚拟化技术:

压缩
详情请参阅 在VDO 中启用或禁用压缩
重复数据删除(Deduplication)
详情请参阅 在VDO 中启用或禁用压缩
精简置备
详情请参阅创建和管理精简置备卷(精简卷)

使用这些技术,VDO:

  • 保存存储空间内联
  • 压缩文件
  • 消除重复
  • 可让您分配超过物理或者逻辑存储量的虚拟空间
  • 允许您通过增大虚拟存储来扩展虚拟存储

VDO 可以在很多类型的存储之上创建。在 RHEL 8 web 控制台中,您可以在以下之上配置 VDO:

  • LVM

    注意

    不可能在精简置备的卷之上配置 VDO。

  • 物理卷
  • 软件 RAID

有关在存储堆栈中放置 VDO 的详情,请参考 系统要求

其它资源

7.2. 在 web 控制台中创建 VDO 卷

在 RHEL web 控制台中创建 VDO 卷。

先决条件

  • 要创建 VDO 的物理驱动器、LVM 或者 RAID。

流程

  1. 登录到 RHEL 8 web 控制台。

    详情请参阅 Web 控制台的日志记录

  2. Storage
  3. VDO Devices 框中的 + 按钮。
  4. Name 字段中输入 VDO 卷的名称,没有空格。
  5. 选择要使用的驱动器。
  6. Logical Size 条中,设置 VDO 卷的大小。您可以扩展超过十倍,但请考虑创建 VDO 卷的目的是:

    • 对于活跃的虚拟机或容器存储,逻辑大小为物理大小的十倍。
    • 对于对象存储,逻辑大小为物理大小的三倍。

    详情请参阅 部署 VDO

  7. Index Memory 栏中,为 VDO 卷分配内存。

    有关 VDO 系统要求的详情,请参阅 系统要求

  8. 选择 Compression 选项。这个选项可以有效地减少各种文件格式。

    详情请参阅 在VDO 中启用或禁用压缩

  9. 选择 Deduplication 选项。

    这个选项通过删除重复块的多个副本来减少存储资源的消耗。详情请参阅 在VDO 中启用或禁用压缩

  10. [可选] 如果要使用需要 512 字节块大小的应用程序的 VDO 卷,请选择 使用 512 字节模拟。这会降低 VDO 卷的性能,但应该很少需要。如果不确定,请将其关机。
  11. Create

验证步骤

  • 检查您是否可在 Storage 部分看到新的 VDO 卷。然后您可以使用文件系统对其进行格式化。

7.3. 在 web 控制台中格式化 VDO 卷

VDO 卷作为物理驱动器使用。要使用它们,您需要使用文件系统进行格式化。

警告

格式化 VDO 将擦除卷上的所有数据。

以下步骤描述了格式化 VDO 卷的步骤。

先决条件

流程

  1. 登录到 RHEL 8 web 控制台。详情请参阅 Web 控制台的日志记录
  2. Storage
  3. 点 VDO 卷。
  4. Unrecognized Data 标签页。
  5. Format
  6. Erase 下拉菜单中选择:

    Don’t overwrite existing data
    RHEL web 控制台只重写磁盘标头。这个选项的优点是格式化速度。
    Overwrite existing data with zeros
    RHEL web 控制台使用 0 重写整个磁盘。这个选项较慢,因为程序必须经过整个磁盘。如果磁盘包含任何数据且需要重写数据,则使用这个选项。
  7. Type 下拉菜单中选择一个文件系统:

    • XFS 文件系统支持大的逻辑卷,在不停止工作的情况下在线切换物理驱动器,并增大。如果您没有不同的首选项,请保留这个文件系统。

      XFS 不支持缩小卷。因此,您将无法缩小使用 XFS 格式的卷。

    • ext4 文件系统支持逻辑卷,在不停止工作的情况下在线切换物理驱动器,并缩减。

    您还可以选择带有 LUKS(Linux 统一密钥设置)加密的版本,它允许您使用密码短语加密卷。

  8. Name 字段输入逻辑卷名称。
  9. Mounting 下拉菜单中选择 Custom

    Default 选项不会保证在下次引导时挂载该文件系统。

  10. Mount Point 字段中添加挂载路径。
  11. 选择 Mount at boot
  12. Format

    根据使用的格式化选项和卷大小,格式化的过程可能需要几分钟。

    成功完成后,,可以在 Filesystem 标签页中看到格式化的 VDO 卷的详情。

  13. 要使用 VDO 卷,点 Mount

此时,系统使用挂载的和格式化的 VDO 卷。

7.4. 在 web 控制台中扩展 VDO 卷

在 RHEL 8 web 控制台中扩展 VDO 卷。

先决条件

  • cockpit-storaged 软件包已安装在您的系统上。
  • 已创建的 VDO 卷。

流程

  1. 登录到 RHEL 8 web 控制台。

    详情请参阅 Web 控制台的日志记录

  2. Storage
  3. VDO Devices 框中点您的 VDO 卷。
  4. 在 VDO 卷详情中点 Grow 按钮。
  5. Grow logical size of VDO 对话框中,扩展 VDO 卷的逻辑大小。
  1. Grow

验证步骤

  • 检查 VDO 卷详情中的新大小,以验证您的更改是否成功。

法律通告

Copyright © 2024 Red Hat, Inc.
The text of and illustrations in this document are licensed by Red Hat under a Creative Commons Attribution–Share Alike 3.0 Unported license ("CC-BY-SA"). An explanation of CC-BY-SA is available at http://creativecommons.org/licenses/by-sa/3.0/. In accordance with CC-BY-SA, if you distribute this document or an adaptation of it, you must provide the URL for the original version.
Red Hat, as the licensor of this document, waives the right to enforce, and agrees not to assert, Section 4d of CC-BY-SA to the fullest extent permitted by applicable law.
Red Hat, Red Hat Enterprise Linux, the Shadowman logo, the Red Hat logo, JBoss, OpenShift, Fedora, the Infinity logo, and RHCE are trademarks of Red Hat, Inc., registered in the United States and other countries.
Linux® is the registered trademark of Linus Torvalds in the United States and other countries.
Java® is a registered trademark of Oracle and/or its affiliates.
XFS® is a trademark of Silicon Graphics International Corp. or its subsidiaries in the United States and/or other countries.
MySQL® is a registered trademark of MySQL AB in the United States, the European Union and other countries.
Node.js® is an official trademark of Joyent. Red Hat is not formally related to or endorsed by the official Joyent Node.js open source or commercial project.
The OpenStack® Word Mark and OpenStack logo are either registered trademarks/service marks or trademarks/service marks of the OpenStack Foundation, in the United States and other countries and are used with the OpenStack Foundation's permission. We are not affiliated with, endorsed or sponsored by the OpenStack Foundation, or the OpenStack community.
All other trademarks are the property of their respective owners.