我有节点红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个数据点组成的二进制状态,如警报和按钮按下和测量(温度,压力,流量.)
这已经运行了一个星期,因为DB写的压力测试。编写似乎不错,但我注意到,如果我将Grafana仪表板中的10次温度测量与30分钟查询窗口转换为3小时查询,那么加载时间开始变得非常长。12小时的窗口是不去的。我认为这是因为我的所有东西都是作为字段键和字段值推送的。如果没有索引,这将给数据库带来压力。
Grafana查询检查器为我提供了每个measurement_query 1081行,因此x10 = 10810行/dasboard_ query。但是整个池的流入必须经过130个测量x 1081 = 140530行/3小时窗口。
我想获得一些关于如何优化模式的提示。我想到了以下几点。
DB: Aplication_nameX
测量: Process_metrics,
标签:温度,压力,流量,%,水平,酸度,功率
Tag_values: ct-xx1.CT,CP-x1.CP-xxn,CF-xx1.CF-xxn,.
Fieldkey=值,fieldvalue=值
测量: Alarms_On,
Fieldkey= State,fieldvalue=“true”,"false“
Measurement:Binary_ON
Fieldkey: State,fieldvalue=“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 这应该可以防止基数的疯狂和我最初的想法。
我认为警报器和二进制值可以仅作为字段键/字段值保留,并且将它们分离到自己的测量值应该可以进行足够的滤波。这些记录也只有在状态更改时才会记录,因此,与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"
},
{
measurement: "Process_metrics",
fields: {
CF_xx1: msg.payload.xxx,
CF_xx2: msg.payload.xxx,
CF_xx3: msg.payload.xxx
},
tags:{
metric:"flow"
},
{
measurement: "Process_metrics",
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的数据处理方法一样。我对DB结构做了进一步的改进,我似乎已经找到了一个折衷方案,即在不同的步骤(PLC->NodeRed->influxDB>Grafana)和数据库上的查询加载中找到了一个折衷方案。从1gb的内存使用量时,强调写和查询,100-300 in在正常使用测试。
目前正在测试:
Python脚本处理从csv到Node-Red可复制格式的PLC侧标记和描述。例如,从csv中提取温度测量值,并将其形成为喷头。
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'])]输出的这是所有的温度测量,CT从CSV。{测量:“温度”,字段:{value:msg.payload.a1,},标签:{CT:“带有进程位置的标签描述”,},},
此列表可以复制到节点-红色数据链路有效载荷到influxDB。
InfluxDB:
数据库: PLCTEST
测量:温度,压力,流量,泵,阀门,警报器,on_off。
标签键: CT,CP,CF,misc_mes.
标签字段:"PLC对标签的描述“
字段键:值
字段值:“来自PLC有效载荷的过程测量值”
这使每个度量的基数保持在合理的范围内,并且查询可以更好地针对相关数据,而无需在整个DB中运行。Ram和CPU负载现在很小,在Grafana负载中从1h到12h的查询在几秒钟内没有锁定。
发布于 2020-09-20 02:58:42
在设计InfluxDB度量模式时,我们需要非常小心地选择标记和字段。
每个标记值将创建单独的系列,并且随着标记值的增加,InfluxDB服务器的内存需求将呈指数增长。
从问题中给出的测量的描述中,我可以看到,你保持高基数值,如温度,压力等作为标签值。这些值应该保留为字段。
通过将这些值保留为标记,influxdb将对这些值进行索引,以加快搜索速度。对于每个标记值,将创建一个单独的系列。随着标签值的增加,串的数量也会增加,导致内存不足。
引用InfluxDB文档。
包含UUID、散列和随机字符串等高度可变信息的
标记将导致数据库中的大量序列,也称为高系列基数。高系列基数是许多数据库工作负载高内存使用率的主要驱动程序。
有关设计模式的详细信息,请参阅influxDB文档。
https://docs.influxdata.com/influxdb/v1.8/concepts/schema_and_data_layout/
https://stackoverflow.com/questions/63955604
复制相似问题