本文共 5078 字,大约阅读时间需要 16 分钟。
在实际应用中,为了实现基于利用率的调度(utilization-based scheduler)对Ceph OSD系统盘数量的优先调度,我们需要对Nova计算监控机制进行相应的扩展和配置。以下将详细介绍实现这一目标的具体步骤和技术细节。
首先,在配置文件中添加新的监控驱动。我们需要编辑Nova的配置文件nova-4.0rc6-py2.7.egg-info/entry_points.txt
,并在nova.compute.monitors.osd
对应的位置添加新的驱动实现。具体来说,我们需要在文件中添加如下内容:
[nova.compute.monitors.osd]virt_driver = nova.compute.monitors.osd.virt_driver:Monitor
接下来,我们需要将新的监控驱动注册到Nova的监控系统中。为此,我们需要编辑nova/compute/monitors/__init__.py
,并在NAMESPACES
列表中添加新的监控类型。具体修改如下:
NAMESPACES = [ 'nova.compute.monitors.cpu', 'nova.compute.monitors.osd', # 增加osd监控]
然后,我们需要实现新的监控功能。具体来说,我们需要在nova/compute/monitors/osd/virt_driver.py
中定义新的监控类。以下是该文件的核心代码逻辑:
import pyudevfrom oslo_config import cfgfrom oslo_log import log as loggingfrom oslo_utils import timeutilsfrom nova.compute.monitors import basefrom nova import exceptionfrom nova.i18n import _LECONFLOG = logging.getLogger(__name__)class Monitor(base.OSDMonitorBase): """CPU monitor that uses the virt driver's get_host_cpu_stats() call.""" def __init__(self, resource_tracker): super(Monitor, self).__init__(resource_tracker) self.source = cfg.CONF.compute_driver self.driver = resource_tracker.driver self._data = {} self._cpu_stats = {} def get_metric(self, name): self._update_data() return self._data[name], self._data["timestamp"] def _update_data(self): now = timeutils.utcnow() if self._data.get("timestamp") is not None: delta = now - self._data.get("timestamp") if delta.seconds <= 1: return self._data, now # Extract node's CPU statistics. try: context = pyudev.Context() pattern = re.compile('^/dev/vd[a-z]') osd_devices = [] for device in context.list_devices(DEVTYPE='disk'): major = device['MAJOR'] if major == '8' or re.search(pattern, device.device_node): osd_devices.append(device.device_node) self._data["osd.num"] = len(osd_devices) except (NotImplementedError, TypeError, KeyError): LOG.exception(_LE("Not all properties needed are implemented")) raise exception.ResourceMonitorError( monitor=self.__class__.__name__ )
此外,我们还需要创建新的监控对象类。为此,我们需要编辑nova/objects/monitor_osd_metric.py
,并定义新的对象类。以下是该文件的核心代码:
from oslo_serialization import jsonutilsfrom oslo_utils import timeutilsfrom nova.objects import basefrom nova.objects import fieldsfrom nova import utilsNOTE(jwcroppe): Used to determine which fields whose value we need to adjust(READ: divide by 100.0 before sending information to the RPC notifier sincethese values were expected to be within the range [0, 1])FIELDS_REQUIRING_CONVERSION = []@base.NovaObjectRegistry.registerclassclass OSDMonitorMetric(base.NovaObject): """Version 1.0: Initial version Version 1.1: Added Numa support VERSION = '1.1' fields = { 'name': fields.OSDMonitorMetricTypeField(nullable=False), 'value': fields.IntegerField(nullable=False), 'numa_membw_values': fields.DictOfIntegersField(nullable=True), 'timestamp': fields.DateTimeField(nullable=False), # This will be the full class name for the plugin from which the metric originates 'source': fields.StringField(nullable=False), } def obj_make_compatible(self, primitive, target_version): super(OSDMonitorMetric, self).obj_make_compatible(primitive, target_version) target_version = utils.convert_version_to_tuple(target_version) if target_version < (1, 1): del primitive['numa_membw_values'] def to_dict(self): dict_to_return = { 'name': self.name, # NOTE(jaypipes): This is what jsonutils.dumps() does # for datetime.datetime objects, which is what timestamp is in # this object as well 'timestamp': timeutils.strtime(self.timestamp), 'source': self.source, } if self.obj_attr_is_set('value'): if self.name in FIELDS_REQUIRING_CONVERSION: dict_to_return['value'] = self.value / 100.0 else: dict_to_return['value'] = self.value elif self.obj_attr_is_set('numa_membw_values'): dict_to_return['numa_membw_values'] = self.numa_membw_values return dict_to_return @classmethod def from_json(cls, metrics): """Converts a legacy json object into a list of MonitorMetric objs and finally returns of MonitorMetricList""" metrics = jsonutils.loads(metrics) if metrics else [] metric_list = [OSDMonitorMetric(**metric) for metric in metrics] return OSDMonitorMetricList(objects=metric_list)
最后,我们需要定义新的监控指标类型字段。为此,我们需要编辑nova/objects/fields.py
,并添加新的枚举类型。以下是该文件的核心代码:
class OSDMonitorMetricTypeField(BaseEnumField): AUTO_TYPE = OSDMonitorMetricType()class OSDMonitorMetricType(Enum): OSD_NUM = "osd.num" ALL = (OSD_NUM,)
通过以上步骤,我们可以实现对Ceph OSD系统盘数量的基于利用率的调度优先级。需要注意的是,上述实现仅为演示 purposes,实际应用中需要根据具体需求进行调整和优化。此外,在实际操作中,建议参考相关文档和官方指南,确保所有配置和修改都符合Nova和Ceph的官方规范。
转载地址:http://tljfk.baihongyu.com/