Nova 服务并发

长期以来,Nova 服务几乎完全依赖于 Eventlet 库来处理多个 API 请求、RPC 请求以及需要并发的其他任务。由于 Eventlet 不预计支持下一个主要版本的 cPython,OpenStack TC 设定了一个 目标 来替换 Eventlet,因此 Nova 已经开始将其并发模型过渡到原生线程。在此过渡期间,Nova 维护基于 Eventlet 的并发模式,同时构建对原生线程模式的支持。

注意

原生线程模式是实验性的。在预生产环境中测试之前,请勿在生产环境中使用它。如果您这样做,请通过邮件列表 openstack-discuss@lists.openstack.org 告知我们结果。

选择服务的并发模式

Nova 仍然默认使用 Eventlet,但允许在服务启动时通过设置环境变量 OS_NOVA_DISABLE_EVENTLET_PATCHING=true 将服务切换到原生线程模式。

注意

从 nova 32.0.0 (2025.2 Flamingo) 开始,nova-scheduler、nova-metadata 和 nova-api 可以切换到原生线程模式。

原生线程模式的可调参数

由于原生线程比绿线程消耗更多的资源,Nova 提供了一组配置选项,以便根据负载和资源限制对部署进行微调。默认值选择支持基本的、小型部署,而不会消耗比传统 Eventlet 模式实质性更多的内存资源。增加以下线程池的大小意味着给定的服务将消耗更多的内存,但也会允许更多任务并发执行。

  • cell_worker_thread_pool_size:用于在部署中的所有 cell 中执行任务。

    例如,要生成 openstack server list CLI 命令的结果,nova-api 服务将使用每个 cell 中的一个原生线程从相关的 cell 数据库加载 nova 实例。

    如果部署有许多 cell,那么可能需要增加此池的大小。

    此选项仅与 nova-api、nova-metadata、nova-scheduler 和 nova-conductor 相关,因为这些服务是执行跨 cell 操作的服务。

  • executor_thread_pool_size:用于处理传入的 RPC 请求。具有更多传入请求的服务需要更大的池。例如,单个 conductor 为许多 compute 以及 scheduler 提供请求。compute 节点仅为 API 提供生命周期操作和其他 compute 迁移期间的请求。

    此选项仅与 nova-scheduler、nova-conductor 和 nova-compute 相关,因为这些服务充当 RPC 服务器。

  • default_thread_pool_size:用于服务中各种并发任务,这些任务未归类到上述池中。

    此选项与使用 nova.utils.spawn() 的每个 nova 服务相关。

查看池的使用情况

当将新工作提交到任何这些池中时,无论哪种并发模式,Nova 都会记录池的统计信息(已执行的工作、可用线程、排队的工作等)。这在需要微调池大小时很有用。参数 thread_pool_statistic_period 定义了从特定池记录此类日志的频率(以秒为单位)。值为 60 秒表示最多每 60 秒从池中记录一次统计信息。值为 0 表示每次将工作提交到池时都会记录日志。默认值为 -1,表示禁用统计信息记录。

防止线程挂起

池中的线程在执行任务后无法取消,因此确保外部依赖项不会无限期地阻止任务执行非常重要,因为这将导致池中可用于传入工作的线程减少,从而降低整体容量。

Nova 的 RPC 接口已经使用适当的超时处理来避免线程挂起。但是,将超时处理添加到 Nova 的数据库接口取决于数据库服务器和数据库客户端库。

对于 mysql-server,可以使用 max_execution_time 配置选项来限制服务器端数据库查询的执行时间。其他数据库服务器也存在类似选项。

对于 pymysql 数据库客户端,可以通过将 read_timeout 连接参数添加到连接字符串来实现客户端超时。

我们建议在 Nova 服务以原生线程模式运行时同时使用这两种方法。