适用于工业应用程序的InfluxDB 1.8模式设计?

问题描述

我有node-red-S7PLC链接,以1.5秒的周期将以下数据推送到InfluxDB。

msg.payload = {
    name: 'PLCTEST',level1_m: msg.payload.a90,"value payload from PLC passed to influx"
power1: msg.payload.a93,valvepos_%: msg.payload.a107,temp1: msg.payload.a111,washer_acidity: msg.payload.a113,etc.
}
return msg;

总共130个单独的数据点,包括警报,按钮按下和测量(温度,压力,流量...)之类的二进制状态

这已经运行了一周,作为对数据库写入的压力测试。写作似乎很好,但是我注意到,如果我从30分钟查询窗口的10个温度测量值切换到Grafana仪表板中的3小时查询,则加载时间开始变得很烦人。 12小时的窗户是不行的。我认为这是因为我所有的东西都作为字段键和字段值推送了。没有索引,这将使数据库紧张。

Grafana查询检查器为每个measurement_query提供了1081行,因此x10 = 10810行/广告牌查询。但是整个池必须经过的流量是130次测量x 1081 = 140530行/ 3小时窗口。

我想获得一些有关如何优化架构的指示。我谨记以下几点。

DB:Aplication_nameX

测量:Process_metrics,

标签:温度,压力,流量,%,水平,酸度,功率
标签值:CT-xx1 ... CT-xxn,CP-xx1 ... CP-xxn,CF-xx1 ... CF-xxn,....
Fieldkey =值,fieldvalue =值
测量:Alarms_On,
Fieldkey =状态,fieldvalue =“ true”,“ false”
测量值:Binary_ON
字段关键字:状态,字段值=“ true”,“ false”

这会在几个时间处于节点红色(我认为):

     msg.payload = [{
     Value: msg.payload.xxx,"value payload from PLC passed to influx"
     Value: msg.payload.xxx,Value: msg.payload.xxx
     },{
     Temp:"CT_xx1",Temp:"CT_xx2",Temp:"CT_xx2"

     }];
     return msg;  

编辑:遵循罗伯茨的评论

在撰写本文之前,我在线阅读了一周的涌入手册和其他示例。与正常的sql思维方式相比,涌入有些不同,并且具有独特性,我确实发现这异常困难。但是周末我确实有一些清晰的时刻。

我认为以下更合适。

DB: Station_name 
measurements: Process_metrics,Alarms,Binary.   
Tags: "SI_metric"  
Values= "Temperature","Pressure" etc.   
Fieldkey: "proces_position"= CT/P/F_xxx.  
values= process_values   

与我最初的想法相比,这应该可以防止基数变得更加疯狂。

我认为警报和二进制只能保留为fieldkey / fieldvalue,将它们分隔为自己的测量值应该提供足够的过滤。这些也仅在状态更改时记录,因此比1s周期的模拟输入少得多的数据库输入。

在我原始的节点红色流程代码之后,这将转换为批处理输出功能

     msg.payload = [
     {
        measurement: "Process_metrics",fields: {
            CT_xx1:  msg.payload.xxx,CT_xx2:  msg.payload.xxx,CT_xx3:  msg.payload.xxx
        },tags:{
            metric:"temperature"
        },{
        measurement: "Process_metrics",fields: {
            CP_xx1:  msg.payload.xxx,CP_xx2:  msg.payload.xxx,CP_xx3:  msg.payload.xxx
        },tags:{
            metric:"pressure"
        },fields: {
            CF_xx1:  msg.payload.xxx,CF_xx2:  msg.payload.xxx,CF_xx3:  msg.payload.xxx
        },tags:{
            metric:"flow"
        },fields: {
            AP_xx1:  msg.payload.xxx,AP_xx2:  msg.payload.xxx,AP_xx3:  msg.payload.xxx
        },tags:{
            metric:"Pumps"
        },{
        measurement: "Binary_states",fields: {
            Binary1:  msg.payload.xxx,Binary2:  msg.payload.xxx,Binary3:  msg.payload.xxx
        },{
        measurement: "Alarms",fields: {
            Alarm1:  msg.payload.xxx,Alarm2:  msg.payload.xxx,Alarm3:  msg.payload.xxx
        }
    ];
    return msg;

编辑2:

在测试了我的上述想法并进一步完善之后的最终想法。

我的第二个想法没有按预期进行。使用Grafana变量的最后一步不起作用,因为过程数据在字段中具有所需的信息,而不是标签。这使Grafana端对rexec查询感到恼火,因为它从字段中获取plc标签名称信息以链接到grafana变量下拉列表。因此再次运行资源密集型字段查询

我偶然发现了一篇有关如何使用TSDB直截了当的问题的博客文章,而上述想法仍然太像sql,就像使用TSDB处理数据一样。我进一步完善了数据库结构,似乎在不同步骤(PLC-> NodeRed-> influxDB-> Grafana)和数据库查询负载的编码时间上找到了一个折衷方案。在正常使用情况测试中,从1gb的ram使用情况(使用写和查询进行压力)到100-300MB。

当前正在测试中:

Python脚本可将PLC侧标签和描述从csv压缩为Node-Red的可复制格式。从csv提取温度测量值并格式化为nodered的示例。

import pandas as pd
from pathlib import Path

file1 = r'C:\\Users\\....pandastestcsv.csv
df1 = pd.read_csv(file1,sep=';')

dfCT= df1[df1['POS'].str.contains('CT',regex=False,na=False)]

def my_functionCT(x,y):
      print( "{measurement:"+'"temperature",'+"fields:{value:msg.payload."+ x +",},tags:{CT:\"" + y +'\",' )

result = [my_functionCT(x,y) for x,y in zip(dfCT['ID'],dfCT['POS'])]

输出的是来自CSV的所有温度测量值CT。 {测量:“温度”,字段:{value:msg.payload.a1,},标签:{CT:“过程位置为CT_310的标签说明”,},},

此列表可以复制粘贴到Node-Red数据链路有效负载中,并复制到influxDB。

InfluxDB:
数据库:PLCTEST
测量值:温度,压力,流量,泵,阀,警报,开/关....
标记键:CT,CP,CF,misc_mes ....
标签字段:“标签的PLC描述”
字段键:值
字段值:“来自PLC有效负载的过程测量值”

这可以确保在合理范围内检查每次测量的基数,并且查询可以更好地针对相关数据,而无需遍历整个数据库。 Ram和cpu负载现在较小,在Grafana负载中从1h的查询跳到12h的查询在几秒钟内就没有锁定。

解决方法

在设计InfluxDB测量方案时,我们在选择标签和字段时需要非常小心。

每个标签值将创建单独的系列,并且随着标签值数量的增加,InfluxDB服务器的内存需求将成倍增加。

从问题中给出的测量描述中,我可以看到您将诸如温度,压力等高基数值保留为标签值。这些值应改为保留为字段。

通过将这些值保留为标签,influxdb将为这些值建立索引,以加快搜索速度。对于每个标签值,将创建一个单独的系列。随着标签值数量的增加,系列的数量也会增加,从而导致内存不足错误。

引用InfluxDB文档。

包含高度可变信息(例如UUID,哈希和 随机字符串会导致数据库中出现大量序列, 被称为高系列基数。高系列基数是主要的 高内存使用率的驱动程序,用于许多数据库工作负载。

有关详细信息,请参阅influxDB文档以设计架构。

https://docs.influxdata.com/influxdb/v1.8/concepts/schema_and_data_layout/