InfluxDB 通识篇

本文涉及的产品
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
云数据库 MongoDB,独享型 2核8GB
推荐场景:
构建全方位客户视图
RDS MySQL Serverless 高可用系列,价值2615元额度,1个月
简介: InfluxDB 通识篇

什么是时序数据库?


时序数据库全称时间序列数据库,英文名 Time Series DataBase,缩写 TSDB。

这种数据库专门用作处理时间序列数据。

那什么是时间序列数据呢?就是随着时间变化而源源不断产生的数据。

举个例子,Mac 电脑上的活动监视器就是一种时间序列数据,每隔几秒它都会获取电脑上各个部件最新的数据。

image.pngimage.pngimage.pngimage.pngimage.png


为什么需要时序数据库?


随着物联网和大数据时代的到来,全球每天产生的数据量大到令人难以想象。这些数据受到业务场景的限制分为不同的种类,每个种类对存储都有不同的要求。单凭传统的 RDBMS 很难完成各种复杂场景下的数据存储。

这时我们就需要根据不同的数据特性和业务场景的要求,选择不同的数据库。

一般选择使用哪个数据库,要从低响应时间(Low Response Time)、高可用性(High Availability)、高并发(High Concurrency)、海量数据(Big Data)和可承担成本(Affordable Cost)五个维度去权衡。

数据库的种类非常繁多,举几个常见的类型来对比一下各自的特点。

关系型数据库主流代表有 MySQL、Oracle 等,优点是具有 ACID 的特性,各方面能力都比较均衡。缺点是查询、插入和修改的性能都很一般。

KV 数据库主流带代表有 Redis、Memcached 等,优点是存储简单、读写性能极高。缺点是存储成本非常高,不适合海量数据存储。

文档型数据库最流行的是 MongoDB,相比 MySQL,数据结构灵活、更擅长存储海量数据,在海量数据的场景下读写性能很强。缺点是占用空间会很大。

搜索引擎数据库最流行的是 ElasticSearch,非常擅长全文检索和复杂查询,性能极强,并且天生集群。缺点是写入性能低、字段类型无法修改、硬件资源消耗严重。

而时序数据库,最初诞生的目的很大程度上是在对标 MongoDB,因为在时序数据库出现之前,存储时序数据这项领域一直被 MongoDB 所占据。

时序数据库一哥 InfluxDB 的公司 InfluxData,曾在 2018 年发表了一篇关于 InfluxDB vs MongoDB 的博客。文中使用 InfluxDB v1.7.2 和 MongoDB v4.0.4 做对比,得出 InfluxDB 比 MongoDB 快 2.4 倍的结论。当然可信度有待考量。

总之,时序数据库的特点是:持续高性能写入、高性能查询、低存储成本、支持海量时间线、弹性。


为什么选择 InfluxDB?


虽然时序数据库早在 13 年左右就已经出现,但真正流行的时间非常晚,一直到了 17、18 年才稍微普及,即使到了今天,时序数据库在 DB Engiens 的数据库排名中仍然很落后,最靠前的 InfluxDB 也仅仅排在了 28 位。

选择 InfluxDB 的原因非常简单,因为它目前是最流行的时序数据库。

InfluxDB 之所以能够从众多时序数据库中脱颖而出,除了自身强大以外,活跃的社区、合理的商业模式和营销功不可没。

image.png

既然时序数据库很好,为什么排名如此考后?原因是应用场景少,记录运维监控和物联网实时数据是时序数据库的用武之地。而大多数的系统使用 MySQL、MongoDB 和 Redis 这些主流数据库就可以很好地支撑。

除了 InfluxDB 以外,还有几个比较流行的时序数据库,比如基于 PostgreSQL 的 TimeScaleDB,目前排在 97 位。基于 HBase 的 OpenTSDB,排在 122 位。基于 Cassandra 的 KairosDB,目前排在 201 位。


InfluxDB 简介


InfluxDB 是 InfluxData 公司在 2013 年开源的数据库,是为了存储物联网设备、DevOps 运维这类场景下大量带有时间戳数据而设计的。

InfluxDB 源码采用 Go 语言编写,在 InfluxDB OSS 的版本中,部署方式上又分为两个版本,单机版和集群版。单机版开源,目前在 github 上有 21k+ star。集群版闭源,走商业路线。

个人认为单机版的 InfluxDB 比较鸡肋。因为一旦选择使 InfluxDB,那么数据量肯定一定达到了某个很高的程度。这时候必须使用集群版。而在数据量不够高的情况下,InfluxDB 并不会比 MongoDB 或者 ElasticSearch 有更明显的优势。

考虑到学习成本、简化上手难度,InfluxDB1.x 采用了一种类似 SQL 的 InfluxQL 语言来操作数据。2019 年 1 月推出了 InfluxDB2.0 alpha 版本。受到 2018 年最流行的脚本语言 JavaScript 影响,推出了全新的查询语言 Flux。并在 2020 年底推出了 InfluxDB 2.0 正式版本,该版本又分为两个系列,云模式的 InfluxDB Cloud 和独立部署的 InfluxDB OSS。

Flux 不是绑定在 InfluxDB 上的查询脚本语言,它是一个独立的项目,图灵完备,便于处理数据,也可以用作 InfluxDB 以外。

由于 InfluxDB 的流行程度不高,而且 2.0 版本也推出不久,所以在国内搜索到的很多 InfluxDB 相关资料都是在讲述 1.x 的内容,参考意义不大,目前最好的学习路径是 InfluxDB 官方文档。本文内容全部基于 InfluxDB OSS 2.0 版本。


TICK 与 InfluxDB


TICK 是 InfluxData 平台的组件集的缩写,分别代表四大组件:Telegraf(数据收集器)、InfluxDB(时序数据库)、Chronograf(可视化 UI)和 Kapacitor(监控服务)。

InfluxData 公司的愿景是帮助人们处理时序数据,仅依靠一个时序数据库是不够的,还需要解决因为时序数据自身产生的一系列问题。因此 InfluxData 决定设计并开发 TICK。

在早期 Kapacitor 的脚本语言是 TICKScript,但是并不好用,遭受到社区中很多人的诟病。因此出现了 Flux。Flux 的功能性比 InfluxQL 更强,比 TICKScript 更易用。

随着 Flux 的逐渐发展,InfluxDB 的能力范围也在逐步扩展。


基本概念


InfluxDB 的数据模型概念和 RDBMS 稍有不同,下面是和 MySQL 的概念对照表。

InfluxDB MySQL 解释
Buckets Database 数据桶-数据库,即存储数据的命名空间。
Measurement Table 度量-表。
Point Record 数据点-记录。
Field Field 未设置索引的字段。
Tag Index 设置了索引的字段。


安装部署


安装方式有好几种,这里介绍如何使用 Docker 进行安装。

首先从 Docker 拉取镜像:

然后快速创建容器:


docker run -d --name influxdb -p 8086:8086 influxdb

启动成功后访问 http://127.0.0.1:8086/ 就可以看到页面了。

image.png

之后填写初始化信息,完成初始化。

image.png


基本配置


将数据持久化到 Docker 容器之外


首先创建一个目录。


mkdir influxdb_docker_data_volume && cd $_

在这个目录下运行启动命令,并添加 volume 参数。


docker run -d --name influxdb -p 8086:8086 --volume $PWD:/root/.influxdbv2 influxdb

这样容器中的数据就会存储到当前目录。


写数据


InfluxDB 写数据的方式有两种,一是使用不同语言的客户端库,二是使用 Telegraf 插件。

这里介绍使用客户端库来进行写数据。

在 Load Data 页面上,有 Sources 标签,其中又有 Client Libraries 和 Telegraf Plugins 两个分类。

image.png

这里选择 Go 语言,点开后会有示例代码。

写数据最少需要 4 个基础信息。

  1. 组织 ID(org ID)
  2. 存储桶(bucket ID)
  3. 身份认证令牌(authentication token)
  4. 数据库地址(InfluxDB URL)

写数据的数据格式有两种,第一种是 InfluxDB Line Protocol 格式。


InfluxDB Line Protocol


完整代码如下:


package main
import (
  "fmt"
  influxdb2 "github.com/influxdata/influxdb-client-go/v2"
)
func main() {
  // You can generate a Token from the "Tokens Tab" in the UI
  const token = "vgqVL_p-qbSpQO0DIzU4QcRgaEyQM-wcEmK2cOkDUHAiQYwLOba7qEZr9Xcq3YvZ2UH-ovu9RG7XkMwChO6eeA=="
  const bucket = "test"
  const org = "lzq"
  client := influxdb2.NewClient("http://127.0.0.1:8086", token)
  // always close client at the end
  defer client.Close()
  // get non-blocking write client
  writeAPI := client.WriteAPI(org, bucket)
  // write line protocol
  writeAPI.WriteRecord(fmt.Sprintf("stat,unit=temperature avg=%f,max=%f", 23.5, 45.0))
  writeAPI.WriteRecord(fmt.Sprintf("stat,unit=temperature avg=%f,max=%f", 22.5, 45.0))
  // Flush writes
  writeAPI.Flush()
}

InfluxDB Line Protocol 本质上是一个具有约定格式的字符串。通过这个字符串形成一个记录,这个字符串必须包含一个测量(measurement)和一组字段(field),同时可能会包含 N 个标签(tag)和一个时间戳(timestamp)。

如果不附带时间戳,那么 InfluxDB 会使用其主机的当前系统时间,单位默认为纳秒。


Data Point


另一种是数据点(Data Point)的数据格式。

这种格式又分为两种风格的 API。

第一种风格是一个函数,传递 N 个参数。

示例代码:


p := influxdb2.NewPoint("stat",
  map[string]string{"unit": "temperature"},
  map[string]interface{}{"avg": 24.5, "max": 45},
  time.Now())
// write point asynchronously
writeAPI.WritePoint(p)

第二种风格是类似 DSL 的 API。

代码如下:


// create point using fluent style
p = influxdb2.NewPointWithMeasurement("stat").
  AddTag("unit", "temperature").
  AddField("avg", 23.2).
  AddField("max", 45).
  SetTime(time.Now())
// write point asynchronously
writeAPI.WritePoint(p)


删数据


InfluxDB 不支持修改数据,但是可以删除数据。

删数据的方式有两种,一种是 InfluxDB CLI,一种是 HTTP API。


InfluxDB CLI


运行 influx delete  命令即可删除数据,需要附带参数。

  1. bucket:指定某个数据桶。
  2. start 和 stop:指定删除的数据时间戳范围。
  3. predicate:可选项,删除符合某种条件的数据。

示例:


influx delete --bucket example-bucket \
  --start 2020-03-01T00:00:00Z \
  --stop 2020-11-14T00:00:00Z

带有条件的示例:


influx delete --bucket example-bucket \
  --start '1970-01-01T00:00:00Z' \
  --stop $(date +"%Y-%m-%dT%H:%M:%SZ") \
  --predicate '_measurement="example-measurement" AND exampleTag="exampleTagValue"'


HTTP API


和 CLI 的方式类似。调用 api/v2/delete  即可。

需要符合以下条件。

  1. 请求方式(Method):POST。
  2. 请求头(Headers):带有 Authorization  用于验证身份,请求格式为 application/json
  3. 查询参数(QueryParams):org/orgID,指定组织。bucket/bucketID,指定数据桶。
  4. 请求体(Body):start:表示开始时间,stop:表示结束时间,predicate(可选):表示删除条件。

请求示例:


curl --request POST http://localhost:8086/api/v2/delete/?org=example-org&bucket=example-bucket \
  --header 'Authorization: Token <YOURAUTHTOKEN>' \
  --header 'Content-Type: application/json' \
  --data '{
    "start": "2020-03-01T00:00:00Z",
    "stop": "2020-11-14T00:00:00Z"
  }'

我不建议在 InfluxDB 中对数据进行删除操作。

时序数据库更适合存储完整的原始数据,而经过分析和提炼后的价值更高的数据,可以存入 MongoDB 或者 MySQL。


读数据


InfluxDB 读数据的方式有 5 种。

  1. InfluxDB UI
  2. InfluxDB HTTP API
  3. Flux REPL
  4. InfluxDB CLI
  5. Client libraries

这里介绍第 5 种,使用客户端的方式来读取数据。

下面是代码演示:


client := influxdb2.NewClient(url, token)
defer client.Close()
query := fmt.Sprintf("from(bucket:\"%v\")|> range(start: -1h) |> filter(fn: (r) => r._measurement == \"stat\")", bucket)
// Get query client
queryAPI := client.QueryAPI(org)
// get QueryTableResult
result, err := queryAPI.Query(context.Background(), query)
if err == nil {
    // Iterate over query response
    for result.Next() {
        // Notice when group key has changed
        if result.TableChanged() {
            fmt.Printf("table: %s\n", result.TableMetadata().String())
        }
        // Access data
        fmt.Printf("value: %v\n", result.Record().Value())
    }
    // check for an error
    if result.Err() != nil {
        fmt.Printf("query parsing error: %\n", result.Err().Error())
    }
} else {
    panic(err)
}

其中关键的是第 3 行名为 query 的字符串变量,它是使用 flux 语法编写的一段脚本。


from(bucket:"test")
  |> range(start: -1h)
  |> filter(fn: (r) => r._measurement == "stat")

from  表示从哪个数据源检索数据。

range  表示根据时间范围过滤数据。start: -1 表示当前时间减掉 1 个小时。

filter  表示自定义过滤条件,其中 fn 是一个函数,在函数内定义规则,语法和 JavaScript 中 Array 的 filter 函数极其类似。

|>  表示管道前移符,将数据通过管道的形式传递到下一个操作中。

篇幅所限,关于 InfluxDB 2.0 的概念和基本使用暂时就介绍到这里。更多关于 InfluxDB 架构、Flux、数据处理、数据可视化、监控告警、最佳实践等内容,会在接下来的文章中进行介绍。



相关文章
|
存储 SQL 前端开发
InfluxDB在项目中的实践
InfluxDB在实际项目中的使用步骤以及各种踩坑避雷。
InfluxDB在项目中的实践
|
存储 数据库 时序数据库
InfluxDB基本操作
InfluxDB基本操作
664 0
|
存储 数据采集 Java
InfluxDB 的学习笔记
在Java项目中实现InfluxDB的落地应用,主要包括添加InfluxDB的Java客户端依赖、创建数据库连接、执行数据的增删改查操作等步骤
726 2
|
5月前
|
存储 监控 关系型数据库
InfluxDB 时序数据的高效解决方案
InfluxDB 是一种专为时间序列数据优化的开源数据库,支持高效存储、检索和分析大量时序数据。它采用 Tag-Key-Value 模型,提供高性能写入与查询能力,适合监控系统、物联网设备数据及实时分析等场景。相比传统关系型数据库(如 MySQL),InfluxDB 针对时序数据进行了架构优化,具备无模式设计、自动数据管理及灵活扩展性等优势。本文通过 Go 语言代码实战展示了如何连接、写入和查询 InfluxDB 数据,并介绍了其核心概念与应用场景,助力开发者快速上手时序数据库开发。
1018 0
InfluxDB 时序数据的高效解决方案
|
存储 监控 关系型数据库
InfluxDB入门:基础概念解析
【4月更文挑战第30天】InfluxDB是开源时序数据库,擅长处理实时数据,常用于监控和分析。本文介绍了其基础概念:数据库(数据容器)、测量值(类似表)、字段(数据值)、标签(元数据)、时间戳和数据点。InfluxDB特性包括高性能写入、灵活查询(InfluxQL和Flux)、可扩展性及活跃社区支持。了解这些概念有助于更好地使用InfluxDB处理时间序列数据。
|
SQL JSON 数据库
influxdb 端点使用http进行sql查询,写数据
influxdb 端点使用http进行sql查询,写数据
768 0
|
存储 数据库 时序数据库
InfluxDB的安装与Python调用
InfluxDB是一个高性能的时序数据库(Time-Series Database, TSDB),用于存储和分析时间序列数据的开源数据库,它非常适合于处理大量的时间戳数据,如金融市场数据、IoT 设备数据、监控数据等,尤其适合处理大量的时序数据和高频数据。 主要特性有: • 内置HTTP接口,使用方便 • 数据可以打标记,查询可以很灵活 • 类SQL的查询语句 • 安装管理很简单,并且读写数据很高效 • 能够实时查询,数据在写入时被索引后就能够被立即查出
InfluxDB的安装与Python调用
|
存储 监控 Java
InfluxDB时序数据库安装和使用
InfluxDB时序数据库安装和使用
902 2
|
SQL 时序数据库
influxdb 进行数据删除和修改
influxdb 进行数据删除和修改
2582 5
|
存储 数据采集 监控
InfluxDB:开启你的高性能读写数据之旅!
InfluxDB:开启你的高性能读写数据之旅!
919 0