Swift Driver 的缓冲读取器

请包含您的 launchpad 蓝图的 URL:https://blueprints.launchpad.net/glance/+spec/buffered-reader-for-swift-driver

此变更提案为镜像上传过程引入了围绕镜像数据的缓冲包装器。此包装器通过提供从上传过程中发生的错误中恢复的能力来帮助提高镜像上传的可靠性。这种恢复能力来自于在上传到 Swift 之前缓冲镜像片段。当发生错误时,Swift 客户端会使用缓冲镜像片段上的“seek”和“tell”操作确定上次成功的位置,从而从该位置恢复上传过程。

问题描述

问题是什么? Nova 通过 gzip 流将镜像数据上传到 Glance。Glance 的 Swift 后端驱动程序从 gzip 流中读取数据片段,并使用 Swift 客户端将其上传到 Swift 集群。在此过程中,如果在将数据上传到 Swift 集群时发生错误,Swift 客户端将中止上传,因为它无法从错误中恢复。这最终会触发 Swift 驱动程序删除迄今为止上传的所有数据。

为什么这个问题很重要? 无法从错误中恢复 - 对快照的可靠性产生直接和负面影响。 - 导致上传到出错为止的网络带宽浪费

为什么 Swift 客户端无法从错误中恢复? 为什么不改进它? Swift 客户端实际上能够从套接字错误、401、408、速率限制错误、5XX 等错误中恢复。它处理了相当多的错误,并确实尝试以适当的方式从每个错误中恢复。当发生错误时,Swift 客户端会尝试使用 reset 函数 [0] 通过将输入源重新定位到上次成功的位置来恢复上传。reset 函数本身利用输入源上的“seek”和“tell”操作 [1] 来确定应从哪个位置恢复上传。当 swiftclient 使用磁盘上的文件或任何其他支持“seek”和“tell”操作的输入源时,这种方法效果很好。但是,在 Nova 到 Glance 的镜像上传的情况下,输入源是一个数据流,不幸的是,它不支持“seek”和“tell”操作。这导致 Swift 客户端中止上传。因此,在镜像数据源上提供“seek”和“tell”操作将自动通过 Swift 客户端的重试机制解决此问题。

提议的变更

引入一个围绕镜像数据的包装器,其形式为名为 BufferedReader 的读取器类,该类支持“seek”和“tell”操作。

当前,Glance 将镜像数据作为动态大对象 (DLO) 上传到 Swift,该对象将数据保存在几个较小的对象中,称为片段。Glance 的 Swift 驱动程序使用 Swift 客户端将每个片段单独上传到后端存储。但是,在将镜像片段传递给 Swift 客户端之前,Swift 驱动程序会用 ChunkReader 类 [3] 包装 [2] 这些片段,这使得 Swift 客户端能够以较小的块(通常为 64KB)上传镜像片段。

在提议的方法中,我们不是用 ChunkReader 包装每个片段,而是用 BufferedReader 包装它,BufferedReader 通过在上传到 Swift 时将镜像数据 tee 到临时文件来缓冲镜像片段。由于镜像片段在磁盘上可用,BufferedReader 将“read”、“seek”和“tell”操作代理到基础临时文件。如果镜像片段成功上传或在耗尽重试后中止上传,则会删除临时文件。如果片段上传失败,Swift 客户端的重试机制将通过使用现在可用的“seek”和“tell”操作重新定位输入来恢复上传。

我们建议将 BufferedReader 引入为可配置选项,同时保持默认行为不变。使用此配置选项,还可以调节用于缓冲的磁盘空间量。如果分配的缓冲空间已满,BufferedReader 将恢复到默认行为,即数据在不进行缓冲的情况下上传到 Swift。

备选方案

  • 另一种选择是使用内存缓冲而不是磁盘缓冲。使用内存缓冲,内存占用将大幅增加,这可能会降低 API 性能。此外,磁盘是一种比内存更便宜的资源,但并不一定更快。

  • 在 [4] 中提出了一种解决方案来专门解决 401 错误。该提案基本上通过确保令牌不会接近到期来工作。如果即将到期,它会更新令牌。虽然这对于 401 来说效果很好,但对于其他错误可能无法采用类似的方法。

数据模型影响

REST API 影响

安全影响

通知影响

不会添加、修改或删除通知。

其他最终用户影响

性能影响

使用磁盘缓冲,涉及将数据写入和从磁盘读取的额外成本。这可能会给镜像上传带来潜在的性能损失。但是,镜像上传过程中花费的大部分时间是在网络上传输数据。相比之下,磁盘的读取和写入操作相对快得多。通过进行彻底的测试,可以进一步详细研究这种方法的性能影响。

其他部署者影响

由于镜像数据被缓冲到磁盘,API 上的磁盘利用率将比以前更高。磁盘利用率将等效于:(镜像片段大小 * 同时快照的数量)

部署者在使用此功能时需要考虑额外的磁盘利用率。应特别注意,这种磁盘利用率不会以任何方式影响 Glance 缓存可用的磁盘空间。

开发人员影响

实现

负责人

主要负责人

hemanth-makkapati

其他贡献者

belliott jesse-j-cook

评审人员

核心评审人

nikhil-komawar stuart-mclaren

其他审核员

brian-rosmaita mfedosin

工作项

  • 实现 BufferedReader 类

  • 使读取器类可配置,并保持默认行为不变

  • 在 devstack 上进行测试

依赖项

没有依赖关系,但 [4] 是一项相关工作。

测试

文档影响

新的配置选项需要文档说明。

参考资料

[0] https://github.com/openstack/python-swiftclient/blob/stable/kilo/swiftclient/client.py#L1296-L1297 [1] https://github.com/openstack/python-swiftclient/blob/stable/kilo/swiftclient/client.py#L1376-L1381 [2] https://github.com/openstack/glance_store/blob/master/glance_store/_drivers/swift/store.py#L546-L550 [3] https://github.com/openstack/glance_store/blob/master/glance_store/_drivers/swift/store.py#L928-L942 [4] https://review.openstack.org/#/c/199049/