问题本质
采集是持续的,而边缘到中心的网络会中断。如果“网络断时采到的数据直接丢弃”,恢复后历史曲线就会有一段空洞,影响追溯和分析。解决思路是边缘侧先存,网络恢复再补传。
三种方案对比
方案一:靠 MQTT Broker 缓存
- 利用 Broker 的会话持久和消息队列
- 优点:实现简单
- 缺点:Broker 重启或队列溢出仍会丢,适合短时中断
方案二:边缘本地落盘(推荐)
- 采集数据先写本地 SQLite/轻量时序库,同时尝试上送
- 网络断时数据留在本地,恢复后按时间顺序补传
- 优点:断电也不丢,可应对长时间断网
- 缺点:边缘要占一点磁盘,需要补传逻辑
方案三:中心侧主动回拉
- 恢复后中心向边缘请求缺失时间段数据
- 优点:逻辑集中
- 缺点:边缘要保留历史并提供查询接口,复杂度高
中小项目推荐方案二。
本地缓存的关键设计
- 每条数据带原始采集时间戳,补传时不能用补传时刻,否则时间轴错乱
- 用一个“是否已上传”标记,或维护上传水位线(已传到哪个时间点)
- 补传按时间顺序批量发送,控制速率避免恢复瞬间打爆中心
- 本地设置保留上限(如 7 天),防止磁盘写满
补传与实时的优先级
网络恢复后,实时数据优先、历史补传让路:先保证当前数据实时上来,再用空闲带宽慢慢补历史,避免补传把实时链路堵住。
去重处理
补传可能和已到达的数据重复(比如 MQTT QoS1 已收到一部分),中心侧按“设备+点位+时间戳”做主键或去重,保证重复补传不产生双份数据。
落地最小实现
- 边缘:采集即写本地 SQLite(事务批量写),上传成功后更新水位线
- 定时任务发现水位线落后于当前时间,就批量取未传数据补送
- 中心:按时间戳去重写入时序库
这样即使断网几小时,恢复后曲线也能补齐,历史数据真正连续可信。