第 5 章 优化 LVM-VDO 性能
VDO 内核驱动程序通过使用多个线程来加快任务。它不是一个线程为一个 I/O 请求做任何事情,而是将工作分成较小的部分,来分配给不同的线程。这些线程在处理请求时相互通信。这样,一个线程可以处理共享数据,而无需不断地锁定和解锁。
当一个线程完成一个任务时,VDO 已为它准备了另一个任务。这会保持线程忙碌,并减少切换任务所花费的时间。VDO 还对较慢的任务使用单独的线程,如将 I/O 操作添加到队列中,或将消息处理到去重索引中。
5.1. VDO 线程类型
VDO 使用各种线程类型来处理特定的操作:
- 逻辑区域线程(
kvdo:logQ
) - 维护提供给 VDO 设备的用户的的逻辑块号(LBN)和底层存储系统中物理块号(PBN)之间的映射。它们还阻止并发写入同一块。逻辑线程在读和写操作过程中处于活动状态。处理通常是平均分布的,但特定的访问模式偶尔可能将工作集中在一个线程中。例如,频繁访问特定块映射页中的 LBN 可能会导致一个逻辑线程处理所有这些操作。
- 物理区域线程(
kvdo:physQ
) - 在写操作过程中处理数据块分配和引用计数。
- I/O 提交线程(
kvdo:bioQ
) -
处理从 VDO 到存储系统的块 I/O (
bio
)操作的转换。它们处理来自其他 VDO 线程的 I/O 请求,并将它们传给底层设备驱动程序。这些线程与设备相关的数据结构进行交互,为设备驱动程序内核线程创建请求,并在 I/O 请求因为设备请求队列满了而被阻止时防止延迟。 - CPU 处理线程 (
kvdo:cpuQ
) - 处理不阻止或需要独占访问其他线程类型管理的数据结构的 CPU 密集型任务。这些任务包括计算哈希值和压缩数据块。
- I/O 确认线程(
kvdo:ackQ
) - 向更高级别的组件发出 I/O 请求完成的信号,如内核页缓存或应用程序线程执行直接 I/O。其 CPU 使用率和对内存争用的影响受到内核级别的代码的影响。
- 哈希区域线程(
kvdo:hashQ)
- 将 I/O 请求与匹配的哈希进行协调,以处理潜在的去重任务。虽然它们创建并管理去重请求,但它们不会执行大量的计算。一个哈希区域线程通常就足够了。
- 去重线程(
kvdo:dedupeQ
) - 处理 I/O 请求并与去重索引进行通信。这个工作是对单独的线程执行,以防止阻塞。如果索引没有快速响应,它也有一个跳过去重的超时机制。每个 VDO 设备只有一个去重线程。
- 日志线程(
kvdo:journalQ
) - 更新恢复日志,并调度日志块以进行写入。此任务不能在多个线程中分配。每个 VDO 设备只有一个日志线程。
- Packer 线程(
kvdo:packerQ
) - 启用压缩时,在写操作过程中工作。它从 CPU 线程收集压缩数据块,以减少浪费的空间。每个 VDO 设备只有一个 packer 线程。