3、数据采集架构设计:边缘采集 vs 云端采集、采集网关硬件选型、采集频率与数据压缩策略、数据缓存与断点续传机制
大家好,我是老张。今天咱们聊聊数据采集架构设计。说实话,这一块是储能数据系统的地基。地基没打好,后面ETL做得再漂亮也是白搭。我在几个大型储能项目里都踩过坑,今天把这些经验掰开揉碎了讲给你听。
3.1 边缘采集 vs 云端采集:不是二选一,是配合
很多人一上来就问:「我该用边缘采集还是云端采集?」我的回答是:别急着二选一。你想想看,储能系统里既有毫秒级的BMS数据,也有小时级的电表数据,怎么可能一套方案通吃?
边缘采集,说白了就是在设备端附近完成数据采集和初步处理。我习惯在采集网关上跑一个轻量级的采集程序,把高频数据先收上来,做一次清洗和聚合,再往云端推。
云端采集,则是设备直接上报原始数据到云平台,由云端的ETL任务去处理。这种方式架构简单,但对网络和带宽要求高。
我个人建议采用边缘+云端混合架构。核心逻辑是这样的:
- 高频数据(≤1秒):边缘采集,本地缓存,按需聚合后上报
- 中频数据(1秒~1分钟):边缘采集,实时上报,云端做二次处理
- 低频数据(≥1分钟):直接云端采集,设备主动上报
核心原则:边缘负责「快」和「稳」,云端负责「全」和「智」。两者各司其职,别让边缘干云端的活,也别让云端处理边缘该做的事。
下面这张图是我自己画的混合采集架构,你看一眼就明白了:
3.2 采集网关硬件选型:别只看参数,要看场景
采集网关选型,我踩过最大的坑就是「参数党」。曾经有个项目,我看某款网关CPU主频高、内存大,直接拍板买了。结果到现场发现,这玩意功耗太高,在户外机柜里散热根本扛不住。嗯,后来全换了。
选型时我一般看这几个维度:
| 维度 | 关键指标 | 我的建议 |
|---|---|---|
| 计算能力 | CPU主频、核心数 | ARM Cortex-A系列起步,别用M系列,跑不了协议栈 |
| 存储 | RAM、eMMC/Flash | RAM ≥ 512MB,存储 ≥ 8GB(要缓存数据) |
| 接口 | RS485、CAN、以太网、4G/5G | RS485至少2路,CAN至少1路,以太网必备 |
| 环境适应性 | 工作温度、防护等级 | 工业级:-40℃~85℃,户外选IP65以上 |
| 功耗 | 典型功耗、待机功耗 | ≤15W,太阳能供电场景≤5W |
| 可靠性 | MTBF、看门狗、双机热备 | MTBF ≥ 100000小时,必须有硬件看门狗 |
我的经验:如果现场有4G网络,优先选带4G模块的网关。别指望现场拉网线,储能站大多在偏远地方。我曾经在一个山顶储能站调试,4G信号只有两格,还好网关支持外接天线,不然数据都传不回来。
3.3 采集频率与数据压缩策略:别把带宽当自来水
采集频率怎么定?我见过最夸张的项目,BMS数据每100毫秒采一次,一天下来一个电池簇就产生800多万条记录。你想想看,100个簇呢?数据量直接爆炸。
我的原则是:按需采集,能聚合就别存原始值。
具体来说:
- 电压、电流、温度:这些变化快,建议100ms~1s采集一次。但上报时可以做聚合——比如每秒上报一次平均值、最大值、最小值,原始数据本地存一份就行。
- SOC、SOH:变化慢,1分钟采集一次足够。别学某些项目每秒采一次SOC,那玩意算法算出来的,一秒能变多少?
- 告警事件:触发式采集,平时不采,有告警才记录。这个最省带宽。
数据压缩方面,我常用的策略:
- 死区压缩:数值变化不超过阈值就不记录。比如电压变化小于0.01V,直接忽略。这个在储能场景特别管用,因为很多数据是平稳的。
- 旋转门压缩:用线性拟合的方式,只记录趋势变化的关键点。适合长时间序列数据。
- Gzip/Zlib压缩:传输层压缩,对JSON格式数据压缩率能达到5:1以上。
避坑指南:我曾经在一个项目里用了死区压缩,阈值设得太大了,结果电压波动没被记录,导致后续的SOC估算偏差很大。后来我把阈值调小,同时保留每5分钟一个强制采样点,问题就解决了。
3.4 数据缓存与断点续传机制:别让网络断了就丢数据
储能站网络不稳定是常态。4G信号时好时坏,光纤被挖断也是常有的事。所以数据缓存和断点续传是必须的,不是可选项。
我一般这样设计:
缓存策略:
- 内存缓存:用环形缓冲区,存最近1分钟的数据。速度快,但掉电就丢。
- 本地文件缓存:每1分钟把内存数据刷到本地SQLite或文件中。掉电不丢,但要注意写入频率,别把Flash写坏了。
- 分级缓存:内存→本地文件→SD卡。数据量大了就往下一级挪。
断点续传机制:
- 每条数据生成一个唯一ID(时间戳+设备ID+序号)。
- 上传时记录已上传的最大ID。
- 网络恢复后,从断点处开始补传。
- 补传时按时间顺序,先传最新的,再补旧的(保证实时性)。
代码示例(伪代码,展示核心逻辑):
// 数据缓存与断点续传核心逻辑
class DataCacheManager {
private:
string lastUploadedId; // 已上传的最大ID
Queue<DataPoint> cacheQueue; // 内存缓存队列
public:
void onDataReceived(DataPoint dp) {
dp.id = generateUniqueId();
cacheQueue.push(dp);
// 每100条数据刷一次本地缓存
if (cacheQueue.size() >= 100) {
flushToLocalStorage();
}
}
void onNetworkRecovered() {
// 从本地存储读取未上传的数据
vector<DataPoint> pendingData = readFromLocalStorage(lastUploadedId);
// 按时间排序,先传最新的
sort(pendingData, byTimestampDesc);
for (auto& dp : pendingData) {
if (uploadToCloud(dp)) {
lastUploadedId = dp.id;
} else {
break; // 网络又断了,下次继续
}
}
}
void flushToLocalStorage() {
// 写入SQLite或文件
// 注意:写入频率不要超过每秒1次,保护Flash
}
};
重要提醒:本地缓存一定要设置上限。我见过一个项目,缓存数据攒了3个月没上传,结果SD卡写满了,新数据全丢了。建议设置缓存上限为7天数据量,超过上限就覆盖最旧的数据。
好了,数据采集架构设计就聊到这儿。核心就三句话:边缘和云端要配合好,网关选型看场景别只看参数,缓存和续传机制必须做扎实。下一节咱们聊数据清洗和标准化,那又是另一番天地了。
公众号:蓝海资料掘金营,微信deep3321