dm-vdo¶
dm-vdo(虚拟数据优化器)设备映射器目标提供块级去重、压缩和精简配置。作为设备映射器目标,它可以将这些功能添加到存储堆栈中,与任何文件系统兼容。vdo 目标不防止数据损坏,而是依赖于其下方存储的完整性保护。强烈建议使用 lvm 来管理 vdo 卷。请参阅 lvmvdo(7)。
用户空间组件¶
格式化 vdo 卷需要使用 “vdoformat” 工具,该工具可在以下位置获取
https://github.com/dm-vdo/vdo/
在大多数情况下,vdo 目标会在下次启动时自动从崩溃中恢复。如果遇到无法恢复的错误(在正常操作或崩溃恢复期间),该目标将进入或以只读模式启动。由于只读模式表示数据丢失,因此必须采取积极措施才能使 vdo 退出只读模式。 “vdoforcerebuild” 工具(可从同一存储库获得)用于准备只读 vdo 以退出只读模式。运行此工具后,vdo 目标会在下次启动时重建其元数据。虽然可能会丢失一些数据,但重建的 vdo 的元数据将在内部保持一致,并且该目标将再次可写。
该存储库还包含其他用户空间工具,可用于检查 vdo 目标的磁盘元数据。幸运的是,这些工具很少需要,除非是 dm-vdo 开发人员使用。
元数据要求¶
每个 vdo 卷都会保留 3GB 的空间用于元数据,或者更多,具体取决于其配置。检查通过去重和压缩节省的空间是否被元数据要求抵消是很有帮助的。可以使用 vdo 估计器工具计算特定数据集节省的空间估计值,该工具可在以下位置获取
目标接口¶
表格行¶
<offset> <logical device size> vdo V4 <storage device>
<storage device size> <minimum I/O size> <block map cache size>
<block map era length> [optional arguments]
必需参数
- 偏移量
vdo 卷逻辑空间开始处的偏移量(以扇区为单位)。
- 逻辑设备大小
vdo 卷将服务的设备大小(以扇区为单位)。必须与 vdo 卷的当前逻辑大小匹配。
- 存储设备
保存 vdo 卷数据和元数据的设备。
- 存储设备大小
保存 vdo 卷的设备大小,以 4096 字节的块数表示。必须与 vdo 卷的当前大小匹配。
- 最小 I/O 大小
此 vdo 卷接受的最小 I/O 大小(以字节为单位)。有效值为 512 或 4096。建议值为 4096。
- 块映射缓存大小
块映射缓存的大小,以 4096 字节的块数表示。最小和建议值为 32768 个块。如果逻辑线程计数非零,则缓存大小必须至少为每个逻辑线程 4096 个块。
- 块映射时代长度
块映射缓存写出修改后的块映射页面的速度。较小的时代长度可能会减少重建所花费的时间,但代价是在正常操作期间增加块映射写入。最大和建议值为 16380;最小值为 1。
可选参数:¶
这些参数中的一些或全部可以指定为 <key> <value> 对。
线程相关参数
不同类别的工作被分配给单独的线程组,并且每个组中的线程数可以单独配置。
如果 <hash>、<logical> 和 <physical> 都设置为 0,则所有三种线程类型处理的工作将由单个线程处理。如果其中任何一个值为非零,则所有值都必须为非零。
- ack
用于完成 bio 的线程数。由于完成 bio 会在 vdo 卷之外调用任意完成函数,因此即使 bio 完成速度较慢,此类型的线程也允许 vdo 卷继续处理请求。默认为 1。
- bio
用于向底层存储发出 bio 的线程数。即使 bio 提交速度较慢,此类型的线程也允许 vdo 卷继续处理请求。默认为 4。
- bioRotationInterval
在切换到下一个线程之前,在每个 bio 线程上排队的 bio 数。该值必须大于 0 且不大于 1024;默认值为 64。
- cpu
用于执行 CPU 密集型工作的线程数,例如哈希和压缩。默认为 1。
- hash
用于管理基于数据块哈希值的去重数据比较的线程数。默认为 0。
- logical
用于管理基于传入 bio 的逻辑地址的缓存和锁定的线程数。默认值为 0;最大值为 60。
- physical
用于管理底层存储设备的线程数。在格式化时,会为 vdo 选择一个 slab 大小;vdo 存储设备必须足够大,以便每个物理线程至少有 1 个 slab。默认值为 0;最大值为 16。
其他参数
- maxDiscard
接受的最大丢弃 bio 大小,以 4096 字节的块为单位。对 vdo 卷的 I/O 请求通常分为 4096 字节的块,并且一次最多处理 2048 个块。但是,对 vdo 卷的丢弃请求可以自动拆分为更大的大小,单个 bio 中最多可达 <maxDiscard> 个 4096 字节的块,并且一次最多限制为 1500 个。增加此值可能会提供更好的整体性能,但代价是单个丢弃请求的延迟增加。默认值和最小值为 1;最大值为 UINT_MAX / 4096。
- deduplication
是否启用去重。默认值为 “on”;可接受的值为 “on” 和 “off”。
- compression
是否启用压缩。默认值为 “off”;可接受的值为 “on” 和 “off”。
设备修改¶
修改后的表可以加载到正在运行的、未挂起的 vdo 卷中。修改将在设备下次恢复时生效。可修改的参数为 <logical device size>、<physical device size>、<maxDiscard>、<compression> 和 <deduplication>。
如果逻辑设备大小或物理设备大小发生更改,在成功恢复后,vdo 将存储新值,并在未来启动时需要这些值。这两个参数都不能减小。逻辑设备大小不得超过 4 PB。物理设备大小必须至少增加 32832 个 4096 字节的块,或者不增加。物理设备大小不得超过底层存储设备的大小。此外,在格式化 vdo 设备时,会选择一个 slab 大小:物理设备大小永远不能超过提供 8192 个 slab 的大小,并且每次增加必须足够大,以便至少添加一个新的 slab。
示例
启动之前格式化的 vdo 卷,具有 1 GB 的逻辑空间和 1 GB 的物理空间,存储到 /dev/dm-1,该设备具有超过 1 GB 的空间。
dmsetup create vdo0 --table \
"0 2097152 vdo V4 /dev/dm-1 262144 4096 32768 16380"
将逻辑大小增加到 4 GB。
dmsetup reload vdo0 --table \
"0 8388608 vdo V4 /dev/dm-1 262144 4096 32768 16380"
dmsetup resume vdo0
将物理大小增加到 2 GB。
dmsetup reload vdo0 --table \
"0 8388608 vdo V4 /dev/dm-1 524288 4096 32768 16380"
dmsetup resume vdo0
将物理大小再增加 1 GB,并增加最大丢弃扇区数。
dmsetup reload vdo0 --table \
"0 10485760 vdo V4 /dev/dm-1 786432 4096 32768 16380 maxDiscard 8"
dmsetup resume vdo0
停止 vdo 卷。
dmsetup remove vdo0
再次启动 vdo 卷。请注意,逻辑和物理设备大小必须仍然匹配,但其他参数可以更改。
dmsetup create vdo1 --table \
"0 10485760 vdo V4 /dev/dm-1 786432 512 65550 5000 hash 1 logical 3 physical 2"
消息¶
所有 vdo 设备都接受以下形式的消息
dmsetup message <target-name> 0 <message-name> <message-parameters>
消息如下:
- stats
输出 vdo 统计信息的当前视图。主要由 vdostats 用户空间程序使用以解释输出缓冲区。
- config
输出有用的 vdo 配置信息。主要供希望重新创建类似 VDO 卷并想知道使用的创建配置的用户使用。
- dump
将许多内部结构转储到系统日志。这并非总是安全运行,因此仅应用于调试挂起的 vdo。可选参数指定要转储的结构:
viopool: I/O 请求的传入 bios 池。 pools: ‘viopool’ 的同义词 vdo: 大部分管理磁盘数据的结构。 queues: 有关每个 vdo 线程的基本信息。 threads: ‘queues’ 的同义词。 default: 等同于 ‘queues vdo’。 all: 以上所有。
- dump-on-shutdown
下次 vdo 关闭时执行默认转储。
状态¶
<device> <operating mode> <in recovery> <index state>
<compression state> <physical blocks used> <total physical blocks>
device:
The name of the vdo volume.
operating mode:
The current operating mode of the vdo volume; values may be
'normal', 'recovering' (the volume has detected an issue
with its metadata and is attempting to repair itself), and
'read-only' (an error has occurred that forces the vdo
volume to only support read operations and not writes).
in recovery:
Whether the vdo volume is currently in recovery mode;
values may be 'recovering' or '-' which indicates not
recovering.
index state:
The current state of the deduplication index in the vdo
volume; values may be 'closed', 'closing', 'error',
'offline', 'online', 'opening', and 'unknown'.
compression state:
The current state of compression in the vdo volume; values
may be 'offline' and 'online'.
used physical blocks:
The number of physical blocks in use by the vdo volume.
total physical blocks:
The total number of physical blocks the vdo volume may use;
the difference between this value and the
<used physical blocks> is the number of blocks the vdo
volume has left before being full.
内存需求¶
vdo 目标需要固定的 38 MB RAM,以及以下随目标扩展的量:
每 1 MB 配置的块映射缓存大小需要 1.15 MB 的 RAM。块映射缓存至少需要 150 MB。
每 1 TB 逻辑空间需要 1.6 MB 的 RAM。
该卷管理的每 1 TB 物理存储需要 268 MB 的 RAM。
重复数据删除索引需要额外的内存,该内存随重复数据删除窗口的大小而扩展。对于密集索引,索引需要每 1 TB 窗口 1 GB 的 RAM。对于稀疏索引,索引需要每 10 TB 窗口 1 GB 的 RAM。索引配置在格式化目标时设置,不能修改。
模块参数¶
vdo 驱动程序有一个数字参数 'log_level',用于控制驱动程序日志的详细程度。默认设置为 6(LOGLEVEL_INFO 和更严重的消息)。
运行时使用¶
使用 dm-vdo 时,务必注意它与其他存储目标的行为差异。
不保证覆盖现有块会成功。由于底层存储可能被多次引用,因此覆盖现有块通常需要 vdo 具有可用的空闲块。
当不再使用块时,向这些块发送丢弃请求可让 vdo 释放对这些块的引用。如果 vdo 是精简配置的,则丢弃未使用的块对于防止目标耗尽空间至关重要。但是,由于重复块的共享,无法保证对任何给定的逻辑块的丢弃请求会回收空间。
假设底层存储正确实现刷新请求,vdo 具有针对崩溃的弹性,但是,未刷新的写入可能在崩溃后保留也可能不保留。
每次写入 vdo 目标都需要大量的处理。但是,大部分工作是可并行化的。因此,vdo 目标在较高的 I/O 深度下可实现更好的吞吐量,并且可以并行支持多达 2048 个请求。
调优¶
vdo 设备有许多选项,并且在不完全了解工作负载的情况下,很难做出最佳选择。此外,大多数配置选项必须在启动 vdo 目标时设置,并且必须完全关闭才能更改;目标处于活动状态时,无法更改配置。理想情况下,在生产环境中部署 vdo 之前,应使用模拟工作负载执行调优。
要调整的最重要值是块映射缓存大小。为了服务对任何逻辑地址的请求,vdo 必须加载保存相关映射的块映射部分。这些映射被缓存。当工作集不适合缓存时,性能会受到影响。默认情况下,vdo 在 RAM 中分配 128 MB 的元数据缓存,以支持一次高效访问 100 GB 的逻辑空间。对于较大的工作集,应按比例放大。
还应调整逻辑和物理线程数。逻辑线程控制块映射的不相交部分,因此额外的逻辑线程可以增加并行性并提高吞吐量。物理线程控制数据块的不相交部分,因此额外的物理线程也可以提高吞吐量。但是,过多的线程会浪费资源并增加竞争。
Bio 提交线程控制将 I/O 发送到底层存储的并行性;线程越少意味着有更多机会重新排序 I/O 请求以获得性能优势,但也意味着每个 I/O 请求在提交之前必须等待更长时间。
Bio 确认线程用于完成 I/O 请求。这是在专用线程上完成的,因为执行 bio 的回调所需的工作量不能由 vdo 本身控制。通常一个线程就足够了,但是额外的线程可能是有益的,尤其是在 bios 具有 CPU 密集型回调时。
CPU 线程用于哈希和压缩;在启用压缩的工作负载中,更多线程可能会导致更高的吞吐量。
哈希线程用于按哈希对活动请求进行排序,并确定它们是否应重复数据删除;这些线程执行的最 CPU 密集型操作是比较 4096 字节的数据块。在大多数情况下,一个哈希线程就足够了。