感知池的调度器支持¶
https://blueprints.launchpad.net/cinder/+spec/pool-aware-cinder-scheduler
目前 Cinder 将每个卷后端视为一个整体,即使该后端由具有完全不同能力和容量的几个较小的池组成。 这种差距可能会导致奇怪的问题——后端似乎有足够的容量来创建卷的副本,但后端却无法这样做。 扩展 Cinder 以支持卷后端内的存储池,不仅可以解决类似的问题,还可以使 Cinder 调度决策更加智能,因为它现在了解后端的全部能力。
问题描述¶
自一开始,Cinder 就被设计为将每个卷后端视为一个整体。 配置决策基于后端报告的统计信息。 假设任何后端都是一个具有一组能力和单个容量的单独离散单元。 在现实中,对于许多存储提供商来说,这种假设是不正确的,因为它们的存储可以进一步划分为池,以提供完全不同的能力和容量集合。 因此,存储后端是存储池的组合,而不是一个大的单一同质实体。 通常,卷/快照无法放置在这些后端上的池之间。 因此,在使用它们与当前的 Cinder 时,存在明显的问题
如果一个卷/快照大于目标后端中的任何子池,则调度后端将失败;
子池可能没有足够的空间来服务连续请求(例如,卷克隆、快照),而整个后端似乎有足够的容量;
这些问题非常令人困惑,并导致用户体验不一致。 因此,扩展 Cinder 以使其意识到后端内的存储池,并将其作为资源放置的最精细粒度非常重要。
用例¶
提议的变更¶
我们希望引入感知池的调度器来解决支持来自单个存储控制器的多个池的需求。
术语¶
池 - 一个逻辑概念,用于描述可用于服务核心 Cinder 请求(例如,卷/快照)的一组存储资源。 这种概念几乎与 Cinder 卷后端相同,因为它具有相似的属性(容量、能力)。 主要区别在于池不能独立存在,它必须驻留在卷后端中。 一个卷后端可以有多个池,但池没有子池(即使它们有,子池也不会暴露给 Cinder,目前)。 池在后端命名空间中具有唯一的名称,这意味着卷后端不能有两个使用相同名称的池。
设计¶
此更改的工作流程很简单:1) 卷后端报告池的数量以及这些池的外观和能力给调度器; 2) 当请求进来时,调度器选择最适合服务请求的池,并将请求传递给后端,目标池位于该后端; 3) 卷驱动程序接收消息,并让目标池根据调度器的指示来服务请求。
为了支持将资源(卷/快照)放置到池上,将对 Cinder 的特定组件进行以下更改:1. 卷后端报告池级别的容量/能力; 2. 调度器根据池容量/能力进行过滤/加权,并将卷/快照放置到某个后端的池中; 3. 记录资源位于后端上的哪个池,并在调度器和卷后端之间传递。
备选方案¶
Navneet Singh 提出了一种替代方案,即对卷管理器/驱动程序代码进行更改,而不是更改调度器。 在他的方法中,后端中的每个子池都将作为服务实体公开(例如,python 进程中的一个 greenthread),它监听自己的 RPC 通道,将自己的统计信息报告给调度器。
与此替代方案相关的 bp:https://blueprints.launchpad.net/cinder/+spec/multiple-service-pools
数据模型影响¶
不涉及数据库模式更改,但是,Volumes 表中的 host 字段现在将包含池信息,但不需要数据库迁移。
- Volumes 表的原始 host 字段
- 使用此更改
HostX@Backend:pool0
REST API 影响¶
N/A
安全影响¶
N/A
通知影响¶
卷的 host 属性现在包含池信息,通知的消费者现在可以扩展以提取池信息(如果需要)。
其他最终用户影响¶
对最终用户不可见的影响。
性能影响¶
每个卷统计报告的 RPC 消息的大小将比以前大(与后端拥有的池的数量成线性关系)。 它不应该真正影响 RPC 设施的性能,即使影响了,纯文本压缩也应该可以轻松缓解这个问题。
其他部署者影响¶
部署者不需要部署新版本的 Cinder,因为这主要是透明的更改,甚至对部署者也是如此。 唯一可见的更改是将附加的池信息编码到卷记录的 host 属性中。
最好先更新/部署调度器优先于卷服务,但此顺序不是强制性的。
开发人员影响¶
对于希望将内部池暴露给 Cinder 以获得更多灵活性的那些卷后端,开发人员应更新其驱动程序,以在它报告给调度器的卷统计信息中包含所有子池的容量和能力。 以下是新的统计消息示例
{
'volume_backend_name': 'Local iSCSI', #\
'vendor_name': 'OpenStack', # backend level
'driver_version': '1.0', # mandatory/fixed
'storage_protocol': 'iSCSI', #- stats&capabilities
'active_volumes': 10, #\
'IOPS_provisioned': 30000, # optional custom
'fancy_capability_1': 'eat', # stats & capabilities
'fancy_capability_2': 'drink', #/
'pools': [
{'pool_name': '1st pool', #\
'total_capacity_gb': 500, # mandatory stats for
'free_capacity_gb': 230, # pools
'allocated_capacity_gb': 270, # |
'QoS_support': 'False', # |
'reserved_percentage': 0, #/
'dying_disks': 100, #\
'super_hero_1': 'spider-man', # optional custom
'super_hero_2': 'flash', # stats & capabilities
'super_hero_3': 'neoncat' #/
},
{'pool_name': '2nd pool',
'total_capacity_gb': 1024,
'free_capacity_gb': 1024,
'allocated_capacity_gb': 0,
'QoS_support': 'False',
'reserved_percentage': 0,
'dying_disks': 200,
'super_hero_1': 'superman',
'super_hero_2': ' ',
'super_hero_2': 'Hulk',
}
]
}
实现¶
负责人¶
- 主要负责人
zhiteng-huang (winston-d)
工作项¶
此提案需要两部分更改:对 Cinder 本身(调度器、卷管理器)的更改以及对希望将池暴露给调度器的那些后端 Cinder 驱动程序的更改。
但即使没有 Cinder 驱动程序更改,它也能正常工作,不会出现问题,因为更改的第一部分已经考虑了兼容性。
依赖项¶
N/A
测试¶
一个完整的测试环境需要以下场景
1) Cinder 使用的后端不支持池(仅为整个后端公开单个池); 2) Cinder 使用的后端支持池(使用更新的驱动程序); 3) Cinder 使用混合后端;
在升级之前,在后端上创建一些卷/快照,这是为了兼容性测试。
对于每个场景,测试应分 3 个步骤进行
1) 更新 cinder-scheduler(或 cinder-volume),测试创建卷克隆、现有卷的快照或删除现有卷; 2) 测试创建新卷; 3) 更新 Cinder 的其余部分(如果 cinder-scheduler 在步骤 1 中更新,则立即更新 cinder-volume,反之亦然),测试创建卷、创建现有卷的克隆、快照或删除现有卷。
文档影响¶
Cinder 本身的变化不会产生文档影响。 但是驱动程序更改可能会引入新的配置选项,从而导致 DocImpact。