我在 HDD 前面有一个 SSD 回写缓存,通过 lvmcache 设置(所以是 dm-cache)。当缓存 LV 未满时( < 100.00%Data%
中的列lvs
),写入会转到缓存设备(通过 监控dstat
)。但是,当缓存 LV 已满时 (Data%
= 100.00%),写入直接进入 HDD,本质上成为直写缓存。即使经过一段时间,块也不会从 SSD 缓存中被逐出,并且性能下降。当我尝试从缓存的 LV 中读取最近读取的数据时,读取来自 SSD,因此我假设整个 SSD 现在已成为读取缓存。这是 dm-cache 的写缓存的预期行为,即使在写回模式下?没有预留空间写吗?这似乎是一个非常糟糕的设计,因为在缓存成为直写缓存之前,用户只能写入一个缓存 LV 的数据。
我的理解是 dm-cache 使用mq eviction algorithm,但这仅适用于读取缓存,因此与我观察到的写入缓存问题无关。
有没有办法为写缓存保留空间,或者同时使用 dm-writecache (我理解它不会做任何读缓存)和 dm-cache ?
dm-cache
是一个“缓慢移动”的缓存:提升一个块需要许多读/写未命中,特别是当提升一个新块意味着降级一个已经缓存的块时。的基于块的固定性质
dm-cache
,加上没有保留的只写区域,意味着需要对相同的非缓存块进行多次写入才能触发块提升/替换。然而,这也意味着内核页面缓存没有“吸收”这些多次丢失的写入,而是将它们合并到对底层块设备的一次写入中。换句话说,您可能会看到内核页面缓存(它吸收和合并写入)和不愿意
dm-cache
提升第一个丢失的块的综合效果。如果您想保留一些设备/空间仅用于写入缓存,您可以
dm-writecache
使用(和通常的lvmcache
)附加信息:
dm-cache
确实阻止升级/降级跟踪访问命中/未命中。首先,您有一个空缓存,所有 I/O 都定向到原始(慢速)设备。因此,当您发出 4K 读取时,它将访问底层慢速设备,并dm-cache
跟踪未命中。在对同一缓存块(默认 32K)进行一些其他未命中后,整个缓存块将被复制到快速设备。如果您现在写入缓存块,您的写入将被缓存。但是,如果您的写入是针对未缓存的块,它会直接进入原始(慢速)设备。在其他一些未缓存的写入之后,dm-cache
最终将分配整个缓存块(记住,默认为 32K)将原始数据复制到缓存设备。此时,可以从缓存中提供新的读/写。降级很简单:当必须提升一个新块时,最旧的块被丢弃/刷新。换句话说,要缓存写入,必须分配相应的缓存段,并且必须将备份数据复制到缓存设备上(写时分配)。为了限制源设备和缓存设备之间的带宽使用,这个副本仅在多次未命中后完成(即:单个未命中不会提升块)。请注意,多次读取相同的未缓存块将不起作用,因为内核页面缓存将简单地自行提供缓存块。
dm-writecache
工作方式不同,更类似于传统的 RAID 控制器写回缓存。它缓存所有写入,忽略读取。它几乎可以被认为是“只写 L2 页面缓存”,脏页被“交换”,等待慢速设备赶上。要使用它,您需要在dm-cache
(此时必须作为writethrough
缓存运行)和之间对快速设备进行分区dm-writecache
,或者为它们分配不同的设备。我从未尝试过通过 LVM 这样做,我怀疑该工具会阻止您嵌套/堆叠两个不同的缓存模块。但是,您可以通过直接dmsetup
命令进行尝试。