前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >如何查询InfluxDB

如何查询InfluxDB

作者头像
大数据弄潮儿
修改2018-05-21 16:41:18
11.2K1
修改2018-05-21 16:41:18
举报
文章被收录于专栏:大数据大数据

InfluxDB是一个很流行的基于时间序列的数据库,下面是这个数据库的最基本的查询命令。InfluxDB使用类SQL(实际上它就是一种特殊的“SQL”)的语言。

代码语言:javascript
复制
SELECT * FROM "foodships" WHERE time > now() - 1h

一开始InfluxDB就支持这种类SQL语言,所以它也同时兼备了这类语言的优缺点:

  1. 对于新用户来说很容易用他们掌握的语言与数据库进行交互。SQL很流行,所以许多开发人员都会使用。这种查询语法对InfluxDB的早期发展很有帮助。
  2. 正如我之前所说的,InfluxQL是一种“类SQL”的语言。编写SQL查询语言不是一件简单的工作。其中一个问题就是DBA包含了一些SQL的预期设计,但是我们的语言与SQL并不完全兼容。这就造成了许多无法令人头疼的问题
  3. 时间序列数据库的特点之一是读写可以同时进行。这其实也是这类数据库的必备特性。你的物联网设备或服务器一直在写入数据,而与此同时仪表板,分析工具和警报管理器将从数据库读取数据。InfluxDB需要更好的可扩展性。
  4. 如果相同时刻存储引擎和查询语言都在同一个项目中,这会阻碍我们想要的代码的快速迭代功能。与存储引擎相比,查询语言更快地优化。引擎需要稳定性,而查询语言需要的更多的是功能和性能。
  5. InfluxQL需要重新进行架构,因为开发者团队无法保证满足社区里面千奇百怪的想法。
  6. 现在的话,SQL学习起来非常简单,但我们的栈中还有另一个DSL可采用:从Kapacitor使用的TICK脚本发送警报并对缩减你的系列样本。
  7. InfluxQL没有数学函数库,因为语言不允许我们用简单的方式添加数据。而使用IFQL,我们却很容易实现它们。

在旧金山的InfluxDays期间,InfluxData的首席技术官兼创始人Paul Dix发布了一种新的开源查询语言,其数据分析与InfluxDB很接近。我们称之为IFQL

架构

代码语言:typescript
复制
var cpu = select(db: "telegraf")
  .filter(exp:{"_measurement" == "cpu" and "_field" == "usage_user"})
  .range(start: -30m)
  
select(db: "telegraf")
  .filter(exp:{"_measurement" == "mem" and "_field" == "used_percent"})
  .range(start: -30m)
  .join(on:["host"], eval:{$ + cpu})

IFQL不只是一种查询语言。它还包含有一个解析器,可以读取上面的查询,并生成一个可视化为JSON,然后通过IFQL直接运行。这意味着你所看到的语法只是其中一种可能的实现。真正重要的部分是在设计和处理器之间。

这个项目的架构和思想让我们可以在IFQL AST之上重新实现InfluxQL和PromQL,TICK Script。除此之外,如果你有你的查询构建器或者你需要创建一个自定义的实现来与InfluxDB交互,你可以简单地将JSON推送到IFQL。这的确很令人很意外。

IFQL的设计是可扩展的,为了实现这个特性 - 我们从Telegraf项目学到了深刻的教训。你需要一个简单的接口和一个接入点,这样开发人员才会很乐意为你的项目做出贡献。这就是为什么IFQL有一个叫做函数目录的原因。它包含当前支持的所有函数,并且希望添加功能的贡献者只在该目录中添加函数。

TICK Script和IFQL

IFQL的目的之一是能够提供TICK Script提供的所有功能,这样我们就能够在不学习两种语言的情况下进行查询,操作和发送警报。

目前,我们已经将两个项目中函数复制了,这样我们就可以通过IFQL再次使用它们。

目前,IFQL是GitHub上的一个独立项目。除了解析器和设计器之外,它还提供了一个简单的名叫 ifqld的http后台程序,用于进行一些测试。

IFQL仍处于测试阶段,这意味着API和查询语法可能将会更改,但它设置起来非常简单。我将使用Docker来举个例子,如果您不熟悉Docker,则可以在此处下载IFQL的安装包 。

我们先从IFQL存储库下载一个InfluxDB配置文件:

代码语言:html
复制
wget https://raw.githubusercontent.com/influxdata/ifql/master/docker-compose.yml
mkdir examples
wget https://raw.githubusercontent.com/influxdata/ifql/master/examples/influxdb.conf -O examples/influxdb.conf

主要区别在于后者支持IFQL的段落:

代码语言:javascript
复制
[ifql]
  enabled = true
  log-enabled = true
  bind-address = ":8082"

InfluxDB使用端口8082与IFQL的gRPC进行通信。

代码语言:javascript
复制
docker-compose up

如您所见,我们创建了一个网络并部署了两个容器。一个是InfluxDB,我们修改了配置,并暴露了8082和8086端口。第二个是IFQL v0.0.2。它使用了端口8093,我们可以通过运行一个简单的curl来验证一切是否正常工作。

代码语言:javascript
复制
15:21 $ curl -I http://localhost:8093/
HTTP/1.1 404 Not Found
Content-Type: text/plain; charset=utf-8
X-Content-Type-Options: nosniff
Date: Tue, 28 Nov 2017 14:21:40 GMT
Content-Length: 19

现在让我们用一些示例数据填充我们的数据库:

代码语言:javascript
复制
curl https://s3.amazonaws.com/noaa.water-database/NOAA_data.txt -o NOAA_data.txt
influx -import -path=NOAA_data.txt -precision=s -database=NOAA_water_database
influx
use NOAA_water_database
SELECT COUNT(*) FROM NOAA_water_database
> SELECT COUNT(*) FROM h2o_feet
name: h2o_feet
time count_level description count_water_level
---- ----------------------- -----------------
0    15258                   15258

正如看到的,我们有一些时间点和记录值。现在我们将使用curl运行一些基本示例与进行ifqld交互:

代码语言:javascript
复制
20:11 $ curl -XPOST --data-urlencode 'q=from(db:"NOAA_water_database").filter(exp:{"_measurement"=="h2o_temperature"}).range(start: -500000h).limit(n: 10)' http://localhost:8093/query       
h2o_temperature,location=coyote_creek degrees=60 1439856000000000000                           
h2o_temperature,location=coyote_creek degrees=65 1439856360000000000                           
h2o_temperature,location=coyote_creek degrees=68 1439856720000000000                           
h2o_temperature,location=coyote_creek degrees=62 1439857080000000000                           
h2o_temperature,location=coyote_creek degrees=62 1439857440000000000                           
h2o_temperature,location=coyote_creek degrees=69 1439857800000000000                           
h2o_temperature,location=coyote_creek degrees=67 1439858160000000000                           
h2o_temperature,location=coyote_creek degrees=67 1439858520000000000                           
h2o_temperature,location=coyote_creek degrees=70 1439858880000000000                           
h2o_temperature,location=coyote_creek degrees=65 1439859240000000000                           
h2o_temperature,location=santa_monica degrees=70 1439856000000000000                           
h2o_temperature,location=santa_monica degrees=60 1439856360000000000                           
h2o_temperature,location=santa_monica degrees=62 1439856720000000000                           
h2o_temperature,location=santa_monica degrees=62 1439857080000000000                           
h2o_temperature,location=santa_monica degrees=60 1439857440000000000                           
h2o_temperature,location=santa_monica degrees=63 1439857800000000000                           
h2o_temperature,location=santa_monica degrees=64 1439858160000000000                           
h2o_temperature,location=santa_monica degrees=63 1439858520000000000                           
h2o_temperature,location=santa_monica degrees=63 1439858880000000000                           
h2o_temperature,location=santa_monica degrees=61 1439859240000000000

让我们将from(db:"NOAA_water_database").filter(exp:{"_measurement"=="h2o_temperature"}).range(start: -500000h).limit(n: 10)

与InfluxQL 进行比较:

  • from有点像SQL的select。它选择database来查询。
  • 在 filter里面有一些特定的关键字被数据库自身使用,比如_measurement。在这种情况下,它通过测量h2o-temperature进行过滤。
  • limit(10)在这种情况下返回20行。为什么是这样?这是我们构建的查询语言的第一个差异。有一种隐式的说法是按照 group by *的方式分组。在这种情况下,有两个系列:h2o_temperature, location=sata_monica和 h20_temperature,location=coyote_creek。如果你需要一个特定的系列,你应该添加.filter(exp:{"_measurement"=="h2o_temperature" AND "location" == "coyote_creek"})

查询语言背后的一些重要决定:

  • 参数的功能顺序并不重要。每个参数都有一个名称,并不是强制性的。
  • 必须使用 ",以避免单引号和双引号之间的不匹配。

IFQL将每个查询从特定语法简化为JSON AST。您可以通过添加查询参数 analyze=true

来获取特定查询的AST 。

代码语言:javascript
复制
from(db:"NOAA_water_database").filter(exp:{"_measurement"=="h2o_temperature"}).range(start:
-500000h).limit(n: 10)

IFQL项目文档中的README.md包含所有其他可用的功能的说明。

可扩展性

ifqld是一个无状态的HTTP守护进程程序,因此它可以比InfluxDB(或其他数据库)更容易地扩展和缩减,因为不涉及任何状态或数据。一些功能,例如filters,被推送到引擎(并非所有情况下),因为InfluxDB能够检索时间序列和所有要求的点。

其他的一些功能,如聚合功能,不会推送到InfluxDB,但是一旦从数据库获取数据,ifqld 进程就会立即运行。这使我们能够以更灵活的方式扩展阅读和聚合。如果有更多的查询或更多的计算需求,我们可以启动更多的 ifqld进程,而不必关心底层存储。

可伸缩性的另一个重要方面就是 ifqld可以查询多个。

代码语言:javascript
复制
19:56 $ curl -s -XPOST --data-urlencode 'q=from(db:"NOAA_water_database").range(start: 200h).count()' http://localhost:8093/query?analyze=true | jq
{
  "operations": [
    {
      "id": "from0",
      "kind": "from",
      "spec": {
        "database": "NOAA_water_database",
        "hosts": null
      }
    },
    {
      "id": "range1",
      "kind": "range",
      "spec": {
        "start": "200h0m0s",
        "stop": "now"
      }
    },
    {
      "id": "count2",
      "kind": "count",
      "spec": {}
    }
  ],
  "edges": [
    {
      "parent": "from0",
      "child": "range1"
    },
    {
      "parent": "range1",
      "child": "count2"
    }
  ]
}

使用CLI参数--host=或环境变量$HOSTS可以指定多个后端。这意味着如果您运行的是开源版本,并且您可以在更多利用更多的数据库管理数据分片,还可以进行横向扩展。

路线图

该项目还不稳定,仍快速发展阶段。API和输出可以根据您和我们在查询语言方面的经历进行更改。这个想法是在2018年初固定API样式。如果您是一名活跃的InfluxDB用户,可以随时打开论坛或者提供有关您的使用的反馈信息,以帮助我们改进语法。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 架构
  • 可扩展性
  • 路线图
相关产品与服务
数据库
云数据库为企业提供了完善的关系型数据库、非关系型数据库、分析型数据库和数据库生态工具。您可以通过产品选择和组合搭建,轻松实现高可靠、高可用性、高性能等数据库需求。云数据库服务也可大幅减少您的运维工作量,更专注于业务发展,让企业一站式享受数据上云及分布式架构的技术红利!
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档