时序数据库的何、为何和如何

导航至

本文由Thamatam Vijay Kumar撰写。向下滚动以查看作者简介和照片。

现代网站充满了各种包含丰富图表、折线图、雷达图以及多图组合的仪表盘。世界对这样的图表和图形着迷,它们为千禧一代的Web应用程序提供了巨大的价值。有许多这样的图表库,它们提供交互式可视化并为用户提供数据洞察。

这些图表使用数据点绘制线条。这些图表库帮助我们分析从几分钟到数年的数百万个数据点,并通过工具提示、图例和聚合显示额外信息。

Example-of-a-multigraph-showing-car-engine-data-for-every-minute-ranging-for-a-day

一个多图示例,显示一天内每分钟的汽车引擎数据

上述示例显示了图表显示数千个数据点的功能,帮助用户更智能化地分析引擎数据,了解引擎状况。

在这篇文章中,我们将介绍如何存储和查询时序数据,这是现代图表的主要数据源。

什么是时序数据?

时序数据是在特定时间间隔内收集的一系列数据点,使我们能够跟踪变量的变化。时序数据是按时间顺序或按时间序列对变量进行观察的序列。

由于时序数据中的数据点在不同的时间收集,因此观察结果之间存在潜在的关联性。这是时序数据与其他数据区别开来的一个特点。

时序数据可用于金融、医疗、制造、物联网、物理科学等领域。

例如包括

  • 公司的股票价值
  • 患者的各种健康参数(如血压、血糖、氧气)的健康监测值
  • 各种汽车引擎传感器的值,如速度、扭矩、机油、冷却液
  • 智能家庭监控器以调节温度和识别入侵者

以下是在时序格式中的汽车引擎传感器样本数据

sample-data

如上所示,这些数据是关于汽车引擎在不同间隔的多个传感器的。这些数据帮助我们理解和分析引擎在不同时间范围内的状况。

何时使用时序数据

但何时我们可以使用时序数据,在什么用例中我们在时序数据库中存储数据?

如上所述,当你有一个连续的数据流来存储一段时间内或不同时间戳的值时,这些应用程序需要一种特殊的数据库。

常见的时间序列数据库应用场景包括

  1. 访问物联网数据(引擎、智能设备等)
  2. 监控网络服务、应用程序和基础设施
  3. 金融交易
  4. 自动驾驶汽车数据
  5. 自主交易算法
  6. 零售行业配送

此外,如果您预计需要存储任何数据流,并且需要连续的时间戳以及不同值,那么专门用于存储时间序列数据的数据库是最合适的。

您可能会问:为什么我们不能将数据存储在关系数据库而不是时间序列数据库中?(请参阅)

为什么使用时间序列数据库

随着时间的推移,时间戳数据的量持续增长,在常规数据库中存储连续数据流变得困难。

我们在观察物理世界中的每一个可用外部设备——汽车、医疗仪器、发电厂、电话、家用电器、人体等等。每一件事都有,或者将会有,一个传感器不断地发出时间序列数据。这需要一个能够处理如此大量数据的平台。

假设传感器每秒发送数据,您拥有10000台发动机,每台发动机有100个传感器值。这将导致数据库中存储超过80亿条记录。在一个月或一年的时间内,在传统数据库中存储如此大量的数据变得不可能,查询数据库以进行简单的查询(例如,获取一年的10个传感器的数据)也变得不可能。这就是为什么世界正在竞相采用时间序列数据库来存储和检索数据,用于时间序列用例和连续数据流。

时间序列数据库的两种替代品是 RDBMSNoSQL

关系数据库管理系统(RDBMS)可以用来存储和检索时间序列数据。由于RDBMS的灵活性,它们可以像TSDB一样存储相同的数据。一个关键的区别是,RDBMS没有针对时间序列数据进行优化,并且在数据量不断增长的情况下,插入和检索时间序列数据的速度会变慢,如上述示例中所述。

另一种类型的数据库,NoSQL,也常用于存储时间序列数据。由于NoSQL数据库在每条记录的数据格式方面更加灵活,它们适合从多个不同的来源捕获时间序列数据。然而,查询NoSQL数据库意味着仔细检查模式并针对它编写自定义查询。像不同类型的连接这样的复杂操作,在SQL方面的创新已经持续了几十年,在NoSQL领域可能会很慢,甚至有缺陷。

选择时间序列数据库

现在我们已经介绍了时间序列的什么是和为什么,让我们比较一下市场上的一些流行的时间序列数据库,以及如何存储和检索连续数据流的数据。

  1. InfluxDB
  2. Graphite
  3. OpenTSDB
  4. TimescaleDB
名称 InfluxDB    Graphite    OpenTSDB    TimescaleDB   
描述 存储时间序列指标和事件的数据库管理系统 时间序列数据的日志记录和绘图工具 基于HBase的可扩展时间序列DBMS 一个基于PostgreSQL,针对快速摄取和复杂查询优化的时间序列数据库
主要数据库模型 时间序列数据库管理系统 时间序列数据库管理系统 时间序列数据库管理系统 时间序列数据库管理系统
二级数据库模型 空间数据库管理系统  关系数据库管理系统
仅基于云
实现语言 Go Python Java C
数据模式 无模式 无模式
类型 数值数据和字符串 仅数值数据 数值数据用于指标,字符串用于标签 数值、字符串、布尔值、数组、JSON blob、地理空间维度、货币、二进制数据,其他复杂数据类型
XML支持
二级索引
查询语言 类似SQL的查询语言
API和其他访问方法 HTTP API JSON over UDP HTTP API Sockets HTTP API Telnet API ADO.NET JDBC 本地C库 ODBC 大对象流式API
支持的编程语言 .Net, Clojure, Erlang, Go, Haskell, Java, JavaScript, JavaScript (Node.js), Lisp, Perl, PHP, Python, R, Ruby, Rust, Scala JavaScript (Node.js), Python Erlang, Go, Java, Python R, Ruby .Net, C, C++, Delphi, Java, JavaScript, Perl, PHP, Python, R, Ruby, Scheme, Tcl
服务器端脚本 用户定义函数、PL/pgSQL、PL/Tcl、PL/Perl、PL/Python、PL/Java、PL/PHP、PL/R、PL/Ruby、PL/Scheme、PL/Unix shell
触发器
分区方法 分片 分片 是,跨时间和空间(哈希分区)属性

评估时间序列数据库以适应您的工作负载时,需要考虑几个因素

  • 数据模型
  • 查询语言
  • 可靠性
  • 性能
  • 生态系统
  • 运维管理和支持

通常,数据库评估基于性能目标。然而,性能只是整体评估的一部分。如果数据库在其数据模型、查询语言或您生产工作负载所需的可靠性方面存在不足,它将无法高效运行。上述表格比较了时间序列数据库在定性维度(数据模型、查询语言和可靠性)上的表现。

目前,在时间序列数据库不断增长的市场中,InfluxDB因其全面的时间序列数据库特性而脱颖而出。凭借良好的技术文档,安装、配置和使用InfluxDB非常简单。由于它是一种类似NoSQL的数据库,我们可以直接插入数据。

在做出决定之前,退后一步,研究您的堆栈、您团队的技能以及您现在和未来的需求。

如何存储和查询时间序列数据

让我们来看看如何在InfluxDB中存储和查询时间序列数据。

存储数据

下载安装InfluxDB。(注意,撰写本文时,最新版本是InfluxDB 2.2)。

一旦InfluxDB安装并设置好用户权限,我们就可以写入和查询数据。

在写入InfluxDB之前,了解一些关键术语非常重要

  • 测量:InfluxDB数据结构的一部分,用于描述存储在相关字段中的数据

  • 标签:严格来说,标签是可选的,但大多数序列都包含标签以区分数据源,并使查询既简单又高效。标签键和标签值都是字符串。

  • 字段(必需):字段键是必需的,始终是字符串;默认情况下,字段值是浮点数。

  • 时间戳:在行尾提供,以纳秒为单位表示自1970年1月1日UTC以来的Unix时间 - 是可选的。如果您未指定时间戳,InfluxDB将使用服务器的本地纳秒Unix纪元时间戳。InfluxDB的时间默认为UTC格式。

如果您是时间序列数据库的新手,这些术语可能有点难以理解,因此这里有一个解释

InfluxDB的测量值类似于SQL数据库表。
InfluxDB的标签类似于SQL数据库中的索引列。
InfluxDB的字段类似于SQL数据库中的非索引列。
InfluxDB的点类似于SQL行。

InfluxDB提供了几种机制来写入和查询数据。

  1. Telegraf插件

  2. InfluxDB API

  3. Influx命令行

在这里,我们使用API机制,通过提供的写入端点来写入和存储数据

/write HTTP端点

POST https://127.0.0.1:8086/write

我们可以使用上述API将数据写入InfluxDB。写入数据的语法如下:‘测量值, 标签键 = ’标签值’, 字段键 = ’字段值’, 纪元时间戳‘。

$ curl -i -XPOST "https://127.0.0.1:8086/write?db=mydb" --data-binary 'enginespeed,serialnumber=10001 value=129 1463689152000000000
 enginespeed,serialnumber=10001 value=84 1463689152000000000
 enginespeed,serialnumber=10001 value=79 1463689152000000000
 torque,serialnumber=10001 value=11 1463689152000000000
 torque,serialnumber=10001 value=23 1463689152000000000
 torque,serialnumber=10001 value=32 1463689152000000000
 power,serialnumber=10001 value=1200 1463689152000000000
 power,serialnumber=10001 value=1100 1463689152000000000
 power,serialnumber=10001 value=1000 1463689152000000000

HTTP/1.1 204 No Content
Content-Type: application/json
Request-Id: [...]
X-Influxdb-Version: 1.4.x
Date: Wed, 08 Nov 2017 18:04:02 GMT

此写入将数据插入多个测量值(发动机速度、扭矩、功率)中。

在这里,我们正在保存一系列纪元时间戳与汽车发动机值相关的数据。

这样,我们可以将连续数据流存储到InfluxDB中,以供进一步查询。

同样,也可以使用CLI和Telegraf插件将数据写入InfluxDB。

查询数据

将数据写入InfluxDB后,可以使用查询端点执行简单的InfluxDB查询

/query HTTP端点

GET https://127.0.0.1:8086/query

我们可以使用上述API从InfluxDB查询数据;写入数据的语法如下

‘测量值, 标签键 = ’标签值’, 字段键 = ’字段值’, 纪元时间戳‘。

$ curl -G 'https://127.0.0.1:8086/query?db=mydb' --data-urlencode 'q=SELECT * FROM "enginespeed"'

结果可以以以下所示JSON格式检索

"results": [
        {
            "statement_id": 0,
            "series": [
                {
                    "name": "engiespeed",
                    "columns": [
                        "time",
                        "value",
                        "serialnumber"
                    ],
                    "values": [
                        [
                            "2017-03-01T00:16:18Z",
                            129,
                            10001
                        ],
                        [
                            "2017-03-01T00:17:18Z",
                            84,
                            10001
                        ],
                        [
                            "2017-03-01T00:17:18Z",
                            79,
                            10001
                        ]

                    ]
                }
            ]
        }
    ]
}

我们也可以在查询中执行所有聚合和分组,以检索所需的数据。一个包含选择和聚合子句的示例查询如下所示

选择与字段键相关联的最大字段值,并包含多个子句

> SELECT MAX("water_level") FROM "h2o_feet" WHERE time >= '2015-08-17T23:48:00Z' AND time <= '2015-08-18T00:54:00Z' GROUP BY time(12m)

name: h2o_feet
tags: location=coyote_creek
time                   max
----                   ---
2015-08-17T23:48:00Z   9.01
2015-08-18T00:00:00Z   8.12
2015-08-18T00:12:00Z   7.887
2015-08-18T00:24:00Z   7.635

这样,我们可以根据需要使用不同的子句执行查询,并以时间序列格式获取数据。如开头所示,可以使用相同的数据通过数据绘制各种图表,这可以用于生成对该数据的更多见解和预测。此外,这些数据还可以用于故障排除和理解指标和事件的流。

在这篇文章中,我试图通过InfluxDB为例,介绍时间序列数据库的什么是、为什么和怎么做。专家们认识到时间序列数据库的兴起需求,我建议更多地了解时间序列,因为以时间序列格式存储您的项目可能是一个变革。

关于作者

Thamatam-Vijay-Kumar

Thamatam Vijay Kumar是博世的数据架构师,拥有11年以上的云解决方案和数据管理经验。他热衷于构建解决方案和产品,并渴望为其进行架构设计。他主要参与了云服务和数据管理相关技术的多个项目,并参与了设计、开发和部署解决方案的工作。