OpenStack配额(Quota)设计与实现

配额(Quota)模块在openstack中是一个比较小的模块,具有比较好的扩展性。

功能

配额能够以user、project以及 quota class 这三个单位计算配额。默认情况下,是以project为计算单元。

抽象

配额在使用的过程中,抽象出三个概念:资源、驱动、引擎。

资源

BaseResource

定义了一个配额单元的基本属性,如下

class BaseResource(object):
    def __init__(self, name, flag=None):
    def quota(self, driver, context, **kwargs):
    def default(self):
quota方法用于获取资源的使用量,default方法用户获取默认值。

默认情况下,BaseResource使用context中的project_id和quota_class,决定使用何种规律获取资源的使用量。(按照用户呢,还是按照用户组呢)Nova并非直接使用BaseResource,而是将它扩展成AbsoluteResource、ReservableResource、CountableResource。

AbsoluteResource:即BaseResource。

ReservableResource:相比BaseResource,多了sync方法,sync会被驱动调用,用于在计算配额之前,先同步配额信息(到本地和数据库)。ReservableResource只能用于project绑定的资源。

CountableResource:相比BaseResource,多了count方法,count方法必须给出一个函数,自己计算配额,其返回值里会包含配额实际使用值。

驱动

驱动是实现配额逻辑的主要方法,其必须提供以下接口。

#取得配额(以各种单位下的)使用值
def get_by_project_and_user(self, context, project_id, user_id, resource):
def get_by_project(self, context, project_id, resource):
def get_by_class(self, context, quota_class, resource):
#取得配额(以各种单位下的)默认限制值
def get_defaults(self, context, resources):
def get_class_quotas(self, context, resources, quota_class, defaults=True):
def get_user_quotas(self, context, resources, project_id, user_id, quota_class=None, defaults=True, usages=True):
def get_project_quotas(self, context, resources, project_id, quota_class=None, defaults=True, usages=True, remains=False):
#取得某个配额可设定的限制范围
def get_settable_quotas(self, context, resources, project_id, user_id=None):
#确定某个配额是否超标
def limit_check(self, context, resources, values, project_id=None, user_id=None):
#确定在配额范围内分配资源,实现配额请求的事物处理
def reserve(self, context, resources, deltas, expire=None, project_id=None, user_id=None):
def commit(self, context, reservations, project_id=None, user_id=None):
def rollback(self, context, reservations, project_id=None, user_id=None):
#清除project、user的配额信息,使用信息
def destroy_all_by_project_and_user(self, context, project_id, user_id):
def destroy_all_by_project(self, context, project_id):
#清空由某个用户产生的使用信息
def usage_reset(self, context, resources):
#放弃所有长期没有被处理的配额请求
def expire(self, context):

多种资源自适应 :限额驱动会先判断资源类型,然后使用合适的方法计算、占用资源。

事物逻辑:相比直接存取数据,限额驱动提供的最有意义的功能就是提供了一个可回滚的事务逻辑。不过目前的代码里,事物逻辑仅限于以project为单位的资源(我想因为只有它才存在并发冲突的问题吧)。调用reserve方法时,能够取得一些带过期时间的reservation,这些reservation能够被提交和回滚和清理。



版权声明:本文为qiuhan0314原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。