1.背景介绍
在智能家居中总会有场景联动的情况,比如灯开了,怎么让其他智能设备进行联动比如窗帘自动打开。这就涉及到嵌入式和后台云端直接的合作了。在这里介绍两种方案
2.方案差异
传统方案-设备通过mqtt上报Dp功能点
Flink流处理模式-设备上报数据到flink进行计算
核心差异分析
维度 | 传统模式 | Flink模式 |
---|---|---|
数据访问路径 | 每次都需要查库 | 规则预加载到内存/状态后端 |
延迟 | 高(50-500ms) | 极低(5-50ms) |
数据库压力 | 高频查询导致压力大 | 仅需定期同步规则变更 |
规则复杂度支持 | 简单条件 | 支持窗口计算、复杂事件序列 |
扩展性 | 垂直扩展数据库 | 水平扩展Flink集群 |
容错性 | 依赖数据库可用性 | 自带Checkpoint和状态恢复机制 |
3.具体流程
整个流程分为通过APP 创建设备的场景数据,也就是规则会存到mysql,并且通过flink-cdc 同步到flink 内存中,后面设备上报数据,flink直接从内存中查找对应规则类似下面的代码
deviceStream.connect(ruleStream) .process(new KeyedBroadcastProcessFunction<>() { // 存储设备最新状态(灯的状态) private ValueState<DeviceState> deviceState; @Override public void processElement( DeviceEvent event, ReadOnlyContext ctx, Collector<ActionCommand> out) throws Exception { // 从广播状态获取所有规则(内存操作) Iterable<Map.Entry<String, SceneRule>> rules = ctx.getBroadcastState(RULE_STATE_DESCRIPTOR).immutableEntries(); // 检查每个规则 for (Map.Entry<String, SceneRule> entry : rules) { if (matches(event, entry.getValue())) { out.collect(buildCommand(entry.getValue())); } } } @Override public void processBroadcastElement( SceneRule rule, Context ctx, Collector<ActionCommand> out) { // 更新广播状态(所有TaskManager都会收到) ctx.getBroadcastState(RULE_STATE_DESCRIPTOR) .put(rule.id, rule); } });
但是其实这个时候还有其他问题就是依赖flink 内存一旦flink 挂了或者其他故障就会导致规则丢失。所以在这里还引入了S3,整个架构通过flink-mysql-s3 互相配合,架构如下图
整个流程就结束了,当然这种架构带来的也是复杂度,适用于设备较多处理场景比较复杂的情况。