小 T 导读:科大智能(CSG)是全国领先的工业智能化解决方案供应商之一。SCARM是CSG开发的远程监控与维护管理平台,是典型的物联网应用,开发团队在评估不同的物联网开发框架后,选用了TDengine。
点击这里,即可体验TDengine!
设备预测性维护是在物流装备/机台等生产设备上加装物联网传感器,实时采集设备运行过程中的状态数据,运用边缘端/云端的设备维保知识库,管理设备维保作业,预警设备故障发生风险;形成物联采集端—边缘计算端—云端大数据端的管理闭环。这个闭环产生的行业价值是巨大的:
SCARM是CSG开发的远程监控与维护管理平台。运用物联网技术,实时监控堆垛机、穿梭车、提升机等物流设备的运行状态,结合维保作业管理数据,计算设备故障风险,指导用户采取适当措施排除设备故障风险,降低设备由于维护不当所致的停机风险。
实现目标如下:
SCARM是典型的物联网应用,边缘计算节点推送的数据经消息队列分发给流式计算模块及日志存储模块,物化模型与以关系数据库为中心的模型有很大区别,开发团队在评估不同的物联网开发框架后,选用了TDengine。我们以一个例子来展示TDengine简单易用的编程接口,及如何用它解决物联网特有的流式计算问题。例子的编程思路如下:
这里需要注意的是,TDengine是一个设备一张表的设计思路,因此在步骤2的数据处理服务中,我们根据项目及设备类型在TDengine时序数据库中先建好超级表(每类设备一个超级表,定义好该类设备要采集的字段,以及一些静态标签如设备ID、分组等)和每个设备对应的子表。在MQTT协议解析后,每台设备的数据应存到其对应的子表中。子表的名字和设备ID之间要建立一种映射关系,这样在写入数据时可以根据上报数据中的设备ID信息直接找到要写的表名。当然整个平台的业务数据还是存储在关系数据库MySQL中;一些用户最常用的数据我们也放到了Redis中。TDengine可以解决最新采集数据的缓存问题,省去了一些Redis的内存开销。
1 安装
在一台Linux服务器上安装TDengine的过程非常简单,只需要执行install.sh脚本,然后执行命令启动taosd服务即可(更多可参考 TDengine官网):
sudo systemctl start taosd
2 配置数据库集群
项目中采用3台服务器配置TDengine数据库集群。TDengine的分布式架构中分为虚拟数据节点和虚拟管理节点两种不同的虚拟化节点。虚拟节点是对物理服务节点的虚拟化分,其中数据节点的分布是完全去中心化的,而管理节点则是遵循Master-Slave的方式。因此再集群配置时,要配置一下管理节点主节点所在服务器的IP地址(MasterIP),以及第一备选节点的IP(SecondIP)。
首先在3台服务器均完成TDengine安装后,先不要启动服务,在每台服务器的taos.cfg文件中添加MasterIP、SecondIP以及PrivateIP的配置信息。之后,启动3台服务器上的taosd服务,并用taos客户端连入主节点所在服务执行
create dnode
其中
是具体的第二台服务器的通信IP地址。这样这台服务器就被加入到了集群中。
仿照上述操作配置第三台服务器后,通过show dnodes命令可查询配置的集群节点如下:
到此,集群配置成功。
在SpringBoot项目的pom.xml文件中加入taos的jdbc依赖:
com.taosdata.jdbc
taos-jdbcdriver
1.0.1
在SpringBoot项目的.yml文件中配置公共的taos数据库连接url:
spring:
taos:
enable: true
jdbcUrl: jdbc:TAOS://192.168.12.28:6020/demo?user=root&password=taosdata
database: demo
打开taos数据库连接
try {
if(connection == null)
connection = DriverManager.getConnection(url);
}catch (Exception e){
e.printStackTrace();
}
创建超级表及设备的子表
Statement smt = connection.createStatement();
String sql = String.format(CREATE_SUPER_TABLE, s_name);
smt.executeUpdate(sql);
sql = String.format(CREATE_TABLE, t_name, s_name, paras[0], paras[1]);
smt.executeUpdate(sql);
设备信息的插入
Statement smt = null;
try{
smt = connection.createStatement();
return smt.executeUpdate("import into " + sqlBody);
}catch (Exception e){
e.printStackTrace();
}finally {
try {
if(smt != null)
smt.close();
}catch (Exception e){
e.printStackTrace();
}
}
设备信息的查询
Statement smt = null;
List list = new ArrayList<>();
try{
smt = connection.createStatement();
result = smt.executeQuery(sql);
Field[] fields = clazz.getDeclaredFields();
T t = null;
while (result.next()){
t = clazz.newInstance();
for (Field field : fields){
field.setAccessible(true);
field.set(t, result.getObject(field.getName(), field.getType()));
}
list.add(t);
}
}catch (Exception e){
e.printStackTrace();
}finally {
try{
if(smt != null)
smt.close();
}catch (SQLException se){
se.printStackTrace();
}
}
相比关系型数据库,时序数据库对量级庞大的时序数据能高效的进行存储和查询,而且在存储空间的节省上也有很大的优势。特别是使用TDengine数据库,相较于一开始使用的OpenTSDB时序数据库,在I/O的操作会更快,数据存储空间占用少。再加上TDengine数据库轻量、集成简单的优势,使用方式灵活,可发挥空间很大。后续期望能通过数据库自带的流式计算来分担业务上的一些计算压力。
张少华(第一作者),安徽科大智能物联高级软件开发工程师,目前负责物联网应用方向研发工作。
黄一多,安徽科大智能物联软件总工程师,目前主要负责物联网、大数据等核心技术研究工作。