支持卷本地缓存¶
https://blueprints.launchpad.net/nova/+spec/support-volume-local-cache
此蓝图建议在 nova 中添加对卷本地缓存的支持。缓存软件,例如 open-cas [4],可以使用快速的 NVME SSD 或持久内存来缓存慢速远程卷。
问题描述¶
目前有不同类型的快速 NVME SSD,例如 Intel Optane SSD,延迟低至 10 微秒。 此外,旨在达到 SSD 尺寸但 DRAM 速度的持久内存现在越来越流行。 持久内存的典型延迟低至几百纳秒。 而虚拟机远程卷的典型延迟可能在毫秒级别(iscsi / rbd)。 因此,这些快速的 SSD 或持久内存可以本地安装在计算节点上,并用作远程卷的缓存。
为了实现缓存,有一些缓存软件,例如 open-cas。open-cas 非常易于使用,您只需要将一个块设备指定为缓存设备,然后就可以使用该设备来缓存其他块设备。这对于上层和下层是透明的。对于上层,虚拟机不知道它正在使用模拟的块设备。对于下层,后端卷不知道它被缓存了,并且后端卷中的数据不会因为缓存而产生额外的更改。这意味着即使缓存由于某种原因丢失,后端卷也可以挂载到其他地方并立即可用。此规范尝试使用此类缓存软件添加卷本地缓存。
与所有本地缓存解决方案一样,多重挂载无法工作。这是因为 node1 上的缓存不知道 node2 对后端卷所做的更改。
此功能需要“Write-Through”(直写)缓存模式,这确保了缓存始终与后端卷完全同步。鉴于此,它对于实时迁移是透明的。“Write-Through”也是 open-cas 的默认缓存模式。
此功能只能缓存首先作为块设备挂载在主机操作系统上的后端卷。因此,由 QEMU 挂载的卷(例如使用 LibvirtNetVolumeDriver 的卷),例如 rbd 和 sheepdog,无法被缓存。详细信息可以在 [5] 中的 libvirt_volume_drivers 列表中找到。
在某些高性能环境中,可能会选择 RDMA。RDMA 有效地缩短了本地卷和远程卷之间的延迟差距。在实验环境中,没有网络交换机,没有对真实卷的读/写 IO,点对点 RDMA 网络链路延迟在最佳情况下甚至可以达到 3us。这是纯网络链路延迟,这也并不意味着它比本地 PCIe 更快,因为主机和目标机器上的 RDMA 网卡本身也是 PCIe 设备。对于 RDMA 场景,建议选择持久内存作为缓存设备,否则可能无法获得性能提升。
用例¶
用户希望使用快速的 NVME SSD 来缓存远程慢速卷。这对于希望为特定卷提高磁盘 IO 性能的云环境来说非常有用。
提议的变更¶
由相同的缓存实例缓存的所有卷共享相同的缓存模式。操作员可以使用缓存软件管理工具动态更改缓存模式。os-brick 仅接受来自 Nova 的缓存名称和缓存 ID。缓存名称标识要使用的缓存软件,当前仅支持“opencas”。允许在一个计算节点中存在多个缓存实例。缓存 ID 标识可以使用的缓存实例。缓存模式对 os-brick 是透明的。
计算能力映射到特性(例如 COMPUTE_SUPPORT_VOLUME_CACHE),并且如果 nove conf 中配置了缓存实例 ID,libvirt 驱动程序可以将此能力设置为 true。如果希望对卷进行缓存,首先该卷应属于具有“cacheable”(可缓存)属性的卷类型。然后选择包含此特性的风味,以便虚拟机将降落在具有缓存能力的宿主机上。如果不想对卷进行缓存,只需选择没有此特性的风味即可。
如果在设置缓存过程中发生故障,例如缓存设备损坏,则重新安排请求。
最终架构将类似于
Compute Node
+---------------------------------------------------------+
| |
| +-----+ +-----+ +-----+ |
| | VM1 | | VM2 | | VMn | |
| +--+--+ +--+--+ +-----+ |
| | | |
+---------------------------------------------------------+
| | | |
| +---------+ +-----+----------+-------------+ |
| | Nova | | QEMU Virtio | |
| +-+-------+ +-----+----------+----------+--+ |
| | | | | |
| | attach/detach | | | |
| | +-----+----------+------+ | |
| +-+-------+ | /dev/cas1 /dev/cas2 | | |
| | osbrick +---------+ | | |
| +---------+ casadm | open cas | | |
| +-+---+----------+------+ | |
| | | | | |
| | | | | | Storage
| +--------+ | | +-----+----+ | rbd +---------+
| | | | | /dev/sdd +----------+ Vol1 |
| | | | +----------+ | +---------+
| +-----+-----+ | | | | Vol2 |
| | Fast SSD | | +-----+----+ iscsi/fc/... +---------+
| +-----------+ | | /dev/sdc +-------------+-------+ Vol3 |
| | +----------+ | +---------+
| | | | Vol4 |
| +-----+----+ iscsi/fc/... | +---------+
| | /dev/sdb +--------------------------------+ Vol5 |
| +----------+ | +---------+
| | | ..... |
+---------------------------------------------------------+ +---------+
更改包括
在连接卷期间缓存卷
在函数 _connect_volume() 中
检查卷是否应该被缓存。如果允许缓存,Cinder 将为卷设置 cacheable 属性。如果设置了 cacheable 并且 CONF 中的 volume_local_cache_driver 不为空,则执行缓存。否则,忽略缓存。
在 attach_encryptor 之前 attach_cache,缓存位于 encryptor 之下。这样做是为了保证加密卷的安全。没有解密的数据将被写入缓存设备。
调用 os-brick 来缓存卷 [2]。os-brick 将调用缓存软件来设置缓存。然后用模拟卷的路径替换原始卷的路径
Nova 使用新模拟的卷路径继续 _connect_volume()
如果在设置缓存过程中发生任何故障,只需忽略该故障并继续 _connect_volume() 的其余代码。
在断开卷连接期间释放缓存
在函数 _disconnect_volume() 中
调用 os-brick 来释放卷的缓存。os-brick 将从模拟卷中检索原始卷的路径,然后将 connection_info 中的路径替换为原始卷路径
Nova 使用原始卷路径继续 _disconnect_volume()
在 nova-cpu.conf 中添加开关以启用/禁用本地缓存
建议的开关名称
volume_local_cache_driver:指定要使用的缓存软件。当前仅支持“opencas”。如果为空,则禁用本地缓存。
volume_local_cache_instance_ids:指定可以使用的缓存实例。通常,opencas 在单个服务器上只有一个缓存实例,但它具有绑定到不同缓存设备的多个缓存实例的能力。Nova 需要将实例 ID 传递给 os-brick 并让 os-brick 找到最佳实例,例如最大的可用空间、缓存的卷较少等。所有这些信息都可以通过缓存管理工具(例如 casadm)通过实例 ID 获取。
建议的节:[compute]。配置如下:[compute] volume_local_cache_driver = ‘opencas’ volume_local_cache_instance_ids = 1,15,222
实例 ID 用逗号分隔。
Nova 仅在卷具有“cacheable”属性并且请求的风味需要这种缓存时才调用 os-brick 来设置卷的缓存。让 cinder 确定并设置属性,就像它为卷加密所做的那样。如果卷包含“multiattach”属性, cinder 将不会设置“cacheable”属性。代码流程如下
Nova osbrick
+
+ |
| |
v |
attach_volume |
+ |
| |
+ |
attach_cache |
+ |
| |
+ |
+-------+ volume_with_cache_property? |
| + |
| No | Yes |
| + |
| +--+Host_with_cache_capability? |
| | + |
| | No | Yes |
| | | |
| | +-----------------------------> attach_volume
| | | +
| | | |
| | | +
| | | set_cache_via_casadm
| | | +
| | | |
| | | +
| | | return emulated_dev_path
| | | +
| | | |
| | +-------------------------------------+
| | | |
| | v |
| | replace_device_path |
| | + |
| | | |
v v v |
|
attach_encryptor and |
rest of attach_volume +
卷本地缓存位于加密器之上,性能会更好,但会暴露缓存设备中的解密数据。 因此,出于安全考虑,缓存应位于 Nova 实现中的加密器之下。
备选方案¶
将本地 SSD 分配给特定的 VM。 然后,VM 可以内部使用 bcache 针对临时磁盘来缓存其卷,如果他们想这样做的话。
缺点可能包括
只能加速一个 VM。 快速 SSD 的功能不能与其他 VM 共享。 与 RAM 不同,SSD 通常在 TB 级别,并且足以缓存一个节点上的所有 VM。
VM 的所有者应该显式设置缓存。但并非所有 VM 所有者都希望这样做,而且并非所有 VM 所有者都具备执行此操作的知识。但他们肯定希望卷的性能默认情况下更好。
创建一个专用的缓存集群。将所有缓存(NVME SSD)安装在缓存集群中,作为一个大的缓存池。然后将一定数量的缓存分配给特定的卷。分配的缓存可以通过 NVMEof 协议挂载到计算节点上。然后仍然使用缓存软件来执行相同的缓存。
但这将是本地 PCIe 和远程网络之间的竞争。以这种方式进行的主要缺点是:存储服务器的网络将成为瓶颈。
延迟)存储集群通常通过 iscsi/fc 协议或通过 librbd(如果使用 ceph)提供卷。延迟将达到毫秒级别。即使使用 NVME over TCP,延迟也可能达到数百微秒,具体取决于网络拓扑。相比之下,NVME SSD 的延迟约为 10us,以 Intel Optane SSD p4800x 为例。
可以在后端存储侧添加缓存,例如在 ceph 中。 存储服务器通常具有自己的缓存机制,例如使用内存作为缓存,或使用 NVME SSD 作为缓存。
与上述解决方案类似,延迟是一个缺点。
数据模型影响¶
无
REST API 影响¶
无
安全影响¶
缓存软件在分离卷时会从缓存设备中删除缓存的卷数据。但通常不会擦除缓存设备中的相关扇区。因此,理论上,在被覆盖之前,卷数据仍然在缓存设备中。使用卷本地缓存的加密卷不会产生这种安全影响。
通知影响¶
无
其他最终用户影响¶
无
性能影响¶
VM 卷的延迟将减少
其他部署者影响¶
应在 nova-cpu.conf 中设置 volume_local_cache_driver 和 volume_local_cache_instance_ids 才能启用此功能。volume_local_cache_driver 的默认值将是空字符串,这意味着禁用本地缓存。
开发人员影响¶
这仅适用于 libvirt,其他驱动程序(如 VMWare、hyperv)将不会更改。这是因为 open-cas 只能支持 Linux,并且 libvirt 是最常用的驱动程序。同时,此规范/实现将仅使用 libvirt 进行测试。
升级影响¶
无
实现¶
负责人¶
- 主要负责人
Liang Fang <liang.a.fang@intel.com>
功能联络人¶
- 功能联络人
gibi
工作项¶
将 COMPUTE_SUPPORT_VOLUME_CACHE 特性添加到 os-traits
添加一个将此特性映射到新的计算能力
如果在 libvirt 驱动程序中配置了缓存,则启用此能力
在连接卷期间缓存卷
在断开卷连接期间释放缓存
添加开关以启用/禁用此功能
添加单元测试
依赖项¶
测试¶
应该添加新的单元测试
应该更改一个 tempest 作业以启用此功能,并在一个 vanilla worker 镜像上使用 open-cas。
这可以使用 open-cas,并使用本地文件作为 NVME 设备。
检查是否为 VM 创建了模拟卷。
检查在删除 VM 时是否释放了模拟卷。
应该更改一个 tempest 作业以启用此功能,并在一个 vanilla worker 镜像上使用 open-cas。
文档影响¶
需要更改文档以描述此功能并包含新的选项 - volume_local_cache_driver、volume_local_cache_instance_ids
参考资料¶
历史¶
发布名称 |
描述 |
|---|---|
Ussuri |
引入 |
Victoria |
重新提出 |