行协议教程

更新时间:

TSDB For InfluxDB®的行协议(Line Protocol)是一种基于文本的格式,用于将数据点写入数据库。数据点必须符合行协议格式,TSDB For InfluxDB®才能成功解析和写入数据点。

语法

行协议中,一行数据表示TSDB For InfluxDB®中的一个数据点,它告诉TSDB For InfluxDB®该数据点的measurement、tag set、field set和时间戳。以下代码块展示了行协议的一个示例,并将其分解成多个组成部分:

weather,location=us-midwest temperature=82 1465839830100400200
  |    -------------------- --------------  |
  |             |             |             |
  |             |             |             |
+-----------+--------+-+---------+-+---------+
|measurement|,tag_set| |field_set| |timestamp|
+-----------+--------+-+---------+-+---------+

下面,我们将逐个分析上图中的元素。

Measurement

您想要写入数据的measurement的名字。在行协议中,measurement是必须要有的。在上面的示例中,measurement的名字是weather

Tag set

您想要在数据点中包含的tag。在行协议中,tag是可选的。请注意,measurement和tag set被逗号隔开并且它们之间没有空格。

使用等号=分隔tag key和tag value,并且它们之间不能有空格:

<tag_key>=<tag_value>

使用逗号分隔多个tag key-value pairs,并且它们之间不能有空格:

<tag_key>=<tag_value>,<tag_key>=<tag_value>

在示例中,tag set由一个tag组成:location=us-midwest。在示例中添加另一个tag(season=summer),如下所示:

weather,location=us-midwest,season=summer temperature=82 1465839830100400200

为了获得最佳性能,您应该在将数据点发送到数据库之前,将tag按tag key进行排序。排序结果应该与Go bytes.Compare function的结果匹配。

空格 I

使用空格分隔measurement和field set,如果数据点中包含了tag set,也需要使用空格分隔tag set和field set。在行协议中,这里必须使用空格。

没有tag set的有效行协议:

weather temperature=82 1465839830100400200

Field set

数据点中的field。在行协议中,每个数据点至少需要有一个field。

使用等号=分隔field key和field value,并且它们之间不能有空格:

<field_key>=<field_value>

使用逗号分隔多个field key-value pairs,并且它们之间不能有空格:

<field_key>=<field_value>,<field_key>=<field_value>

在示例中,field set由一个field组成:temperature=82。在示例中添加另一个field(humidity=71),如下所示:

weather,location=us-midwest temperature=82,humidity=71 1465839830100400200

空格 II

使用空格分隔field set和时间戳(如果有的话)。如果为数据点指定了时间戳,那么在行协议中,这里必须使用空格。

时间戳

数据点中的时间戳是精确到纳米的Unix时间。在行协议中,时间戳是可选的。如果您没有指定数据点的时间戳,那么TSDB For InfluxDB®使用服务器本地的纳秒级时间戳(UTC格式)作为数据点的时间戳。

在示例中,时间戳是1465839830100400200(也就是2016-06-13T17:43:50.1004002Z,按照RFC3339格式)。下面的行协议表示相同的数据点,但是不带时间戳。当TSDB For InfluxDB®将该数据点写入数据库,它使用服务器的本地时间戳,而不是2016-06-13T17:43:50.1004002Z

weather,location=us-midwest temperature=82

使用HTTP API来指定除纳秒之外其它精度的时间戳,例如微秒、毫秒或者秒。我们建议尽量使用最粗糙的精度,因为这可以显著提高压缩效果。

说明

请使用网络时间协议(Network Time Protocol,NTP)来同步主机(host)之间的时间。TSDB For InfluxDB®使用主机的本地UTC时间为数据分配时间戳;如果主机的时钟与NTP不同步,写入TSDB For InfluxDB®的数据的时间戳可能会不准确。

数据类型

本节将介绍行协议中主要组成部分的数据类型:measurement、tag key、tag value、field key、field value和时间戳。

measurement、tag key、tag value和field key始终是字符串。

说明

注释:因为TSDB For InfluxDB®将tag value存储为字符串,所以TSDB For InfluxDB®不能对tag value执行数学运算。此外,InfluxQL函数不接受将tag value作为主要参数。当您在设计schema时,最好考虑一下这些细节。

时间戳是UNIX时间戳。最小的有效时间戳是-92233720368547758061677-09-21T00:12:43.145224194Z,最大的有效时间戳是92233720368547758062262-04-11T23:47:16.854775806Z。如上所述,默认情况下,TSDB For InfluxDB®假设时间戳精确到纳秒。关于如何指定其它精度,请查看文档HTTP API

field value可以是浮点数、整数、字符串或者布尔值:

  • 浮点数 - 默认情况下,TSDB For InfluxDB®假设所有数值类型的field value是浮点数。

    将field value 82存储为浮点数:

    weather,location=us-midwest temperature=82 1465839830100400200
  • 整数 - 在field value后面加上i,告诉TSDB For InfluxDB®将该数字存储为整数。

    将field value 82存储为整数:

    weather,location=us-midwest temperature=82i 1465839830100400200
  • 字符串 - 用双引号把字符串类型的field value括起来(更多关于行协议中引号的介绍,请参见“引号”内容)。

    将field value too warm存储为字符串:

    weather,location=us-midwest temperature="too warm" 1465839830100400200
  • 布尔值 - 可以使用tTtrueTrueTRUE指定TRUE,使用fFfalseFalseFALSE指定FALSE。

    将field value true存储为布尔值:

    weather,location=us-midwest too_hot=true 1465839830100400200
    说明

    注释:写入和查询布尔值的语法不一样。请查看FAQ获得更多相关信息。

在measurement中,一个field的数据类型在一个shard内不会不一致,但是在不同的shard,它的数据类型可以不同。例如,如果TSDB For InfluxDB®尝试将整数存储在与浮点数相同的shard中,那么将整数写入一个之前接受浮点数的field会失败:

> INSERT weather,location=us-midwest temperature=82 1465839830100400200
> INSERT weather,location=us-midwest temperature=81i 1465839830100400300
ERR: {"error":"field type conflict: input field \"temperature\" on measurement \"weather\" is type int64, already exists as type float"}

但是,如果TSDB For InfluxDB®尝试将整数存储在一个新的shard中,那么将整数写入一个之前接受浮点数的field会成功:

> INSERT weather,location=us-midwest temperature=82 1465839830100400200
> INSERT weather,location=us-midwest temperature=81i 1467154750000000000
>

若想了解field value的数据类型差异如何影响SELECT *查询,请查看FAQ的相关章节。

引号

本节将介绍在行协议中,什么时候不能使用双引号(")或单引号('),什么时候应该使用它们。我们先介绍不使用引号的情形,然后再介绍使用引号的情形:

  • 不能用双引号或单引号将时间戳括起来。这是无效的行协议。

    示例:

    > INSERT weather,location=us-midwest temperature=82 "1465839830100400200"
    ERR: {"error":"unable to parse 'weather,location=us-midwest temperature=82 \"1465839830100400200\"': bad timestamp"}
  • 不能用单引号将field value括起来(即使它们是字符串)。这也是无效的行协议。

    示例:

    > INSERT weather,location=us-midwest temperature='too warm'
    ERR: {"error":"unable to parse 'weather,location=us-midwest temperature='too warm'': invalid boolean"}
  • 不能用双引号或单引号将measurement的名字、tag key、tag value和field key括起来。虽然这是有效的行协议,但是TSDB For InfluxDB®会把引号当作是名字的一部分。

    示例:

    > INSERT weather,location=us-midwest temperature=82 1465839830100400200
    > INSERT "weather",location=us-midwest temperature=87 1465839830100400200
    > SHOW MEASUREMENTS
    name: measurements
    ------------------
    name
    "weather"
    weather

    查询在"weather"中的数据,您需要用引号将measurement的名字括起来,并且将measurement中的双引号转义:

    > SELECT * FROM "\"weather\""
    name: "weather"
    ---------------
    time                            location     temperature
    2016-06-13T17:43:50.1004002Z    us-midwest   87
  • 不能用双引号将字符串类型、整型或布尔类型的field value括起来。否则,TSDB For InfluxDB®会把这些值当作字符串。

    示例:

    > INSERT weather,location=us-midwest temperature="82"
    > SELECT * FROM weather WHERE temperature >= 70
    >
  • 需要用双引号将字符串类型的field value括起来。

    示例:

    > INSERT weather,location=us-midwest temperature="too warm"
    > SELECT * FROM weather
    name: weather
    -------------
    time                            location     temperature
    2016-06-13T19:10:09.995766248Z  us-midwest   too warm

特殊字符和关键字

特殊字符

对于tag key、tag value和field key,始终使用反斜杠\来转义:

  • 逗号 ,

    weather,location=us\,midwest temperature=82 1465839830100400200
  • 等号 =

    weather,location=us-midwest temp\=rature=82 1465839830100400200
  • 空格

    weather,location\ place=us-midwest temperature=82 1465839830100400200

    对于measurement,始终使用反斜杠\来转义:

  • 逗号 ,

    wea\,ther,location=us-midwest temperature=82 1465839830100400200
  • 空格

    wea\ ther,location=us-midwest temperature=82 1465839830100400200

    对于字符串类型的field value,使用反斜杠\来转义:

  • 双引号 "

    weather,location=us-midwest temperature="too\"hot\"" 1465839830100400200

行协议不需要用户将反斜杠\转义,但是如果您这样做也没有问题。例如,写入以下数据:

weather,location=us-midwest temperature_str="too hot/cold" 1465839830100400201
weather,location=us-midwest temperature_str="too hot\cold" 1465839830100400202
weather,location=us-midwest temperature_str="too hot\\cold" 1465839830100400203
weather,location=us-midwest temperature_str="too hot\\\cold" 1465839830100400204
weather,location=us-midwest temperature_str="too hot\\\\cold" 1465839830100400205
weather,location=us-midwest temperature_str="too hot\\\\\cold" 1465839830100400206

将会理解为(请注意,用单引号或双引号将反斜杠括起来会产生相同的结果):

> SELECT * FROM "weather"
name: weather
time                location   temperature_str
----                --------   ---------------
1465839830100400201 us-midwest too hot/cold
1465839830100400202 us-midwest too hot\cold
1465839830100400203 us-midwest too hot\cold
1465839830100400204 us-midwest too hot\\cold
1465839830100400205 us-midwest too hot\\cold
1465839830100400206 us-midwest too hot\\\cold

所有其它的特殊字符也不需要转义。例如,行协议处理表情符号(emojis)没有问题:

> INSERT we⛅️ther,location=us-midwest t⛅️emperture=82 1465839830100400200
> SELECT * FROM "we⛅️ther"
name: we⛅️ther
------------------
time                                  location     t⛅️emperture
1465839830100400200      us-midwest      82

关键字

行协议将InfluxQL关键字作为标识符名字。通常,我们建议避免在schema中使用InfluxQL关键字,因为它可能会在查询数据时引起混淆。

关键字time是一个特例。time可以是一个连续查询名字、数据库名字、measurement的名字、保留策略名字、subscription的名字和用户名。在这些情况下,不需要在查询中用双引号将time括起来。time不能是field key或tag key;TSDB For InfluxDB®拒绝写入将time作为field key或tag key的数据,对于这种数据写入,TSDB For InfluxDB®会返回错误。请查阅FAQ获得更多相关信息。

将数据写入TSDB For InfluxDB®

将数据写入数据库

现在您已经知道了关于行协议的所有内容,那么如何使用行协议将数据写入TSDB For InfluxDB®呢?在本节,我们将给出两个简单示例,请参见工具章节获取更多相关信息。

HTTP API

使用HTTP API将数据写入TSDB For InfluxDB®。向/write路径发送POST请求,并在request body中给出行协议数据:

curl -i -XPOST "https://<网络地址>:3242/write?db=science_is_cool&u=<账号名称>&p=<密码>" --data-binary 'weather,location=us-midwest temperature=82 1465839830100400200'

有关查询参数、状态码、响应和更多示例的深入讲解,请查看文档HTTP API

CLI

使用TSDB For InfluxDB®的命令行界面(Command Line Interface,CLI)将数据写入TSDB For InfluxDB®。启动CLI,使用相关的数据库,并且将INSERT放在行协议语句前面:

INSERT weather,location=us-midwest temperature=82 1465839830100400200

您还可以使用CLI导入文件中的数据。

将数据写入TSDB For InfluxDB®的方法有几种,请参见工具章节获取更多相关信息。

重复数据点

measurement的名字、tag set和时间戳唯一标识一个数据点。如果您提交的数据具有相同measurement、tag set和时间戳但具有不同field set,那么数据的field set会变为旧field set和新field set的并集,如果有任何冲突以新field set为准。

有关此行为的完整示例和如何避免这种情况,请查看FAQ相关章节。