跳转到: 导航, 搜索

Manila/Provide private data storage API for drivers

为驱动程序提供有限的数据 API

问题

驱动程序目前无法在数据库中存储键/值对,用于共享/快照/等。这些值对租户不可见,仅供驱动程序使用。

用例

用例 #1: 通用驱动程序应存储卷 ID,而不是重命名卷(当前行为)
用例 #2: 一些无法创建 32 位字符共享名称的后端,需要维护从 128 位 UUID 到较小值的映射。

概念

为驱动程序提供私有数据存储(键/值对)

class StorageDriver(object):
    def __init__(self, backend_host):
        # Backend cannot access data stored by another backend
        self.backend_host = backend_host

    def details_get(self, namespace_name, entity_id, key, default):
        raise NotImplementedError()

    def details_update(self, namespace_name, entity_id, details,
                       delete_existing):
        raise NotImplementedError()

    def details_delete(self, namespace_name, entity_id, key):
        raise NotImplementedError()


class SqlStorageDriver(StorageDriver):
    pass


class PrivateDriverData(object):

    def __init__(self, context, storage):
        self.storage = storage
        self.context = context

    def details_get(self, entity_id, key=None, default=None):
        return self.storage.details_get(entity_id, key, default)

    def details_update(self, entity_id, details, delete_existing=False):
        return self.storage.details_update(
            entity_id, details, delete_existing)

    def details_delete(self, entity_id, key=None):
        return self.storage.details_delete(entity_id, key)


在管理器中向所有驱动程序提供此存储

class ShareManager(manager.SchedulerDependentManager):
    # …
    def __init__(self, share_driver=None, service_name=None, *args, **kwargs):
       # …
       self.private_driver_storage = PrivateDriverData(
              # …
       )
       self.driver = importutils.import_object(
           share_driver, 
           self.private_driver_storage,
           #...
       )
       # ...

并在驱动程序中使用

# Get data
share_data = self.data_storage.details_get(share_id)  # Get all data
volume_id = self.data_storage.details_get(share_id, 'volume_id')  # Get single key

# Update
self.data_storage.details_update(share_id, {'foo': 'bar'})

# Delete
self.data_storage.details_delete(share_id, 'foo')  # Delete single key
self.data_storage.details_delete(share_id)  # Delete all


此存储将允许获取/更新/删除驱动程序管理的所有实体的私有数据。驱动程序将能够创建 Manila(共享)中的数据与后端(NAS)之间的映射。此外,驱动程序可以使用此存储用于缓存目的 - 以最大程度地减少对后端的请求数量。

默认实现会将数据存储在 Manila 数据库中的单独表中

CREATE TABLE private_drivers_data
(
    created_at DATETIME,
    updated_at DATETIME,
    deleted_at DATETIME,
    deleted INT,
    host VARCHAR(255) NOT NULL,  # Backend name
    entity_id VARCHAR(36) NOT NULL, # Entity UUID
    `key` VARCHAR(255) NOT NULL, 
    value VARCHAR(1023) NOT NULL,
    PRIMARY KEY(host, entity_id, key)
);

数据库扩展风险

默认情况下,所有私有共享数据都将存储在 Manila SQL 数据库中,我们面临数据库成为大型部署中的瓶颈的风险。 在此功能的范围内,可以通过实现此接口的不同存储后端来解决此风险。 正如我们所见,后端不共享数据,因此存储可以轻松地水平扩展。 我们可以将私有共享数据移动到任何分布式键/值存储。