2. 数据同步基础:同步与异步、全量与增量、实时与批量、数据一致性模型
好,咱们正式开始聊数据同步。
说实话,我在做边缘计算之前,一直觉得数据同步不就是把数据从A搬到B嘛。直到有一次,我在一个工业现场项目中,因为同步策略选错了,导致产线数据丢了整整两个小时。嗯,从那以后,我对这块就特别较真。
这一节,咱们把四个最核心的概念掰开揉碎讲清楚。你理解透了,后面设计同步策略时就不会踩坑。
2.1 同步与异步:你到底等不等我?
这两个词,说白了就是「调用方要不要等结果」。
同步(Sync):客户端发个请求,然后傻等着。服务器处理完,返回结果,它才继续往下走。
我在项目中遇到过,有些设备端用同步方式上报数据,结果网络一抖,整个线程就卡住了。你想想看,一个传感器采集线程被卡住,后续数据全丢了。
适用场景:对实时性要求极高,且网络稳定的场景。比如设备固件升级的确认响应。
异步(Async):客户端发完请求,扭头就走。服务器处理完,通过回调或者消息队列通知你。
我个人习惯,边缘设备上报数据,99%的情况用异步。为什么?因为边缘网络太不可控了。你让设备等,它可能等到超时,然后重试,反而把网络搞崩溃。
// 伪代码示例:同步 vs 异步
// 同步方式
bool result = syncUpload(sensorData); // 线程阻塞,直到返回
if (result) { ... }
// 异步方式
asyncUpload(sensorData, callback); // 立即返回,不阻塞
// 回调函数里处理结果
void callback(bool success) { ... }
我的建议:边缘设备到网关这一跳,尽量用异步。网关到云端,可以用同步,因为网络相对可靠。
2.2 全量与增量:你是从头来,还是接着干?
这个好理解。全量同步,就是把所有数据重新传一遍。增量同步,只传变化的部分。
全量同步:简单粗暴,但代价大。
我曾经在一个项目中,设备每次重启都做全量同步。结果呢?几百台设备同时重启,云端服务器直接被打挂了。后来我学乖了,全量同步只用在设备首次上线,或者数据严重不一致时。
增量同步:高效,但实现复杂。
增量同步的核心是「怎么知道哪些数据变了」。常见做法有:
- 时间戳:记录每条数据的最后修改时间。我比较喜欢这种方式,简单。
- 版本号:每条数据带一个递增的版本号。适合数据冲突多的场景。
- 日志捕获(CDC):监听数据库的变更日志。适合数据量极大的场景。
| 方式 | 优点 | 缺点 | 我推荐指数 |
|---|---|---|---|
| 时间戳 | 实现简单,容易理解 | 时钟不同步会出问题 | ⭐⭐⭐⭐ |
| 版本号 | 不受时钟影响,冲突好处理 | 需要维护全局版本号 | ⭐⭐⭐⭐⭐ |
| CDC | 性能最好,不影响业务 | 实现复杂,依赖数据库特性 | ⭐⭐⭐ |
注意:用时间戳做增量同步时,一定要考虑设备时钟漂移。我曾经遇到过,设备电池没电了,时钟复位到1970年,结果全量同步了所有数据……
2.3 实时与批量:你是立刻送,还是攒一波?
实时同步,数据一产生就发出去。批量同步,攒够一定数量或时间再发。
实时同步:延迟低,但网络开销大。
适合告警数据、控制指令。比如设备温度超过阈值,必须立刻上报,晚一秒可能就烧了。
批量同步:节省带宽和电量,但延迟高。
适合周期性采集的数据,比如环境温湿度,每5分钟采集一次,然后批量上报。
我个人习惯的做法是:
- 关键数据(告警、状态变更):实时同步,用MQTT QoS 1或2。
- 非关键数据(日志、统计):批量同步,攒够100条或者1分钟发一次。
// 批量同步的典型逻辑
List<DataPoint> buffer = new ArrayList<>();
int BATCH_SIZE = 100;
long BATCH_INTERVAL_MS = 60000; // 1分钟
void onDataReceived(DataPoint data) {
buffer.add(data);
if (buffer.size() >= BATCH_SIZE) {
flushBatch();
}
}
// 定时器触发
void onTimer() {
if (!buffer.isEmpty()) {
flushBatch();
}
}
2.4 数据一致性模型:你到底要多「准」?
这是最容易被忽略,但也是最要命的部分。
数据一致性模型,说白了就是「你允许数据有多乱」。
- 强一致性:写完就能读到。代价是性能差,延迟高。边缘计算中很少用,除非是金融级别的交易数据。
- 最终一致性:写完不一定马上读到,但过一会儿一定能读到。这是边缘计算的主流模型。
- 弱一致性:可能永远读不到最新的。适合日志、监控等非关键数据。
我在项目中遇到过,客户要求「设备状态必须实时同步到云端」。我问他:「如果网络断了呢?」他说:「那就等网络恢复。」你看,这其实就是最终一致性。
核心原则:不要追求你不需要的一致性。强一致性是有代价的,而且代价往往比你想象的大。
举个例子,你家里的智能灯泡,开关状态需要强一致吗?不需要。你按一下开关,灯没亮,再按一下,亮了。用户能接受。但如果是工厂里的安全阀门,那必须强一致,因为人命关天。
好了,这四个基础概念讲完了。同步与异步决定了交互方式,全量与增量决定了数据量,实时与批量决定了传输节奏,一致性模型决定了最终效果。下一节,咱们聊聊具体怎么把这些组合起来,设计一套靠谱的同步策略。