快速理解OpenTSDB的Schema设计
在时序数据库中,Time Series是一个基础概念。我们先来看看Wiki中关于Time Series的定义:
Time Series是一组按照时间发生先后顺序进行排列的数据点序列。通常一组时间序列的时间间隔为一恒定值(如1秒,5分钟,1小时等)。
我们可以这样命名一个Time Series:
webserver01.sys.cpu.0.user
这样从名称中可以很容易获知该Time Series关联了如下信息:
Web Server: webserver01
CPU Core: 0
如果我们的查询可以同时指定web server以及cpu core的话,这种设计则非常适合。
但对于一个拥有64 Cores的Web Server,如果查询所有CPU Cores的聚合结果的话,可以通过如下的通配符来匹配所有相关的Time Series:
查询1: webserver01.sys.cpu.*.user
这样,可以获取到64个Time Series,然后聚合结果即可。
但如果有1000个Web Servers呢?我们需要基于如下的通配符来匹配所有的相关Time Series:
查询2: .sys.cpu..user
关于如上两种查询,一种可选的加速方案为:在这64个Time Series之外,记录一个名为”webserver01.sys.cpu.user.all”的Time Series,这样可以加速查询1中所有CPU Cores的聚合统计计算。 而关于查询2,可以记录一个名为”webservers.sys.cpu.user.all”的Time Series来进行加速。
在OpenTSDB的Schema定义中,引入了Tag的概念。每一个Time Series包含一个Metric名称,但可能包含包含1组或多组Tags信息(每一个Tag包含一个TagKey与TagValue),以前面的”webserver01.sys.cpu.0.user”为例,在OpenTSDB表示为:
sys.cpu.user host=webserver01, cpu=0
将其拆解后的构成信息:
sys.cpu.user : <Metric Name>
host : <TagKey>
webserver01 : <TagValue>
cpu : <TagKey>
0 : <TagValue>
OpenTSDB中的一个Time Series,由Metric Name与X个Tags(X>=1)唯一决定。
例如:
sys.cpu.user host=webserver01
sys.cpu.user host=webserver01, cpu=0
sys.cpu.user host=webserver02, cpu=1
代表了三个不同的Time Series。
如果查询时指定Web Server,指定CPU Core的聚合结果,可以简单表达为:
sum: sys.cpu.user {host=webserver01, cpu=42}
注:实际查询时需要指定时间信息,这里为了简单起见,省略了时间信息,下同。
如果查询Web Server上所有的CPU Cores的聚合结果,可以这么表达:
sum: sys.cpu.user {host=webserver01}
这样就可以汇聚了webserver01上所有CPU Cores所关联的Time Series的结果。
再进一步,如果查询所有的Web Servers所有CPU Cores的聚合结果,可以这么表达:
sum: sys.cpu.user
与同一metric name相关的所有的Time Series信息,都是相邻存储的,因此,我们可以轻易实现与此metric相关的快速聚合查询或结果钻取。
既然了解了OpenTSDB的schema由Metric与Tags构成,我们接下来看看需要注意的一个问题:
继续上面的例子,假设我们记录了一个Web Server的64个CPU Cores相关的Time Series:
sys.cpu.user host=webserver01,cpu=0 1356998400 1
sys.cpu.user host=webserver01,cpu=1 1356998400 0
sys.cpu.user host=webserver01,cpu=2 1356998400 2
sys.cpu.user host=webserver01,cpu=3 1356998400 0
…
sys.cpu.user host=webserver01,cpu=63 1356998400 1
而且我们使用了如下命名的Time Series来记录关于这个Web Server上的所有CPU Cores的聚合结果:
sys.cpu.user host=webserver01 1356998400 50
也就是说,表中一共存储了65条记录。
关于如下查询:sum:sys.cpu.user {host=webserver01}
我们期望的聚合结果应该为50,但实际的查询结果却会变为100,这是因为这次查询共聚合了下面的65条记录的结果:
sys.cpu.user host=webserver01 1356998400 50
sys.cpu.user host=webserver01,cpu=0 1356998400 1
sys.cpu.user host=webserver01,cpu=1 1356998400 0
sys.cpu.user host=webserver01,cpu=2 1356998400 2
sys.cpu.user host=webserver01,cpu=3 1356998400 0
…
sys.cpu.user host=webserver01,cpu=63 1356998400 1
再举一个典型的例子来阐述说明一下这里的查询行为:
如果查询条件为”sum:sys.cpu.user {host=webserver01}”, 如下这些Time Series都将会被包含其中:
sys.cpu.user host=webserver01,cpu=0
sys.cpu.user host=webserver01,cpu=0,manufacturer=Intel
sys.cpu.userhost=webserver01,foo=bar
sys.cpu.user host=webserver01,cpu=0,datacenter=lax,department=ops
因为这些与”sys.cpu.use”的Time Series中都包含了Tag {host=webserver01}(尽管有一些Time Series中包含了更多的Tags)。
因此,使用OpenTSDB时需要注意关于Tags定义方面的问题。