使用集中式数据库进行缓存

https://blueprints.launchpad.net/glance/+spec/centralized-cache-db

问题描述

我们使用两个不同的数据库来管理 Glance。一个是 oslo.db 管理的集中式数据库(默认是 MySQL),用于存储与常规操作相关的信息;另一个是 SQLite 数据库,用于存储与缓存相关操作的信息。即使我们仅在启用缓存中间件时才创建 SQLite 数据库,我们仍然需要与集中式数据库一起维护它。此外,Glance 缓存是每个控制器节点(Glance API 服务)本地的,因此在运行多个 Glance 服务的情况下,我们将有多个 SQLite 数据库运行。

提议的变更

我们建议从本次发布开始,使用集中式数据库(默认 MySQL)进行与缓存相关操作,并停止使用 SQLite 数据库。在这种情况下,我们可以避免为每个 Glance 服务创建 SQLite 数据库,并将所有内容置于集中式数据库下。

目前,用户可以使用 sqlite(默认)和 xattr 来选择如何使用 image_cache_driver 配置选项来控制缓存。我们建议引入新的驱动程序 centralized_db 和所需的配置选项,使其成为默认选项,并在本周期内将 sqlite 驱动程序和相关的配置选项标记为已弃用,并在 ‘D’ 开发周期中将其删除。

为了使用集中式数据库进行缓存,我们建议使用与 SQLite 数据库几乎相同的模式(列),并添加对本地节点(Glance 服务)的额外引用。如果启用了缓存,新的部署将直接开始使用这个新的集中式数据库。

在升级/更新的情况下,我们需要处理将现有的记录从 SQLite 数据库迁移到集中式数据库。由于我们可能运行多个 Glance 服务,因此使用 alembic 迁移来处理这将非常困难。为了避免这种情况,我们可以使用迁移在服务启动期间一次性执行此操作。如果 SQLite 数据库在服务启动时存在,并且 image_cache_driver 未设置为 centralized_db,那么我们将从其中读取记录,并将其插入到集中式数据库中新创建的 cached_images 表中。迁移完所有记录后,我们将清除 SQLite 数据库表,并保持 SQLite 数据库文件不变(如果需要,可以由管理员/操作员稍后删除)。重要的是,一旦部署者选择使用 centralized_db,并将他们的记录从 sqlite 迁移到集中式数据库,那么即使部署者想要恢复到 sqlite 驱动程序,我们也不会将它们迁移回去。

由于部署可以运行多个 Glance 服务,为了为多个 Glance 服务单独记录缓存详细信息,我们可以使用现有的配置选项 worker_self_reference_url,它将区分每个运行的 Glance 服务的缓存记录。worker_self_reference_url 之前用于识别新导入工作流中的节点,现在也可以用于此目的。由于 worker_self_reference_url 也需要用于 glance-direct 导入方法,如果发现部署者未为任何 Glance 设置设置它,那么在服务启动时,我们将记录适当的错误消息并阻止服务启动。此外,在多个节点的情况下,worker_self_reference_url 需要设置为每个节点的唯一值,并且如果,不小心,两个或多个节点具有相同的值,那么我们将不会将该节点的缓存数据迁移到集中式数据库,并记录适当的警告消息。

一旦我们将现有的缓存记录迁移到集中式数据库,我们需要确保现有的与缓存相关的命令行工具(如 cache-cleaner、cache-pruner)能够正常工作。由于这些工具使用专用的配置文件(glance-cache.conf),我们需要提供配置选项,以便这些工具可以连接到集中式数据库。

备选方案

数据模型影响

在 mysql 中创建两个新表,一个用于记录缓存相关操作,另一个用于记录 Glance API 引用,如下所示。

cached_images 的模式

CREATE TABLE cached_images (
  id bigint auto increment PRIMARY KEY,
  image_id varchar(36),
  last_accessed DateTime,
  last_modified DateTime,
  size bigint,
  hits int,
  checksum varchar(32),
  node_reference_id int,
  UNIQUE KEY `uq_cache_unique_id` (`image_id`,`node_reference_id`)
  FOREIGN KEY (node_reference_id) REFERENCES cache_node_reference(node_reference_id)

)

cache_node_reference 的模式

CREATE TABLE cache_node_reference (
  node_reference_id int PRIMARY KEY auto increment,
  node_reference_url varchar(255)
  UNIQUE KEY `uq_node_reference_url` (`node_reference_url`)
)

REST API 影响

安全影响

通知影响

其他最终用户影响

性能影响

其他部署者影响

开发人员影响

实现

负责人

主要负责人

abhishekk

其他贡献者

工作项

  • 弃用现有的 sqlite 驱动程序和相关的配置选项

  • 为两个新表创建 alembic 脚本

  • 为新表添加 sqlalchemy 中的模型/查询

  • 引入新的 centralized_db 驱动程序和相关的配置选项

  • 更改缓存代码以使用新的 mysql 数据库

  • 在服务启动时添加逻辑以将数据从 sqlite 迁移到 mysql

  • 修改相关的命令行工具,如 cache-cleaner、cache-pruner,以使用集中式驱动程序

  • Tempest 测试以确保多个 Glance 节点使用集中式数据库。

  • Grenade 测试以验证升级场景。

依赖项

测试

  • 单元测试

  • 功能测试

  • Tempest 测试

  • grenade 测试以验证升级场景

文档影响

需要记录在导入工作流和缓存相关操作中使用 worker_self_reference_url 的方法。

参考资料