经历了五年的成长,OpenStack 的 IaaS 服务愈发成熟,在私有云和公有云领域得到较为广泛的应用,与此同时,相应的计费方案也呼之欲出,特别对于公有云。但是纵观社区的计费项目,它们在功能、成熟度等方面有待提升,加上不同场景下的计费方式差异较大,所以社区的计费项目有时可能无法很好的满足需求。按需按量是云计算的一大重要特点,如果计费系统能够提供更为精细的时间粒度,比如秒级,将有助于提升云平台的弹性。本文浅谈如何设计一个计费系统,并给出一个简单的 demo —— koala


计费资源

在设计计费系统前,首先需要明白哪些资源需要计费,以及这些资源的特点。OpenStack 的服务覆盖了多个领域,从 IaaS 到 PaaS,例如:

  • IaaS
    • Compute: instance
    • Network: floating ip, router, load balance
    • Storage: volume, snapshot, image, instance snapshot, object storage.
    • Alarm
  • PaaS
    • Database
    • Big Data
    • Redis

本文重点关注 IaaS 计算、存储和网络资源的计费,它们的计费规则通常可以抽象为:

费用 = 时间 * 规格单价

例如:
虚拟机 = 时间 * 规格单价
存储 = 时间 * (容量 * 每GB单价)
路由器 = 时间 * 规格单价

但是 floating ip 是一种比较特殊的资源,因为它的计费方式多样:按流量或按带宽计费。如果按带宽计费,可用上述公式。在按流量计费的场景下,它的计费规则为:

费用 = 流量 * 流量单价 

理想的计费系统

凡是和钱挂钩的系统,在设计上都必需小心翼翼,三思而后行,这类系统对高可靠、准确和安全性有着严格的要求,OpenStack 的计费系统也不例外。本人认为,一个理想的计费系统必须满足以下需求:

  • 准确性:准确的记录资源的使用状况,并生成账单。
  • 高可靠性:计费系统需设计成高可靠,避免单点故障。
  • 安全性:全方位保证计费系统的安全,比如采用 HTTPS,ACL 等。

也应该尽可能满足以下需求:

  • 实时性
  • 支持多 region
  • 可扩展性:每当有新的云服务上线,这些服务应当可方便地接入到计费系统。
  • 秒级计费:精确到秒级计费,提升云平台的弹性。
  • 容错能力:本着宁可漏计,不可多计的原则,合理的处理数据的采集异常、发送异常等场景。
  • 子账户:支持子账户。

社区主要有两个计费项目,cloudkittystacktach。Cloudkitty 依赖 ceilometer 的 sample 计费,只能提供分钟级别的粒度,无法记录资源状态的变更时间点,实时性弱,并且受限于 ceilometer 的性能,支持的资源有限,扩展性差。Stacktach 的计费功能基本不可用。

所以,本文提出另外一种计费系统,它依赖 ceilometer 的 event 信息进行计费。


基于 event 的计费系统

博文 ceilometer 的 sample 和 event 分析了 sample 和 event 这两类数据的特点。

sample 数据虽然为计费提供了一定的信息,但是并不能提供完整的信息,如:无法提供虚拟机的状态,shut off 和 running 状态的计费价格不一致;无法提供虚拟机准确的创建时间,关机时间,即无法提供秒级的计费等。

event 类型数据同样记录了资源的重要信息,event 的数据类型可分为两类:

  • 状态变更类型 event:所有的资源,每当其被创建、更新或者删除等时,会及时发出 notification 事件。
  • audit 类型 event:nova, cinder 和 neutron 等服务会周期性(每小时)统计各个资源的状态,并发出 notification 事件。

instance_event

从全局出发,和 event 相比,sample 具有如下缺点,如:

  • 计费指标不全面,没有 volume、floatingIP、snapshot、router 相关的计量数据。
  • 无法提供虚拟机的状态,shutoff 和 running 状态的计费价格不一致。
  • 无法提供虚拟机准确的创建时间,关机时间,即无法提供秒级的计费。
  • 数据量太大问题,sample 一般为数分钟采集一次,其中诸多数据对计费而言,毫无意义。

而采用 event 计费,可有如下优点:

  • 准确性:因为 event 记录了资源的状态变更,所以具有高准确性。
  • 秒级计费
  • 实时性高:秒级的实时性。
  • 高扩展性:OpenStack 各个服务基本上都支持 notification。

下图展示一个基于 event 的计费系统样例的架构:

koala

从上可以看出,该计费系统全局唯一,每当各个 region 下的 ceilometer-notification-agent 收集到 event 时,会把这些 event 先过滤,然后做一定处理后经 https 发送至计费系统。如下发给计费系统的一个 event 样例:

{
    "region": "bj",
    "resource_id": "ca9ef7fe-889d-462e-91e4-f05a60abc739",
    "resource_name": "lg",
    "resource_type": "volume",
    "tenant_id": "33294fe9cd6c4150b43b38cd92ea17c5",
    "event_type": "create",
    "event_time": "2015-09-25T07:54:38.235522"
    "content": {"size": 100}
}

每当计费系统接收到请求后,生成账单信息。如果计费信息发送失败,ceilometer 可标志该 event。如下是根据上述 event 生成的账单信息。

[
    {
        "consumption": 0.0022200000000000002,
        "description": "Resource has been deleted",
        "end_at": "2015-09-25T08:01:48.629053",
        "resource_id": "723566f3-db38-4e37-bdc7-fb0d33856468",
        "start_at": "2015-09-25T08:01:39.504316",
        "unit_price": 0.88800000000000001
    }
]

在上述架构下,计费系统有如下优点:

  • 支持多 region
  • 低耦合:计费系统和 OpenStack 的组件解耦,仅通过 https 协议通信,低耦合下计费系统可以不关心 OpenStack 的版本。

这种架构要求 ceilometer 发送计费信息,势必需往 ceilometer 增添代码,这是其中的一个缺点。计费系统本身在实现和部署上还需要注意以下问题:

  • 高可靠:koala 就是按照高可靠标准设计的,它只有一个进程 koala-api,可以部署在多个节点。
  • 高容错性:它依赖处理计费时具体的逻辑实现。
  • 安全性