聚合的调度器数据库隔离¶
https://blueprints.launchpad.net/nova/+spec/isolate-scheduler-db
我们希望将 nova-scheduler 分离到 gantt。为此,此蓝图是 scheduler-lib 分离后的第二阶段。这两个蓝图是独立的。
在此蓝图中,我们需要隔离调度器正在执行的所有数据库访问,并重构代码(管理器、过滤器、称重器),以便调度器仅在内部访问与调度器相关的表或资源。
注意:此规范仅针对与聚合相关的过滤器进行更改。
问题描述¶
在做出涉及聚合信息的决策时,调度器会直接或间接通过 nova.objects.AggregateList 访问 Nova DB 的 aggregates 表。为了使调度器的分离干净,Nova 调度器对将保留在 Nova DB 中的表(例如 aggregates 表)的任何访问都必须进行重构,以便调度器具有一个 API 方法,允许 nova-conductor 或其他服务更新调度器对聚合信息的视图。
以下是受该提案影响的所有过滤器的摘要
AggregateImagePropertiesIsolation,
AggregateInstanceExtraSpecsFilter,
AggregateMultiTenancyIsolation,
AvailabilityZoneFilter,
AggregateCoreFilter (调用 n.objects.aggregate.AggregateList.get_by_host)
AggregateRamFilter (调用 n.objects.aggregate.AggregateList.get_by_host)
AggregateTypeAffinityFilter (调用 n.objects.aggregate.AggregateList.get_by_host)
用例¶
N/A,这是一项重构工作。
项目优先级¶
此蓝图是 Kilo 优先级确定的“scheduler”重构工作的一部分。
提议的变更¶
策略将包括每次聚合发生更改(添加或删除主机或更改元数据)时更新调度器。
由于当前的调度器设计随着请求数量而扩展(对于每个请求,都会使用 HostManager 模块中的 get_all_host_states 方法生成一个新的 HostState 对象),因此我们很难要求调度器每次有新的计算加入聚合时更新数据库。然后,这将创建一个新的范例,即调度器随着添加到聚合中的计算数量而扩展,这可能会导致一些竞争条件。
相反,我们建议在调度器中创建一个所有聚合的内存视图,该视图将在调度器启动时通过调用 Nova Aggregates API 填充,并让过滤器访问这些对象,而不是自行调用 Nova aggregates DB 表间接访问。使用 nova.compute.api.AggregateAPI 进行的聚合更新也会调用调度器 RPC API,以要求调度器更新相关视图。
备选方案¶
显然,主要问题是复制聚合信息以及可能发生的竞争条件。恕我直言,在调度器有一天能够独立存在的前提下,在调度器内存中复制信息是值得付出的代价。
一个推论是,如果复制不好,那么调度器应该完全拥有 Aggregates 表。因此,nova.compute.api.AggregatesAPI 中的所有调用都将被视为“外部”调用,并且一旦调度器被分离出来,Aggregates 将不再驻留在 Nova 中。
另一种中期方法是设想调度器的第二个服务(例如 nova-scheduler-updater - 命名仍然很糟糕……),它将接受 RPC API 调用并与 nova-scheduler 服务单独写入调度器 DB,nova-scheduler 服务实际上将被视为“nova-api”类型的服务,因为我们可以认为调度器为填充相对 HostState 信息而预热的时间可能会有问题,并且我们更喜欢将所有这些对象持久化到调度器 DB 中。
最后,我们绝对反对每次过滤器需要信息时就从调度器调用 Aggregates API,因为它无法扩展。
数据模型影响¶
没有,我们只是创建一个不会持久化的内存对象。
REST API 影响¶
无
安全影响¶
无
通知影响¶
没有。操作的原子性(添加/修改聚合)保持不变,我们不想为同一操作添加 2 个通知。
其他最终用户影响¶
无
性能影响¶
应该通过访问内存对象而不是访问数据库来完成访问,因此我们绝对期望更好的访问时间和改进的可扩展性。
其他部署者影响¶
无
开发人员影响¶
理想情况下
过滤器不应再将调用放置到其他代码位,除了调度器。这将通过修改调度器组件以代理导体调用到 Singleton 来完成,Singleton 将拒绝任何非与调度器相关的对象。请参阅脚注 [1] 作为示例。如上所述,我们将仍然为 Kilo 版本提供回退模式,以便与 N-1 版本兼容。
实现¶
在这里,我们建议通过在 nova.scheduler.host_state.HostManager 的初始化期间调用 nova.objects.AggregateList.get_all() 来设置 nova.objects.Aggregate 对象的集合,作为 HostManager 的属性。
为了访问主机所属的聚合列表,我们计划在初始化阶段将对相应 Aggregate 对象的引用列表作为 nova.scheduler.host_state.HostState 的额外属性添加。
第二阶段将包括通过修改调度器 RPC API,添加一个新的 update_aggregate() 方法,nova.scheduler.client 也会公开该方法,来提供对该缓存系统的更新。
update_aggregate() 方法将仅接受一个参数,即 nova.objects.Aggregate 对象,并将正确更新 HostManager.aggregates 属性,以便 HostState.aggregates 引用将隐式更新。
每次更新聚合时,我们将通过在每个方法中添加对 nova.scheduler.client 的另一个调用来挂钩现有的 nova.compute.api.AggregateAPI 类。
完成所有这些操作后,过滤器只需查看 HostState.aggregates 即可访问与主机所属的聚合相关的所有聚合信息(包括元数据)。
负责人¶
- 主要负责人
sylvain-bauza
- 其他贡献者
无
工作项¶
在调度器启动时实例化 HostManager.aggregates 和 HostState.aggregates
将 update_aggregate() 方法添加到调度器 RPC API 并增加版本
创建 nova.scheduler.client 方法用于 update_aggregate()
修改 nova.api.AggregateAPI 方法以调用调度器客户端方法
修改过滤器,以便它们可以查看 HostState
修改调度器入口点以阻止导体访问 Aggregates(一旦 Lxxx 版本开发开放)
依赖项¶
无
测试¶
涵盖了现有的 tempest 测试和 CI。
文档影响¶
无
参考资料¶
https://etherpad.openstack.org/p/icehouse-external-scheduler
http://eavesdrop.openstack.org/meetings/gantt/2014/gantt.2014-03-18-15.00.html
[1] http://git.openstack.org/cgit/openstack/nova/commit/?id=e5cbbcfc6a5fa31565d21e6c0ea260faca3b253d