断网期间怎么办:本地缓存、补传与去重
设备离线是常态而不是异常。本文说明缓存该存多少、重连后补传为什么会把平台打垮、以及补传数据与实时数据混在一起时时间戳要怎么处理。
- 设备离线是常态,缓存容量应按业务可接受的最长离线时长按最坏情况计算。
- 缓存写满的丢弃策略必须明确并写入文档,告警类数据应单独存放单独限额。
- 同一次网络中断导致的集体重连会造成数十倍瞬时流量,必须随机退避加限速。
- 时间戳要用采集时刻而非接收时刻,否则补传数据会全部挤在恢复后的一分钟。
- 补传数据可能迟到数小时,更适合走批处理补算而非强行塞进实时链路。
现场设备断网是常态:基站维护、园区停电、工业环境里的电磁干扰、运营商侧的策略调整。项目验收时网络都好,上线三个月后才发现某个站点每天断十几分钟。设计阶段就把离线当作正常状态处理,比事后补救省事得多 —— 这也是我们在制造业类现场项目里优先确认的一项。
本地缓存存多久
容量规划的输入是三个数:单条记录的字节数、上报频率、可接受的最长离线时长。三者相乘就是需要的存储空间。要注意按最坏情况算 —— 如果业务上要求「断网一天的数据不能丢」,那就按一天算,而不是按通常断几分钟算。
存储介质也要考虑写入寿命。高频写入普通 Flash 会在几年内把擦写次数用完,表现为设备在质保期后期批量出现存储故障。降低写入频率、使用磨损均衡、或者改用适合频繁写入的介质,都应当在硬件选型时确定。
缓存满了怎么办
必须明确选择丢弃策略,并写进文档:丢最旧的,还是丢最新的,还是降采样保留。对趋势类数据,丢最旧的通常可接受;对告警类数据,任何一条都不能丢,应当单独存放、单独限额。最糟的做法是没有策略 —— 写满之后行为由存储层决定,而不同批次的硬件可能表现不同。
重连补传会把平台打垮
一个园区的几百台设备因为同一次网络中断同时离线,网络恢复后它们也会同时重连、同时开始补传。瞬时流量可能是平时的几十倍,而这正是平台最脆弱的时刻。
- 设备侧:重连加随机退避,不要所有设备都在网络恢复的那一秒发起连接;
- 设备侧:补传限速,按固定速率发送,不要一次性把缓存全部推出去;
- 平台侧:对补传通道单独限流,保证实时数据的处理不被补传挤占;
- 平台侧:接入层做好背压,宁可让设备稍后重试,也不要让后端服务被压垮。
时间戳必须是采集时间
补传数据最容易出的错,是平台用「收到的时刻」当作数据时间。这样一来,断网一小时后补传的数据会全部挤在恢复后的那一分钟里,曲线完全失真,基于时间窗口的统计和告警也会跟着出错。
正确做法是设备在采集时就打上时间戳并随数据一起上报,平台以这个时间为准。随之而来的要求是设备时钟必须准确,这又牵出对时问题 —— 两件事必须一起设计,只做其中一件等于没做。
去重与幂等
补传过程中断再重来、确认报文丢失导致重发,都会产生重复数据。设备为每条记录生成稳定的唯一标识(常见做法是设备标识加采集时间加序号),平台按此判重。这个标识必须在设备重启后仍然稳定,否则重启前后的同一条数据会被当成两条。
下游的计算也要能接受乱序和迟到。这一层的取舍通常在物联网平台解决方案的方案阶段就要定下来。实时流处理里通常用水位线机制处理迟到数据,但补传可能迟到几小时甚至几天,超出常规水位线的容忍范围。这类数据更适合走单独的批处理补算路径,而不是强行塞进实时链路。
常见问题
设备本地缓存应该存多少条数据?
用单条字节数乘以上报频率乘以可接受的最长离线时长,按最坏情况计算,而不是按常见情况。同时要核对存储介质的擦写寿命,高频写入普通 Flash 可能在质保期内就耗尽寿命。
补传数据和实时数据怎么区分?
不靠区分,靠时间戳。数据在采集时就打上时间并随上报带来,平台一律以该时间为准入库,补传与实时在数据层面就没有差别。平台侧可以在传输通道上分流以便限速,但不应改变数据本身的时间语义。
几百台设备同时重连会怎样?
瞬时连接数和消息量可能达到平时的数十倍,容易压垮接入层或后端存储。设备端需要随机退避和补传限速,平台端需要对补传通道单独限流并实现背压。这一项建议在压测时专门构造场景验证。
参考资料
- MQTT Version 5.0 OASIS Standard · OASIS
- 物联网平台产品文档 · 阿里云