配置和使用调度器的驱动过滤器和权重

OpenStack 块存储使您能够基于后端特定属性,通过使用调度器的驱动过滤器和 GoodnessWeigher 来选择卷后端。驱动过滤器和权重调度可以帮助确保调度器根据请求的卷属性以及各种后端特定属性选择最佳后端。

驱动过滤器和权重是什么以及何时使用它

驱动过滤器和权重使您能够更精细地控制 OpenStack 块存储调度器在处理卷请求时选择最佳后端的方式。一个使用驱动过滤器和权重可以发挥作用的示例场景是,如果使用了使用薄配置的后端。默认过滤器使用 free capacity 属性来确定最佳后端,但这并不总是完美的。如果后端能够提供更准确的后端特定值,则可以使用它作为权重的组成部分。驱动过滤器和权重在以下情况下也可能有用:如果存在一个后端,该后端对卷的硬性限制为 1000 个。最大卷大小为 500 GB。一旦总空间占用达到 75%,后端性能就会下降。驱动过滤器和权重可以提供一种检查这些限制的方法。

启用驱动过滤器和权重

要启用驱动过滤器,请在 cinder.conf 文件中将 scheduler_default_filters 选项设置为 DriverFilter。如果已经存在其他过滤器,则可以将 DriverFilter 添加到列表中以与其他过滤器一起使用。

要将 goodness 过滤器作为 weigher 启用,请在 cinder.conf 文件中将 scheduler_default_weighers 选项设置为 GoodnessWeigher,或者如果已经存在其他 weigher,则将其添加到列表中。

您可以选择在没有 GoodnessWeigher 的情况下使用 DriverFilter,反之亦然。但是,过滤器和 weigher 协同工作,在帮助调度器选择理想后端时可以产生最大的效益。

重要提示

GoodnessWeigher 可以与 CapacityWeigher 等一起使用,但必须谨慎使用,因为它可能会混淆 CapacityWeigher。

示例 cinder.conf 配置文件

scheduler_default_filters = DriverFilter
scheduler_default_weighers = GoodnessWeigher

注意

将这些自定义过滤器和 weigher 与 OpenStack 中可用的其他过滤器和 weigher 结合使用是有益的。例如,可以将 CapacityFilterCapacityWeigher 与这些结合使用。应谨慎地一起使用它们,因为根据定义的逻辑,一个可能会混淆另一个。

定义您自己的过滤器和 goodness 函数

您可以通过使用 OpenStack 块存储暴露的各种属性来定义自己的过滤器和 goodness 函数。暴露的属性包括有关正在发出的卷请求的信息、 volume_type 设置以及有关驱动程序的后端特定信息。所有这些都允许对确定卷请求的理想后端的方式进行大量控制。

filter_function 选项是一个字符串,定义了一个将确定后端是否应被视为调度器中潜在候选者的方程式。

goodness_function 选项是一个字符串,定义了一个将对潜在主机的质量进行评级(0 到 100,0 最低,100 最高)的方程式。

重要提示

如果您没有自行定义它们,则驱动过滤器和 weigher 将为每个后端使用过滤器和 goodness 函数的默认值。如果需要完全控制,则应为 cinder.conf 文件中的每个后端定义过滤器和 goodness 函数。

过滤器和 goodness 函数中支持的运算

下面是一个表格,其中列出了您创建的自定义过滤器和 goodness 函数中当前可用的所有运算

操作

类型

+, -, *, /, ^

标准数学

非、与、或、&、|、!

逻辑

>, >=, <, <=, ==, <>, !=

相等性

+, -

符号

x ? a : b

三元运算

abs(x)、max(x, y)、min(x, y)

数学辅助函数

警告

您在过滤器或 goodness 字符串中定义的语法错误将在卷请求时抛出。

创建自定义函数时可用的属性

可以在 filter_functiongoodness_function 字符串中使用各种属性。这些属性允许访问卷信息、qos 设置、额外规格等。

当前可用于以下属性及其子属性

后端的 Host 统计信息

为了访问这些属性,请使用以下格式: stats.<property>

host

主机的名称

volume_backend_name

卷后端名称

vendor_name

供应商名称

driver_version

驱动程序版本

storage_protocol

存储协议

QoS_support

布尔值,表示是否支持 QoS

total_capacity_gb

总容量(以 GB 为单位)

allocated_capacity_gb

已分配的容量(以 GB 为单位)

free_capacity_gb

可用容量(以 GB 为单位)

reserved_percentage

保留存储百分比

特定于后端的 Capabilities

这些属性由您创建过滤器和 goodness 函数的特定后端确定。某些后端可能在此处没有任何可用属性。一旦 Capabilities 根据后端变化太大,最好检查调度器日志中报告的属性。调度器会不断报告这些 Capabilities。为了访问这些属性,请使用以下格式: capabilities.<property>

请求的卷属性

为了访问卷属性,请使用以下格式: volume.<property>

status

请求的卷的状态

volume_type_id

卷类型 ID

display_name

卷的显示名称

volume_metadata

卷拥有的任何元数据

reservations

卷拥有的任何预留

user_id

卷的用户 ID

attach_status

卷的附加状态

display_description

卷的显示描述

id

卷的 ID

replication_status

卷的复制状态

snapshot_id

卷的快照 ID

encryption_key_id

卷的加密密钥 ID

source_volid

源卷 ID

volume_admin_metadata

此卷的任何管理员元数据

source_replicaid

源复制 ID

consistencygroup_id

一致性组 ID

size

卷的大小(以 GB 为单位)

metadata

常规元数据

此处最常用的属性很可能是 size 子属性。

请求的卷类型的额外规格

通过运行查看卷类型的可用属性

$ cinder extra-specs-list

请求的卷类型的当前 QoS 规格

通过运行查看卷类型的可用属性

$ openstack volume qos list

为了在自定义字符串中访问这些属性,请使用以下格式

<property>.<sub_property>

驱动过滤器和 weigher 用法示例

以下是单独使用过滤器和 weigher、一起使用以及使用驱动程序特定属性的示例。

自定义过滤器函数的示例 cinder.conf 文件

[default]
scheduler_default_filters = DriverFilter
enabled_backends = lvm-1, lvm-2

[lvm-1]
volume_driver = cinder.volume.drivers.lvm.LVMVolumeDriver
volume_backend_name = sample_LVM01
filter_function = "volume.size < 10"

[lvm-2]
volume_driver = cinder.volume.drivers.lvm.LVMVolumeDriver
volume_backend_name = sample_LVM02
filter_function = "volume.size >= 10"

上面的示例将根据请求的卷的大小将卷过滤到不同的后端。默认 OpenStack 块存储调度器权重计算完成。小于 10 GB 的卷发送到 lvm-1,大于或等于 10 GB 的卷发送到 lvm-2。

自定义 goodness 函数的示例 cinder.conf 文件

[default]
scheduler_default_weighers = GoodnessWeigher
enabled_backends = lvm-1, lvm-2

[lvm-1]
volume_driver = cinder.volume.drivers.lvm.LVMVolumeDriver
volume_backend_name = sample_LVM01
goodness_function = "(volume.size < 5) ? 100 : 50"

[lvm-2]
volume_driver = cinder.volume.drivers.lvm.LVMVolumeDriver
volume_backend_name = sample_LVM02
goodness_function = "(volume.size >= 5) ? 100 : 25"

上面的示例将根据请求的卷的大小确定后端的 goodness 评级。默认 OpenStack 块存储调度器过滤完成。该示例演示了三元 if 语句如何在过滤器或 goodness 函数中使用。如果请求的卷大小为 10 GB,则 lvm-1 的评级为 50,lvm-2 的评级为 100。在这种情况下,lvm-2 获胜。如果请求的卷大小为 3 GB,则 lvm-1 的评级为 100,lvm-2 的评级为 25。在这种情况下,lvm-1 将获胜。

自定义过滤器和 goodness 函数的示例 cinder.conf 文件

[default]
scheduler_default_filters = DriverFilter
scheduler_default_weighers = GoodnessWeigher
enabled_backends = lvm-1, lvm-2

[lvm-1]
volume_driver = cinder.volume.drivers.lvm.LVMVolumeDriver
volume_backend_name = sample_LVM01
filter_function = "stats.total_capacity_gb < 500"
goodness_function = "(volume.size < 25) ? 100 : 50"

[lvm-2]
volume_driver = cinder.volume.drivers.lvm.LVMVolumeDriver
volume_backend_name = sample_LVM02
filter_function = "stats.total_capacity_gb >= 500"
goodness_function = "(volume.size >= 25) ? 100 : 75"

上面的示例结合了前两个示例中的技术。最佳后端现在根据后端的总容量和请求的卷的大小来确定。

访问驱动程序特定属性的示例 cinder.conf 文件

[default]
scheduler_default_filters = DriverFilter
scheduler_default_weighers = GoodnessWeigher
enabled_backends = lvm-1,lvm-2,lvm-3

[lvm-1]
volume_group = stack-volumes-lvmdriver-1
volume_driver = cinder.volume.drivers.lvm.LVMVolumeDriver
volume_backend_name = lvmdriver-1
filter_function = "volume.size < 5"
goodness_function = "(capabilities.total_volumes < 3) ? 100 : 50"

[lvm-2]
volume_group = stack-volumes-lvmdriver-2
volume_driver = cinder.volume.drivers.lvm.LVMVolumeDriver
volume_backend_name = lvmdriver-2
filter_function = "volume.size < 5"
goodness_function = "(capabilities.total_volumes < 8) ? 100 : 50"

[lvm-3]
volume_group = stack-volumes-lvmdriver-3
volume_driver = cinder.volume.drivers.LVMVolumeDriver
volume_backend_name = lvmdriver-3
goodness_function = "55"

上面的示例说明了如何在过滤器和 goodness 函数中使用后端特定属性。在此示例中,LVM 驱动程序的 total_volumes capability 用于确定在卷请求期间使用哪个主机。在上面的示例中,lvm-1 和 lvm-2 将处理所有小于 5 GB 的卷的请求。当 lvm-1 包含 3 个或更少的卷时,lvm-1 和 lvm-2 具有相同的优先级。之后,当 lvm-2 包含 8 个或更少的卷时,lvm-2 具有优先级。lvm-3 将收集所有大于或等于 5 GB 的卷以及 lvm-1 和 lvm-2 失去优先级后的所有卷。