Ceilometer项目的初衷是作为Openstack的计费系统。众所周知,计费系统在云计算系统特别是公有云中起着重要的作用。这也意味着Ceilometer项目是Openstack走向成熟商业产品的标志。但可能是因为当时的核心开发人员对计费也没有想得特别清楚,以至于现在的Ceilometer更像是一个监控系统,而且是一个性能比较慢的监控系统。不过这也给了很多开发人员展示拳脚的机会。
Ceilometer的概念
+-------+--------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-------+--------------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| name | varchar(255) | NO | MUL | NULL | |
| type | varchar(255) | YES | | NULL | |
| unit | varchar(255) | YES | | NULL | |
+-------+--------------+------+-----+---------+----------------+
包括名字、类型和单位,其中类型又分为以下三种:
1)cumulative:表示递增的数据
2)delta:值会被前面的值所影响
3) gauge:表示值的变化没有规律
+-------------------+--------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-------------------+--------------+------+-----+---------+----------------+
| internal_id | int(11) | NO | PRI | NULL | auto_increment |
| resource_id | varchar(255) | YES | MUL | NULL | |
| user_id | varchar(255) | YES | | NULL | |
| project_id | varchar(255) | YES | | NULL | |
| source_id | varchar(255) | YES | | NULL | |
| resource_metadata | text | YES | | NULL | |
| metadata_hash | varchar(32) | YES | | NULL | |
+-------------------+--------------+------+-----+---------+----------------+
其中resource_metadata表示资源的详细信息,比如如果是一个镜像资源则会包含该镜像的名字、状态、格式等信息。
metadata_hash表示resource_metadata的hash值,主要是为了提高查询的效率。
+-------------------+---------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-------------------+---------------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| volume | double | YES | | NULL | |
| message_signature | varchar(1000) | YES | | NULL | |
| message_id | varchar(1000) | YES | | NULL | |
| timestamp | decimal(20,6) | YES | MUL | NULL | |
| recorded_at | decimal(20,6) | YES | | NULL | |
| meter_id | int(11) | YES | MUL | NULL | |
| resource_id | int(11) | YES | MUL | NULL | |
+-------------------+---------------+------+-----+---------+----------------+
其中volume为sample的值。
statistics中duration和period的概念比较容易混淆,其中duration表示统计的总体时间范围,而period又可以把duration分成更小的时间片进行聚合。
lan@lan-pc:~$ ceilometer statistics -m image -p 10
+--------+---------------------+---------------------+-----+-----+-----+-----+-------+----------+---------------------+---------------------+
| Period | Period Start | Period End | Max | Min | Avg | Sum | Count | Duration | Duration Start | Duration End |
+--------+---------------------+---------------------+-----+-----+-----+-----+-------+----------+---------------------+---------------------+
| 10 | 2015-01-18T07:44:48 | 2015-01-18T07:44:58 | 1.0 | 1.0 | 1.0 | 4.0 | 4 | 0.0 | 2015-01-18T07:44:48 | 2015-01-18T07:44:48 |
| 10 | 2015-01-18T07:54:48 | 2015-01-18T07:54:58 | 1.0 | 1.0 | 1.0 | 4.0 | 4 | 0.0 | 2015-01-18T07:54:48 | 2015-01-18T07:54:48 |
| 10 | 2015-01-18T08:04:48 | 2015-01-18T08:04:58 | 1.0 | 1.0 | 1.0 | 4.0 | 4 | 0.0 | 2015-01-18T08:04:48 | 2015-01-18T08:04:48 |
| 10 | 2015-01-18T08:14:48 | 2015-01-18T08:14:58 | 1.0 | 1.0 | 1.0 | 4.0 | 4 | 0.0 | 2015-01-18T08:14:48 | 2015-01-18T08:14:48 |
| 10 | 2015-01-18T08:24:48 | 2015-01-18T08:24:58 | 1.0 | 1.0 | 1.0 | 4.0 | 4 | 0.0 | 2015-01-18T08:24:48 | 2015-01-18T08:24:48 |
| 10 | 2015-01-18T08:34:48 | 2015-01-18T08:34:58 | 1.0 | 1.0 | 1.0 | 4.0 | 4 | 0.0 | 2015-01-18T08:34:48 | 2015-01-18T08:34:48 |
+--------+---------------------+---------------------+-----+-----+-----+-----+-------+----------+---------------------+---------------------+
每次进行统计时都会进行所有的聚合运算,但由于ceilometer采用了map-reduce模型来计算这些值,所以也不容易产生多余的比较。
常用的转换(transformers)有以下三种:
1). unit_conversion: 单位转换,传入一个scale值。
2). rate_of_change: 将当前值和前一个值比较并除以时间差:
volume_delta = (s.volume - prev_volume
if (prev_volume <= s.volume or
s.type != sample.TYPE_CUMULATIVE)
else s.volume)
rate_of_change = ((1.0 * volume_delta / time_delta)
if time_delta else 0.0)
如果sample的类型不是cumulative,则volume_delta直接采用当前值 - 前一个值,这种情况允许负值。
如果sample的类型是cumulative,而且当前值 > 前一个值, 则取差, 如果当前值<前一个值,则将delta重置为当前值。
3). accumulator: 在传递出去之前能够收集多个sample数据。
4). aggregator: 聚合一段时间或者一个阀值内的sample。
当sample类型为cumulative时,返回最后一个sample值。
当sample类型为gauge时,返回所有sample的平均值。
5). arithmetic: 可以对多个meter进行算数运算:
- name: "arithmetic"
parameters:
target:
name: "memory_util"
unit: "%"
type: "gauge"
expr: "100 * $(memory.usage) / $(memory)"
pipeline中还有一个很重要的概念publisher,Ceilometer没有强制将数据发送到MQ中,它可以将数据灵活的发送到其他监控系统或者文件中。当前存在的publisher有:
1)rpc: 将sample数据以rpc的方式发送到MQ中
2)notifier: 将sample数据以notifier的方式发送到MQ中
3)udp: 将sample数据以socket的方式发送到udp server中
4)direct: 将sample数据直接存到数据库中
5)file: 将sample数据存到文件中
ceilometer中提供的dispatcher功能和publisher有点类似,只不过publisher根据不同的meter可能不通,而ceilometer会采用唯一的dispatcher。当前存在的dispatcher有:
1)database: 将publisher过来的sample数据直接存入数据库中
2)file:将publisher过来的sample数据存入文件中
3)http: 将publisher过来的sample数据以http的形式发送出去
由于ceilometer的数据会逐步的增长,相应的查询性能也会越来越差,目前的dispatcher已经不能满足快速查询的需求。同时,针对ceilometer存储的关键数据中时间作为很重要的一个查询条件,ceilometer的开发大牛们为了提交查询效率,提出了一个新的dispatcher: Gnocchi. 它为Openstack提供了TDBaaS(Time Series Database as a service)服务。感兴趣的话可以看一下Julien Danjou的blog:
https://julien.danjou.info/blog/2014/openstack-ceilometer-the-gnocchi-experiment
+---------------------------+---------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+---------------------------+---------------+------+-----+---------+-------+
| alarm_id | varchar(255) | NO | PRI | NULL | |
| enabled | tinyint(1) | YES | | NULL | |
| name | text | YES | | NULL | |
| description | text | YES | | NULL | |
| user_id | varchar(255) | YES | MUL | NULL | |
| project_id | varchar(255) | YES | MUL | NULL | |
| state | varchar(255) | YES | | NULL | |
| ok_actions | text | YES | | NULL | |
| alarm_actions | text | YES | | NULL | |
| insufficient_data_actions | text | YES | | NULL | |
| type | varchar(50) | YES | | NULL | |
| rule | text | YES | | NULL | |
| timestamp | decimal(20,6) | YES | | NULL | |
| state_timestamp | decimal(20,6) | YES | | NULL | |
| repeat_actions | tinyint(1) | YES | | 0 | |
| time_constraints | text | YES | | NULL | |
+---------------------------+---------------+------+-----+---------+-------+
其中rule表示alarm被触发的规则;evaluation_period表示需要触发规则的次数;
ok_actions表示当alarm进入ok状态需要触发的操作(webhooks);相应的,alarm_actions和insufficient_data_action分别表示当alarm进入alarm和insufficient状态时需要触发的操作。
repeat_actions: 表示alarm是否需要重复触发动作。
lan@lan-pc:~/stack/devstack$ ceilometer alarm-list
+--------------------------------------+----------+-------------------+---------+------------+---------------------------------+------------------+
| Alarm ID | Name | State | Enabled | Continuous | Alarm condition | Time constraints |
+--------------------------------------+----------+-------------------+---------+------------+---------------------------------+------------------+
| fa2b4aac-f8c7-4ec6-9208-71dcd1b0f51f | cpu_high | insufficient data | True | False | cpu_util > 70.0 during 3 x 600s | None |
+--------------------------------------+----------+-------------------+---------+------------+---------------------------------+------------------+
7 Event(事件) , event表示Openstack中资源状态的变化,比如虚拟机的启动,镜像的删除等。event的结构如下:
+---------------+---------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+---------------+---------------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| message_id | varchar(50) | YES | UNI | NULL | |
| event_type_id | int(11) | YES | MUL | NULL | |
| generated | decimal(20,6) | YES | MUL | NULL | |
+---------------+---------------+------+-----+---------+----------------+
event_type表示事件的类型,由点来分隔,如“compute.instance.update” 表示虚拟机状态的改变。
message_id表示消息的唯一标识id
generated表示事件发生的时间
其中Event中还有Traits的概念,它是一些键值对,描述了这个事件的详情,同事trait还有类型,当前支持 strings、ints、floats和datetimes.
它的结构如下:
+---------------+---------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+---------------+---------------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| t_string | varchar(255) | YES | MUL | NULL | |
| t_float | double | YES | MUL | NULL | |
| t_int | int(11) | YES | MUL | NULL | |
| event_id | int(11) | YES | MUL | NULL | |
| trait_type_id | int(11) | YES | MUL | NULL | |
| t_datetime | decimal(20,6) | YES | MUL | NULL | |
+---------------+---------------+------+-----+---------+----------------+