OpenStack Block Storage enables you to choose a volume back end based on back-end specific properties by using the DriverFilter and GoodnessWeigher for the scheduler. The driver filter and weigher scheduling can help ensure that the scheduler chooses the best back end based on requested volume properties as well as various back-end specific properties.
The driver filter and weigher gives you the ability to more finely control how the OpenStack Block Storage scheduler chooses the best back end to use when handling a volume request. One example scenario where using the driver filter and weigher can be if a back end that utilizes thin-provisioning is used. The default filters use the free capacity property to determine the best back end, but that is not always perfect. If a back end has the ability to provide a more accurate back-end specific value you can use that as part of the weighing. Another example of when the driver filter and weigher can prove useful is if a back end exists where there is a hard limit of 1000 volumes. The maximum volume size is 500 GB. Once 75% of the total space is occupied the performance of the back end degrades. The driver filter and weigher can provide a way for these limits to be checked for.
To enable the driver filter, set the scheduler_default_filters option in the cinder.conf file to DriverFilter or add it to the list if other filters are already present.
To enable the goodness filter as a weigher, set the scheduler_default_weighers option in the cinder.conf file to GoodnessWeigher or add it to the list if other weighers are already present.
You can choose to use the DriverFilter without the GoodnessWeigher or vice-versa. The filter and weigher working together, however, create the most benefits when helping the scheduler choose an ideal back end.
Important
The support for the DriverFilter and GoodnessWeigher is optional for back ends. If you are using a back end that does not support the filter and weigher functionality you may not get the full benefit.
Example cinder.conf configuration file:
scheduler_default_filters = DriverFilter
scheduler_default_weighers = GoodnessWeigher
Note
It is useful to use the other filters and weighers available in OpenStack in combination with these custom ones. For example, the CapacityFilter and CapacityWeigher can be combined with these.
You can define your own filter and goodness functions through the use of various properties that OpenStack Block Storage has exposed. Properties exposed include information about the volume request being made, volume\_type settings, and back-end specific information about drivers. All of these allow for a lot of control over how the ideal back end for a volume request will be decided.
The filter_function option is a string defining an equation that will determine whether a back end should be considered as a potential candidate in the scheduler.
The goodness_function option is a string defining an equation that will rate the quality of the potential host (0 to 100, 0 lowest, 100 highest).
Important
Default values for the filter and goodness functions will be used for each back end if you do not define them yourself. If complete control is desired then a filter and goodness function should be defined for each of the back ends in the cinder.conf file.
Below is a table of all the operations currently usable in custom filter and goodness functions created by you:
Operations | Type |
---|---|
+, -, *, /, ^ | standard math |
not, and, or, &, |, ! | logic |
>, >=, <, <=, ==, <>, != | equality |
+, - | sign |
x ? a : b | ternary |
abs(x), max(x, y), min(x, y) | math helper functions |
Caution
Syntax errors in filter or goodness strings defined by you will cause errors to be thrown at volume request time.
There are various properties that can be used in either the filter_function or the goodness_function strings. The properties allow access to volume info, qos settings, extra specs, and so on.
The following properties and their sub-properties are currently available for use:
These properties are determined by the specific back end you are creating filter and goodness functions for. Some back ends may not have any properties available here.
The property most used from here will most likely be the size sub-property.
View the available properties for volume types by running:
$ cinder extra-specs-list
View the available properties for volume types by running:
$ cinder qos-list
In order to access these properties in a custom string use the following format:
<property>.<sub_property>
Below are examples for using the filter and weigher separately, together, and using driver-specific properties.
Example cinder.conf file configuration for customizing the filter function:
1 2 3 4 5 6 7 8 9 10 11 12 13 | [default]
scheduler_default_filters = DriverFilter
enabled_backends = lvm-1, lvm-2
[lvm-1]
volume_driver = cinder.volume.drivers.lvm.LVMVolumeDriver
volume_backend_name = sample_LVM
filter_function = "volume.size < 10"
[lvm-2]
volume_driver = cinder.volume.drivers.lvm.LVMVolumeDriver
volume_backend_name = sample_LVM
filter_function = "volume.size >= 10"
|
The above example will filter volumes to different back ends depending on the size of the requested volume. Default OpenStack Block Storage scheduler weighing is done. Volumes with a size less than 10 GB are sent to lvm-1 and volumes with a size greater than or equal to 10 GB are sent to lvm-2.
Example cinder.conf file configuration for customizing the goodness function:
1 2 3 4 5 6 7 8 9 10 11 12 13 | [default]
scheduler_default_weighers = GoodnessWeigher
enabled_backends = lvm-1, lvm-2
[lvm-1]
volume_driver = cinder.volume.drivers.lvm.LVMVolumeDriver
volume_backend_name = sample_LVM
goodness_function = "(volume.size < 5) ? 100 : 50"
[lvm-2]
volume_driver = cinder.volume.drivers.lvm.LVMVolumeDriver
volume_backend_name = sample_LVM
goodness_function = "(volume.size >= 5) ? 100 : 25"
|
The above example will determine the goodness rating of a back end based off of the requested volume’s size. Default OpenStack Block Storage scheduler filtering is done. The example shows how the ternary if statement can be used in a filter or goodness function. If a requested volume is of size 10 GB then lvm-1 is rated as 50 and lvm-2 is rated as 100. In this case lvm-2 wins. If a requested volume is of size 3 GB then lvm-1 is rated 100 and lvm-2 is rated 25. In this case lvm-1 would win.
Example cinder.conf file configuration for customizing both the filter and goodness functions:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | [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_LVM
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_LVM
filter_function = "stats.total_capacity_gb >= 500"
goodness_function = "(volume.size >= 25) ? 100 : 75"
|
The above example combines the techniques from the first two examples. The best back end is now decided based off of the total capacity of the back end and the requested volume’s size.
Example cinder.conf file configuration for accessing driver specific properties:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | [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 = "volumes.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"
|
The above is an example of how back-end specific properties can be used in the filter and goodness functions. In this example the LVM driver’s total_volumes capability is being used to determine which host gets used during a volume request. In the above example, lvm-1 and lvm-2 will handle volume requests for all volumes with a size less than 5 GB. The lvm-1 host will have priority until it contains three or more volumes. After than lvm-2 will have priority until it contains eight or more volumes. The lvm-3 will collect all volumes greater or equal to 5 GB as well as all volumes once lvm-1 and lvm-2 lose priority.
Except where otherwise noted, this document is licensed under Creative Commons Attribution 3.0 License http://creativecommons.org/licenses/by/3.0/legalcode.