-
Docker安装InfluxDB1.x和InfluxDB2.x以及与SpringBoot整合
两者区别:
1.x 版本使用 influxQL 查询语言,2.x 和 1.8+(beta) 使用 flux 查询语法;相比V1 移除了database 和 RP,增加了bucket。 V2具有以下几个概念: timestamp、field key、field value、field set、tag key、tag value、tag set、measurement、series、point、bucket、bucket schema、organization 新增的概念: bucket:所有 InfluxDB 数据都存储在一个存储桶中。一个桶结合了数据库的概念和存储周期(时间每个数据点仍然存在持续时间)。一个桶属于一个组织 bucket schema:具有明确的schema-type的存储桶需要为每个度量指定显式架构。测量包含标签、字段和时间戳。显式模式限制了可以写入该度量的数据的形状。 organization:InfluxDB组织是一组用户的工作区。所有仪表板、任务、存储桶和用户都属于一个组织。
本文所有代码:https://github.com/Tom-shushu/InfluxDB1.xAnd2.x-SpringBoot
新得阅读地址:http://www.zhouhong.icu/post/161
一、InfluxDB1.x Docker安装以及与Boot整合
A、docker安装InfluxDB1.x (influxdb1.8.4)
1、安装:
docker run -d --name influxdb -p 8086:8086 influxdb:1.8.4
2、查看
docker ps -a
3、进入docker的influx中
docker exec -it daf88772adc9 /bin/bash
4、直接输入influx启动
influx
5、修改账户密码
# 显示用户 SHOW USERS # 创建用户 CREATE USER "username" WITH PASSWORD 'password' # 赋予用户管理员权限 GRANT ALL PRIVILEGES TO username # 创建管理员权限的用户 CREATE USER <username> WITH PASSWORD '<password>' WITH ALL PRIVILEGES # 修改用户密码 SET PASSWORD FOR username = 'password' # 撤消权限 REVOKE ALL ON mydb FROM username # 查看权限 SHOW GRANTS FOR username # 删除用户 DROP USER "username"
6、在配置文件启用认证
默认情况下,influxdb的配置文件是禁用认证策略的,所以需要修改设置一下。
编辑配置文件vim /etc/influxdb/influxdb.conf,把 [http] 下的 auth-enabled 选项设置为 true
7、设置保存策略(多长时间之前的数据需要删除)---默认为 autogen 永久不删除
a、查看数据库的保存策略
show retention policies on 数据库名
例子:
# 选择使用telegraf数据库 > use influx_test; Using database influx_test # 查询数据保存策略 > show retention policies on influx_test name duration shardGroupDuration replicaN default ---- -------- ------------------ -------- ------- autogen 0s 168h0m0s 1 true
name 策略名称:默认autogen
duration 持续时间: 0s 代表无限制
shardGroupDuration shardGroup数据存储时间:shardGroup是InfluxDB的一个基本存储结构, 应该大于这个时间的数据在查询效率上应该有所降低。
replicaN 副本个数:1 代表只有一个副本
default 是否默认策略:true 代表设置为该数据库的默认策略
b、设置保存策略
# 新建一个策略 CREATE RETENTION POLICY "策略名称" ON 数据库名 DURATION 时长 REPLICATION 副本个数; # 新建一个策略并且直接设置为默认策略 CREATE RETENTION POLICY "策略名称" ON 数据库名 DURATION 时长 REPLICATION 副本个数 DEFAULT;
例子:
# 创建新的默认策略role_01保留数据时长1小时 > CREATE RETENTION POLICY "1hour" ON influx_test DURATION 1h REPLICATION 1 DEFAULT;
c、修改保存策略
ALTER RETENTION POLICY "策略名称" ON "数据库名" DURATION 时长 ALTER RETENTION POLICY "策略名称" ON "数据库名" DURATION 时长 DEFAULT
d、删除保存策略
drop retention POLICY "策略名" ON "数据库名"
8、使用桌面可视化工具连接数据库
工具链接:https://github.com/CymaticLabs/InfluxDBStudio/releases/download/v0.2.0-beta.1/InfluxDBStudio-0.2.0.zip
如果刚才没有设置密码,这里可以不需要填写密码,如果有账号密码则需要勾上下面的Use SSL
连接成功后如下:
B、InfluxDB1.x与Spring整合(只列举部分代码,后面会放上整个项目的GitHub地址)
整个项目结构如下:
1、引入依赖 (其他依赖未显示全,后面会放上整个项目的GitHub地址)
<dependency> <groupId>com.influxdb</groupId> <artifactId>influxdb-client-java</artifactId> <version>4.0.0</version> </dependency> <dependency> <groupId>org.influxdb</groupId> <artifactId>influxdb-java</artifactId> <version>2.20</version> </dependency>
2、新建yml文件
influx: url: 'http://xxx.xx.xxx.xx:8086' password: 'password' username: 'username'
3、连接配置 InfluxDBConfig
@Data @Configuration @ConfigurationProperties(prefix = "influx") public class InfluxDBConfig { private String url; private String username; private String password; /** * description: 用于查询 * date: 2022/1/20 23:11 * author: zhouhong * @param * @param null * @return */ @Bean(destroyMethod = "close") public InfluxDB influxDBClient(){ return InfluxDBFactory.connect(this.url, this.username, this.password); } /** * description: 用于写入 * date: 2022/1/20 23:12 * author: zhouhong * @param * @param null * @return */ @Bean(name = "influxDbWriteApi",destroyMethod = "close") public WriteApi influxDbWriteApi(){ InfluxDBClient influxDBClient = InfluxDBClientFactory.createV1(this.url, this.username, this.password.toCharArray(), "influx_test", "autogen"); return influxDBClient.getWriteApi(); } }
4、封装用于查询的方法
@Component public class InfluxUtil { /** * description: 通用查询 * date: 2022/1/20 23:13 * author: zhouhong * @param * @param null * @return */ public QueryResult query(String command, String database, InfluxDB influxDB) { Query query = new Query(command, database); return influxDB.query(query); } }
5、新建需要写入的数据的实体类、需要返回的类(省略,具体参考github示例)InsertParams.java InfluxResult.java
6、新建server层和impl实现类
InfluxServiceImpl.java 如下:
/** * description: 时序数据库Impl * date: 2022/1/16 20:47 * author: zhouhong */ @Service @Slf4j public class InfluxServiceImpl implements InfluxService { @Resource(name = "influxDbWriteApi") private WriteApi influxDbWriteApi; @Resource(name = "influxDBClient") private InfluxDB influxDBClient; @Autowired private InfluxUtil influxUtil; @Override public void insert(InsertParams insertParams) { influxDbWriteApi.writeMeasurement(WritePrecision.MS, insertParams); } @Override public Object queryAll(InsertParams insertParams) { List<InfluxResult> list = new ArrayList<>(); InfluxResult influxResult = new InfluxResult(); String sql = "SELECT * FROM \"influx_test\" WHERE time > '2022-01-16' tz('Asia/Shanghai')"; QueryResult queryResult = influxUtil.query(sql, "influx_test", influxDBClient); queryResult.getResults().get(0).getSeries().get(0).getValues().forEach(item -> { influxResult.setTime(item.get(0).toString()); influxResult.setCurrent(item.get(1).toString()); influxResult.setEnergyUsed(item.get(2).toString()); influxResult.setPower(item.get(3).toString()); influxResult.setVoltage(item.get(4).toString()); list.add(influxResult); }); return list; } @Override public Object querySumByOneDay(InsertParams insertParams) { String sql = "SELECT SUM(voltage) FROM \"influx_test\" WHERE time > '2022-01-18' GROUP BY time(1d) tz('Asia/Shanghai')"; QueryResult queryResult = influxUtil.query(sql, "influx_test", influxDBClient); return queryResult.getResults().get(0).getSeries().get(0); } }
7、controller层 InfluxDbController.java(返回结果是封装过后的,详情见github示例)
@RestController public class InfluxDbController { @Autowired private InfluxService influxService; /** * description: 时序数据库插入测试 * date: 2022/1/16 23:00 * author: zhouhong * @param * @param null * @return */ @PostMapping("/influxdb/insert") public ResponseData insert(@RequestBody InsertParams insertParams) { influxService.insert(insertParams); return new SuccessResponseData(); } /** * description: 时序数据库查询全部数据测试 * date: 2022/1/16 23:00 * author: zhouhong * @param * @param null * @return */ @PostMapping("/influxdb/queryAll") public ResponseData query(@RequestBody InsertParams insertParams) { return new SuccessResponseData(influxService.queryAll(insertParams)); } /** * description: 时序数据库按天查询当前电压总和测试 * date: 2022/1/16 23:00 * author: zhouhong * @param * @param null * @return */ @PostMapping("/influxdb/queryByOneDay") public ResponseData queryByOneDay(@RequestBody InsertParams insertParams) { return new SuccessResponseData(influxService.querySumByOneDay(insertParams)); } }
8、PostMan测试(注意需要先新建一个 数据库---influx_test)
8.1 插入测试 localhost:9998/influxdb/insert
入参:
{ "energyUsed":243.78, "power":54.50, "current":783.34, "voltage":44.09 }
返回:
{ "success": true, "code": 200, "message": "请求成功", "localizedMsg": "请求成功", "data": null }
8.2、查询全部(注意,这里返回结果我封装了一下)localhost:9998/influxdb/queryAll
入参:
{
}
返回:
{ "success": true, "code": 200, "message": "请求成功", "localizedMsg": "请求成功", "data": [ { "energyUsed": "243.78", "power": "54.5", "current": "783.34", "voltage": "44.09", "time": "2022-01-20T23:44:00.626+08:00" }, { "energyUsed": "243.78", "power": "54.5", "current": "783.34", "voltage": "44.09", "time": "2022-01-20T23:44:00.626+08:00" } ] }
8.3聚合查询(统计2022-01-18到现在,以天为单位每天的用电量之和) localhost:9998/influxdb/queryByOneDay 精度问题暂时没处理
入参:
{ }
返回:
{ "success": true, "code": 200, "message": "请求成功", "localizedMsg": "请求成功", "data": { "name": "influx_test", "tags": null, "columns": [ "time", "sum" ], "values": [ [ "2022-01-18T00:00:00+08:00", null ], [ "2022-01-19T00:00:00+08:00", null ], [ "2022-01-20T00:00:00+08:00", 481.07000000000005 ] ] } }
C、常见的查询SQL 后面加上 tz('Asia/Shanghai') 解决时区差
1、查所指定时间之后的所有
SELECT * FROM "real_water_amount" where time > '2022-01-01' tz('Asia/Shanghai')
2、查询平均值 mean()
SELECT mean(value) FROM "real_water_amount" where time > '2022-01-01' tz('Asia/Shanghai')
3、查询最大最小值 max() min()
SELECT max(value) FROM "real_water_amount" where time > '2022-01-01' tz('Asia/Shanghai')
4、按年、月、天、周、小时、分钟、秒统计
SELECT sum(value) FROM "real_water_amount" where time > '2022-01-01' group by time(1d) tz('Asia/Shanghai')
5、按照列过滤
SELECT * FROM "real_water_amount" where time > '2022-01-01' and iotId = '8ecJY59UJd1jwPLBmJA5000000'
二、InfluxDB2.x Docker安装以及与Boot整合
A、Docker安装InfluxDB2.x
1、安装:默认拉取最新版本
docker run -d --name influxdb -p 8086:8086 influxdb
2、查看
docker ps -a
3、浏览器访问 IP:8086 (注意:部署在远程服务器上需要开启8086端口安全组)设置账号密码
从上到下为:账号(zhouhong)、密码(66668888)、确认密码(66668888)、组织(my_influxdb)、Buucket(Tom);完了之后点击 Quick Start
4、然后点击 Data -- > Buucket 就可以看到我们刚才创建的 名字为 Tom 的 Buucket了
5、点击 API Tokens 获取当前用户的 Token(整合时需要)
6、设置Bucket的保存策略
准备工作完成,开始整合
B、InfluxDB2.x与SpringBoot整合
1、依赖
<dependency> <groupId>com.influxdb</groupId> <artifactId>influxdb-client-java</artifactId> <version>4.0.0</version> </dependency> <dependency> <groupId>org.influxdb</groupId> <artifactId>influxdb-java</artifactId> <version>2.20</version> </dependency>
2、yml配置文件
influx: influxUrl: 'http://XXX.XX.XXX.XX:8086' bucket: 'tom' org: 'my_influxdb' token: 'Rt23UemGI_cfS-lFDrurtjh46P1enfhrji-KrZYR04wUR1Yxw_oBCZPL6GmFYSDn20Q9gM_P9DIBhHc2RJjNkA=='
3、配置类
@Setter @Getter public class InfluxBean{ /** * 数据库url地址 */ private String influxUrl; /** * 桶(表) */ private String bucket; /** * 组织 */ private String org; /** * token */ private String token; /** * 数据库连接 */ private InfluxDBClient client; /** * 构造方法 */ public InfluxBean(String influxUrl, String bucket, String org, String token) { this.influxUrl = influxUrl; this.bucket = bucket; this.org = org; this.token = token; this.client = getClient(); } /** * 获取连接 */ private InfluxDBClient getClient() { if (client == null) { client = InfluxDBClientFactory.create(influxUrl, token.toCharArray()); } return client; } /** * 写入数据(以秒为时间单位) */ public void write(Object object){ try (WriteApi writeApi = client.getWriteApi()) { writeApi.writeMeasurement(bucket, org, WritePrecision.NS, object); } } /** * 读取数据 */ public List<FluxTable> queryTable(String fluxQuery){ return client.getQueryApi().query(fluxQuery, org); } }
@Data @Configuration @ConfigurationProperties(prefix = "influx") public class InfluxConfig { /** * url地址 */ private String influxUrl; /** * 桶(表) */ private String bucket; /** * 组织 */ private String org; /** * token */ private String token; /** * 初始化bean */ @Bean(name = "influx") public InfluxBean InfluxBean() { return new InfluxBean(influxUrl, bucket, org, token); } }
4、实现类
@Service @Slf4j public class InfluxServiceImpl implements InfluxService { @Resource private InfluxBean influxBean; @Override public void insert(InsertParams insertParams) { insertParams.setTime(Instant.now()); influxBean.write(insertParams); } @Override public List<InfluxResult> queue(){ // 下面两个 private 方法 赋值给 list 查询对应的数据 List<FluxTable> list = queryInfluxAll(); List<InfluxResult> results = new ArrayList<>(); for (int i = 0; i < list.size(); i++) { for (int j = 0; j < list.get(i).getRecords().size(); j++) { InfluxResult influxResult = new InfluxResult(); influxResult.setCurrent(list.get(i).getRecords().get(j).getValues().get("current").toString()); influxResult.setEnergyUsed(list.get(i).getRecords().get(j).getValues().get("energyUsed").toString()); influxResult.setPower(list.get(i).getRecords().get(j).getValues().get("power").toString()); influxResult.setVoltage(list.get(i).getRecords().get(j).getValues().get("voltage").toString()); influxResult.setTime(list.get(i).getRecords().get(j).getValues().get("_time").toString()); System.err.println(list.get(i).getRecords().get(j).getValues().toString()); results.add(influxResult); } } return results; } /** * description: 查询一小时内的InsertParams所有数据 * date: 2022/1/21 13:44 * author: zhouhong * @param * @param null * @return */ private List<FluxTable> queryInfluxAll(){ String query = " from(bucket: \"tom\")" + " |> range(start: -60m, stop: now())" + " |> filter(fn: (r) => r[\"_measurement\"] == \"influx_test\")" + " |> pivot( rowKey:[\"_time\"], columnKey: [\"_field\"], valueColumn: \"_value\" )"; return influxBean.queryTable(query); } /** * description: 根据某一个字段的值过滤(查询 用电量 energyUsed 为 322 的那条记录) * date: 2022/1/21 12:44 * author: zhouhong * @param * @param null * @return */ public List<FluxTable> queryFilterByEnergyUsed(){ String query = " from(bucket: \"tom\")" + " |> range(start: -60m, stop: now())" + " |> filter(fn: (r) => r[\"_measurement\"] == \"influx_test\")" + " |> filter(fn: (r) => r[\"energyUsed\"] == \"322\")" + " |> pivot( rowKey:[\"_time\"], columnKey: [\"_field\"], valueColumn: \"_value\" )"; return influxBean.queryTable(query); } }
C、测试
1、插入 localhost:9998/inlfuxdb/insert
入参:
{ "energyUsed":"23.12", "power":"321.60", "current":"782.72", "voltage":"67.43" }
返回:
{ "success": true, "code": 200, "message": "请求成功", "localizedMsg": "请求成功", "data": null }
2、查询所有
入参:
{}
返回:
{ "success": true, "code": 200, "message": "请求成功", "localizedMsg": "请求成功", "data": [ { "energyUsed": "23.12", "power": "321.60", "current": "782.72", "voltage": "67.43", "time": "2022-01-20T17:51:01.819Z" }, { "energyUsed": "243.78", "power": "541.50", "current": "32.34", "voltage": "89.09", "time": "2022-01-20T17:33:47.246Z" } ] }
D、Flux常见查询语句
1、指定数据源:from(bucket:"tom")
指定时间范围:
使用管道转发运算符 ( |>) 将数据从数据源通过管道传输到range() 函数,该函数指定查询的时间范围。它接受两个参数:start和stop。范围可以是使用相对负持续时间 或使用绝对时间
//使用绝对时间 from(bucket:"tom") |> range(start: 2022-01-05T23:30:00Z, stop: 2022-01-21T00:00:00Z) //过去十五天的数据 from(bucket:"tom") |> range(start: -15d)
2、数据过滤
将范围数据传递到filter()函数中,以根据数据属性或列缩小结果范围
// 根据 _measurement 和 _field 过滤 from(bucket:"tom") |> range(start: -15d) |> filter(fn: (r) => r._measurement == "influx_test" and r._field == "power" and r.energyUsed == "23.12" )
3、数据转换
使用函数,将数据聚合为平均值、下采样数据等
from(bucket:"tom") |> range(start: -15d) |> filter(fn: (r) => r._measurement == "influx_test" ) |> window(every: 10m) from(bucket:"tom") |> range(start: -15d) |> filter(fn: (r) => r._measurement == "influx_test" ) |> window(every: 10m) |> mean()
其他查询函数请查看官网:https://docs.influxdata.com/flux/v0.x/stdlib/universe/
来源:https://www.cnblogs.com/Tom-shushu/p/15830776.html
来源:https://www.cnblogs.com/Tom-shushu/p/15830776.html
栏目列表
最新更新
python爬虫及其可视化
使用python爬取豆瓣电影短评评论内容
nodejs爬虫
Python正则表达式完全指南
爬取豆瓣Top250图书数据
shp 地图文件批量添加字段
爬虫小试牛刀(爬取学校通知公告)
【python基础】函数-初识函数
【python基础】函数-返回值
HTTP请求:requests模块基础使用必知必会
SQL SERVER中递归
2个场景实例讲解GaussDB(DWS)基表统计信息估
常用的 SQL Server 关键字及其含义
动手分析SQL Server中的事务中使用的锁
openGauss内核分析:SQL by pass & 经典执行
一招教你如何高效批量导入与更新数据
天天写SQL,这些神奇的特性你知道吗?
openGauss内核分析:执行计划生成
[IM002]Navicat ODBC驱动器管理器 未发现数据
初入Sql Server 之 存储过程的简单使用
uniapp/H5 获取手机桌面壁纸 (静态壁纸)
[前端] DNS解析与优化
为什么在js中需要添加addEventListener()?
JS模块化系统
js通过Object.defineProperty() 定义和控制对象
这是目前我见过最好的跨域解决方案!
减少回流与重绘
减少回流与重绘
如何使用KrpanoToolJS在浏览器切图
performance.now() 与 Date.now() 对比