内存数据表和数据视图模块架构分析
1. 模块概述
内存数据表(Data Cache)和数据视图(Data View)是cNetgate项目中的核心数据管理模块,负责系统数据的存储、管理和处理。这两个模块紧密配合,为整个系统提供了高效、灵活的数据管理能力。
1.1 内存数据表模块
功能概述:
- 提供全局数据缓冲,存储从设备采集的数据
- 支持站点和数据点的两级数据结构
- 提供数据的读写、查询和迭代功能
- 支持数据的实时更新和通知机制
应用场景:
- 存储从串口、网络等设备采集的实时数据
- 作为系统内部数据交换的中心枢纽
- 为触发器、转发器等模块提供数据来源
1.2 数据视图模块
功能概述:
- 基于原始数据创建虚拟数据视图
- 支持脚本语言(Lua、Python、JavaScript)处理数据
- 提供定时数据处理和计算能力
- 实现数据的转换、过滤和聚合
应用场景:
- 对原始数据进行计算和转换
- 基于多个数据点创建复合数据
- 实现复杂的数据处理逻辑
- 提供数据可视化和分析的数据源
2. 架构设计
2.1 整体架构图
插件层
核心层
应用层
项目管理
数据采集
数据转发
触发器
内存数据表
数据视图
插件管理
脚本系统
Modbus插件
MQTT插件
Serial插件
HTTP插件
2.2 内存数据表架构
外部模块
操作接口
内存数据表
数据缓存对象 data_t
站点数据 siteData_t
数据项 valueItem_t
数据值 value_t
数据读写
站点管理
数据迭代
数据通知
插件
转发器
触发器
2.3 数据视图架构
外部模块
操作接口
数据视图
数据视图对象 dvDataView_t
虚拟站点 dvSite_t
数据点 dataViewDP_t
脚本引擎
视图管理
数据处理
脚本执行
内存数据表
项目管理
脚本系统
3. 核心数据结构
3.1 内存数据表核心结构
data_t - 数据缓存主结构
c
typedef struct stData {
pthread_mutex_t m_mutex; // 互斥锁,保证线程安全
vector_t * p_site; // 站点数据向量,存储siteData_t *
} data_t;
siteData_t - 站点数据结构
c
typedef struct stSiteData {
string_t * p_name; // 站点名称
map_t * p_values; // 数据项映射,key为变量名称指针,value为valueItem_t *
} siteData_t;
valueItem_t - 数据项结构
c
typedef struct stValueItem {
bool m_need_writeback; // 是否需要写回设备
string_t * p_name; // 变量名称
value_t * p_value; // 变量值
} valueItem_t;
3.2 数据视图核心结构
dvDataView_t - 数据视图主结构
c
typedef struct stDvDataView {
string_t * p_script_type; // 脚本类型(LUA、PY3、JS)
map_t * p_sites; // 虚拟站点映射
struct stScriptObject * p_script; // 脚本引擎对象
} dvDataView_t;
dvSite_t - 虚拟站点结构
c
typedef struct stDvSite {
string_t * p_name; // 站点名称
uint32_t m_cycle; // 处理周期(毫秒)
uint64_t * p_timer; // 定时器ID
map_t * p_vars; // 数据点映射
} dvSite_t;
dataViewDP_t - 数据点结构
c
typedef struct stDataViewDP {
string_t * p_name; // 数据点名称
string_t * p_expr; // 表达式
value_t * p_value; // 计算结果
} dataViewDP_t;
4. 主要功能实现
4.1 内存数据表功能
4.1.1 数据缓存管理
创建和释放数据缓存:
newDataCache(): 创建数据缓存对象,初始化互斥锁和站点向量releaseDataCache(data_t * data): 释放数据缓存对象,清理所有站点和数据
站点管理:
dataAddSite(data_t * data, const string_t * name): 添加新站点removeSite(data_t * data, const string_t * name): 移除指定站点dataGetSite(data_t * data, const string_t * site_name): 获取指定站点
4.1.2 数据操作
数据写入:
dataSetValueEx(data_t * data, const string_t * site_name, const string_t * value_name, const value_t * value): 设置指定站点和变量的值dataWriteValue(data_t * data, const string_t * name, const value_t * value): 标记需要写回设备的数据
数据读取:
dataGetValueEx(data_t * data, const string_t * site_name, const string_t * var): 获取指定站点和变量的值dataGetValue(data_t * data, const string_t * name): 通过"站点.变量"格式获取值
数据迭代:
dataIterator(data_t * data, dataIterCb cb, void * usr): 遍历所有站点和数据dataIteratorBySite(data_t * data, const string_t * sname, dataIterBySiteCb cb, void * usr): 遍历指定站点的所有数据
4.2 数据视图功能
4.2.1 数据视图管理
创建和释放数据视图:
newDataView(cJSON * json): 从JSON配置创建数据视图对象releaseDataView(dvDataView_t * ctx): 释放数据视图对象
站点控制:
dvDataViewStart(dvDataView_t * ctx, const string_t * site, bool start): 启动指定站点的数据处理dvDataVieweStop(dvDataView_t * ctx, const string_t * site): 停止指定站点的数据处理dvDataViewStartAll(dvDataView_t * ctx, const string_t * site, bool start): 启动所有站点的数据处理dvDataVieweStopAll(dvDataView_t * ctx): 停止所有站点的数据处理
4.2.2 脚本引擎集成
脚本引擎初始化:
dataView__init_script_engine__(dvDataView_t * ctx): 根据配置初始化脚本引擎
脚本类型支持:
- 支持Lua、Python 3和JavaScript脚本
- 通过
dataView__parse_script_type(const string_t * name)解析脚本类型
5. 工作流程
5.1 内存数据表工作流程
数据项 站点数据 数据缓存 插件 数据项 站点数据 数据缓存 插件 dataSetValueEx(site, var, value) 加锁保护 查找或创建站点 查找或创建数据项 更新值 解锁 返回操作结果 dataGetValueEx(site, var) 加锁保护 查找站点 查找数据项 返回值 解锁 返回值
5.2 数据视图工作流程
内存数据表 脚本引擎 数据视图 项目管理 内存数据表 脚本引擎 数据视图 项目管理 loop [定时执行] newDataView(json配置) 初始化数据结构 初始化脚本引擎 解析数据点配置 返回数据视图对象 dvDataViewStart(site, true) 启动站点定时器 执行数据处理脚本 读取原始数据 返回原始数据 执行计算逻辑 返回计算结果 更新数据视图结果
6. 技术优势
6.1 内存数据表优势
-
高效的数据存储:
- 使用哈希表(map)存储数据项,提供O(1)时间复杂度的数据访问
- 站点和数据点的两级结构,便于组织和管理数据
-
线程安全:
- 所有数据操作都通过互斥锁保护,确保多线程环境下的数据一致性
-
灵活的数据操作:
- 支持多种数据访问方式:直接读写、按站点操作、批量迭代
- 提供"站点.变量"格式的统一访问接口
-
数据写回机制:
- 支持标记需要写回设备的数据,实现数据的双向流动
6.2 数据视图优势
-
多语言脚本支持:
- 支持Lua、Python 3和JavaScript三种脚本语言
- 为不同背景的开发者提供熟悉的编程环境
-
灵活的数据处理:
- 基于脚本的可编程数据处理,支持复杂的计算逻辑
- 定时执行机制,确保数据实时更新
-
虚拟数据模型:
- 基于原始数据创建虚拟数据视图,不影响原始数据
- 支持数据的转换、过滤和聚合
-
与内存数据表的无缝集成:
- 直接访问内存数据表中的原始数据
- 将处理结果写回内存数据表,供其他模块使用
7. 代码优化建议
7.1 内存数据表优化
-
内存管理优化:
- 减少频繁的内存分配和释放,考虑使用内存池
- 优化字符串操作,减少不必要的字符串复制
-
并发性能优化:
- 考虑使用读写锁替代互斥锁,提高并发读取性能
- 对于批量操作,减少锁的粒度和持有时间
-
数据结构优化:
- 对于大规模数据,考虑使用更高效的数据结构
- 优化哈希函数,减少哈希冲突
-
错误处理增强:
- 增加更详细的错误信息和日志
- 实现数据校验机制,确保数据一致性
7.2 数据视图优化
-
脚本执行优化:
- 实现脚本缓存机制,避免重复解析
- 优化脚本执行环境,减少资源消耗
-
定时任务管理:
- 实现更精确的定时器管理
- 支持任务优先级和调度策略
-
内存使用优化:
- 减少脚本引擎的内存占用
- 优化数据视图的内存结构
-
扩展性增强:
- 支持更多脚本语言和版本
- 提供更丰富的脚本API
7. 南北向与模块关系
7.1 南北向概念
在工业物联网系统中,数据流向通常分为两个方向:
- 南向(Southbound):系统向下与设备、传感器等底层设备的通信方向,负责数据采集
- 北向(Northbound):系统向上与上层应用、平台的通信方向,负责数据转发和提供服务
7.2 与内存数据表的关系
北向
核心
南向
设备
采集插件
内存数据表
数据视图
内存数据表
转发插件
上层应用
南向与内存数据表:
- 南向插件(如Serial、Modbus等)通过
dataSetValueEx等接口将采集到的数据写入内存数据表 - 内存数据表作为南向数据的汇聚点,存储所有从设备采集的原始数据
- 南向插件可以通过
dataGetValueEx等接口读取内存数据表中的数据,实现对设备的控制
北向与内存数据表:
- 北向插件(如MQTT、HTTP等)通过
dataGetValueEx等接口从内存数据表读取数据 - 内存数据表作为北向数据的数据源,为上层应用提供原始数据或经过处理的数据
- 北向插件可以将上层应用的控制命令写入内存数据表,再由南向插件转发到设备
7.3 与数据视图的关系
数据视图在南北向中的作用:
- 数据视图从内存数据表中读取原始数据,进行转换、计算和处理
- 处理后的数据可以写回内存数据表,供北向插件使用
- 数据视图可以实现复杂的数据处理逻辑,如数据聚合、过滤、转换等
- 数据视图为北向应用提供了更加灵活、定制化的数据服务
8. 数据表生成与项目文件关系
8.1 数据表生成过程
内存数据表的生成:
- 项目初始化 :当项目启动时,通过
newDataCache()创建内存数据表对象 - 站点创建 :根据项目配置文件中的站点定义,通过
dataAddSite()添加站点 - 数据点初始化:当插件连接到设备后,根据设备配置创建数据点
- 数据采集 :插件通过
dataSetValueEx()将采集到的数据写入内存数据表
数据视图的生成:
- 项目初始化 :当项目启动时,根据配置文件中的数据视图定义,通过
newDataView()创建数据视图对象 - 脚本引擎初始化:根据配置初始化相应的脚本引擎(Lua、Python、JavaScript)
- 数据点解析:解析配置文件中的数据点定义,包括表达式、计算逻辑等
- 定时任务启动 :通过
dvDataViewStart()启动数据视图的定时处理任务
8.2 与项目文件的关系
项目文件结构:
- 项目配置文件定义了系统的整体结构,包括站点、设备、数据点、数据视图等
- 站点配置定义了设备的连接参数、数据点映射等
- 数据视图配置定义了虚拟站点、数据点表达式、脚本类型等
配置文件与数据表的映射:
项目配置文件
站点配置
数据视图配置
内存数据表站点
数据视图对象
内存数据表数据点
数据视图数据点
处理后的数据
配置文件解析流程:
- 项目启动时,解析项目配置文件
- 根据站点配置创建内存数据表中的站点
- 根据数据视图配置创建数据视图对象和虚拟站点
- 插件根据配置连接到设备,并开始数据采集
- 数据视图根据配置开始定时处理数据
运行时关系:
- 项目配置文件是数据表生成的依据
- 内存数据表是配置文件中站点和数据点的运行时体现
- 数据视图是配置文件中数据视图定义的运行时体现
- 项目运行过程中,数据表的状态会实时反映设备的状态
9. 总结
内存数据表和数据视图模块是cNetgate项目中的核心数据管理组件,它们共同为系统提供了高效、灵活的数据管理能力。内存数据表作为系统的"数据中心",负责存储和管理原始数据;数据视图则作为"数据处理中心",负责对原始数据进行转换和计算。
这两个模块在南北向架构中扮演着重要的角色:
- 作为南向数据的汇聚点,存储从设备采集的原始数据
- 作为北向数据的数据源,为上层应用提供数据服务
- 作为数据处理的中间层,实现数据的转换、计算和处理
数据表的生成与项目文件密切相关,项目配置文件定义了数据表的结构和行为,数据表则是配置文件的运行时体现。通过这种设计,cNetgate系统实现了配置与运行时的分离,提高了系统的灵活性和可维护性。
未来的发展方向包括进一步优化性能、增强可靠性、扩展功能,以及提供更友好的开发和使用体验,使系统能够更好地适应不断变化的工业物联网需求。