当前位置: 欣欣网 > 码农

开源时序数据库 InfluxDB

2024-06-02码农

为什么是InfluxDB?

在选择时间序列数据库时,最重要的考虑因素是存储和查询性能、存储空间效率和灵活的可扩展性,而InfluxDB似乎是一个不错的选择。从时间序列数据库相关的趋势数据来看,它已经超越了以前常用的RRDTool和Graphite,以压倒性的速度增长

数据来源:https://db-engines.com/en/ranking/time+series+dbms

数据来源:https://db-engines.com/en/ranking_trend/system/InfluxDB

数据来源:https://db-engines.com/en/ranking_trend/time+series+dbms

简介

InfluxDB是一个开源的时序数据库,使用GO语言开发,特别适合用于处理和分析资源监控数据这种时序相关数据。而InfluxDB自带的各种特殊函数如求标准差,随机取样数据,统计数据变化比等,使数据统计和实时分析变得十分方便。

InfluxDB的单机版是开源的,而集群版是商业版,InfluxDB被设计运行在SSD上,如果使用机器或者网络磁盘作为存储介质,会导致性能下降至少一个数量级。InfluxDB支持 Restful api ,同时也支持https,为了保证安全性,非局域网建议使用https与Influxdb进行通信。

使用场景

InfluxDB 是一种时序数据库,时序数据库通常被用在监控场景,比如运维和 IOT(物联网)领域。这类数据库旨在存储时序数据并实时处理它们。

比如:我们可以写一个程序将服务器上 CPU 的使用情况每隔 10 秒钟向 InfluxDB 中写入一条数据。接着,我们写一个查询语句,查询过去 30 秒 CPU 的平均使用情况,然后让这个查询语句也每隔 10 秒钟执行一次。最终,我们配置一条报警规则,如果查询语句的执行结果 >xxx 满足条件,就立刻触发报警。

上述就是一个指标监控的场景,在 IOT 领域中,也有大量的指标需要我们监控。比如:机械设备的轴承震动频率,农田的湿度温度等等。

为什么不用关系型数据库

写入性能

关系型数据库也是支持时间戳的,也能够基于时间戳进行查询。但是,从我们的使用场景出发,需要注意数据库的写入性能。通常,关系型数据库会采用 B+树 数据结构,在数据写入时,有可能会触发叶裂变,从而产生了对磁盘的随机读写,降低写入速度。

当前市面上的时序数据库通常都是采用 LSM Tree 的变种,顺序写磁盘来增强数据的写入能力。网上有不少关于性能测试的文章,同学们可以自己去参考学习,通常时序数据库都会保证在单点每秒数十万的写入能力。

数据价值

时序数据库一般用于指标监控场景。这个场景的数据有一个非常明显的特点就是冷热差别明显。通常,指标监控只会使用近期一段时间的数据,比如我只查询某个设备最近 10 分钟的记录,10 分钟前的数据我就不再用了。那么这 10 分钟前的数据,对我们来说就是冷数据,应该被压缩放到磁盘里去来节省空间。而热数据因为经常要用,数据库就应该让它留在内存里,等待查询。而市面上的时序数据库大都有类似的设计。

时间不可倒流,数据只写不改

时序数据是描述一个实体在不同时间所处的不同状态。

就像是打开任务管理器,查看 CPU 的使用情况。发现 CPU 占用率太高了,于是杀死了一个进程,但 10 秒前的数据不会因为我关闭进程再发生改变了。

这是时序数据的一大特点。与之相应,时序数据库基本上是插入操作较多,而且还没有什么更新需求。

存储

InfluxDB中存储的是时间序列数据,比如说某个时间点系统负载、服务耗时等信息,时间序列数据可以包含多个值。关于什么是时间序列数据,简单来来说就是数据是和一个时间点关联的,结合MySQL中的记录与id关系来看就是时间序列数据的主键就是时间点(timestrap)。

InfluxDB中的一条数据至少包括 measurement (对应mysql中表概念)、 timestamp 、至少 一个k-v结构的field ,再加上0个或者多个k-v结构的tag。

对比MySQL来看, measurement 就是一张表,其主键是 timestamp 时间戳, tag field 对应就是表中列, tag field 都是 k-v 接口, k 对应列的名字, v 对应该列存储的值, tag field 不同的是, tag 是有索引的而 field 没有(如果查询条件为tag则会扫描所有查询到的数据),对于mysql表的有索引列和无索引列。

注意:MySQL中的表需要提前定义结构,而influxdb中的measurement无需提前定义,其null值也不会被存储。

InfluxDB中measurement无需定义,即无模式设计,开发者可以在任意添加measurement,tags和fields,不过针对同一个field,第二次和第一次写入的数据类型不匹配,InfluxDB会报错(由于默认tag的v都是字符串类型,所有不存在这个问题,不管输入是什么数据都当做字符串来处理)。

理论和原理

InfluxDB 行协议

Telegraf的内部数据结构叫做InfluxDB行协议。如下图所示:

Telegraf本身是InfluxData公司专门为InfluxDB开发的数据采集器。上面这种数据格式是InfluxDB数据库使用的,只要数据符合上面这种格式,就能通过InfluxDB的API将数据导入数据库。所以,自家的插件当然支持自家的生态了,InfluxDB。

与 CSV 相似,在 InfluxDB 行协议中,一条数据和另一条数据之间使用换行符分隔,所以一行就是一条数据。另外,在时序数据库领域,一行数据一行数据由下面 4 种元素构成。

  • measurement(测量名称)

  • Tag Set(标签集)

  • Field Set(字段集)

  • Timestamp(时间戳)

  • 安装部署

    拉取镜像

    docker pull influxdb

    启动influxdb容器

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

    通过地址: http://127.0.0.1:8086 访问

    初始化用户

    进入容器

    docker exec -it 8e1e2f1f174cb4f6696685bf0bdf2bc28ce68b23744c07880ed78198e9e18f30 sh

    PHP客户端集成

    官方提供了很多语言的集成方式,这里我们以PHP为例,其他语言,可以在下图位置查看

    通过composer安装

    composer require influxdata/influxdb-client-php guzzlehttp/guzzle

    初始化客户端 influxdb.php

    <?php
    /**
     * @desc influxdb.php 描述信息
     * @author Tinywan(ShaoBo Wan)
     * @date 2024/6/2 9:45
     */
    declare(strict_types=1);
    require_once '../vendor/autoload.php';
    use InfluxDB2\Client;
    use InfluxDB2\Model\WritePrecision;
    /** 创建接口令牌 */
    $token = 'Kmdv_gAm2EEWDpPCBdC4cTbkT_rUa1UsDBNvhTh1cn0Sc7P0emgtsIL35hRlV0XSKQLSVesC4MEuViDN55bCug==';
    $org = '开源技术小栈';
    $bucket = 'resty';
    /** 初始化客户端 */
    $client = new Client([
    "url" => "http://192.168.3.29:8086",
    "token" => $token
    ]);
    /** 写入数据 */
    $writeApi = $client->createWriteApi();
    $data = "mem,host=host1 used_percent=23.43234543";
    $writeApi->write($data, WritePrecision::S, $bucket$org);
    /** 执行查询 */
    $query = "from(bucket: \"resty\") |> range(start: -1h)";
    $tables = $client->createQueryApi()->query($query$org);
    foreach ($tables as $table) {
    foreach ($table->records as $record) {
    $time = $record->getTime();
    $measurement = $record->getMeasurement();
    $field = $record->getField();
    $value = $record->getValue();
    print"$time$measurement$field=$value\n";
    }
    }





    执行脚本 influxdb.php

    php influxdb.php 
    // 数据查询结果
    2024-06-02T01:58:41Z mem: used_percent=23.43234543

    浏览写入数据