当前位置: 首页 > news >正文

软件设计不是CRUD(22):在流式数据处理系统中进行业务抽象落地——设计思考

(接上文《软件设计不是CRUD(21):在流式数据处理系统中进行业务抽象落地——需求分析》)

那么思考到这里我们就能做一些关于设计思路的总结:

  • 每一个独立的数据处理流,就是数据采集系统中的一个功能。这个功能具备一个静态的控制逻辑(当然控制逻辑也可以是动态的,本文不进行讨论)。只要某个IoT设备/设备网关的数据处理过程匹配控制逻辑本身,那么IoT设备/设备网关就可以通过这个数据处理流进行数据采集。

  • 为了让一个数据流能最大程度支持更多具体数据结构的数据采集工作,数据处理流都会进行模型抽象和行为抽象,以便让具体的IoT设备/设备网关可以实现具体的模型和具体的行为(业务逻辑)。

  • 这样一来,当新的IoT设备/设备网关需要进行数据采集时,首先可以寻找现有的各个数据处理流,是否匹配新的IoT设备/设备网关的数据结构。如果匹配,就可以在实现这个数据处理流的抽象模型和抽象行为,以便进行接入;如果没有,则再创建新的数据处理流(新的数据处理流也应该进行模型抽象和行为抽象)。

  • 而以上新数据类型的采集能力接入,完全不会影响其它数据处理流的工作,也不会影响同一数据处理流对其它数据类型的采集工作。只需要在完成具体模型和具体行为的实现后,通过诸如Jenkins这样的自动化部署工具重新发布数据处理流即可。

3、设计落地

3.1、整体设计思考

下图是数据采集系统的核心设计结构
在这里插入图片描述

  • 数据汇聚层的设计思考

数据汇聚层提供两种数据汇聚能力,一种能力是支撑下层IoT设备/设备网关主动发送数据的能力,数据汇聚层提供Kafka或者Logstash作为数据的接收组件,下层IoT设备/设备网关在主动发送数据时,不需要保证数据一定满足某种规范结构,只需要保证发送的数据是可以序列化的即可。数据发送者还需要保证不同类型的IoT设备/设备网关发送到不同的分组汇总,例如如果采用Kafka接受监控数据,那么不同的数据将被推送到不同的Kafka-Topic中。

数据汇聚层还提供了一个主动向下采集数据的代理程序,这个代理程序主要是服务于那些不能主动推送数据的IoT设备/集中设备,以便周期性从这些设备中取得监控数据。根据需要取得的数据不同、下层设备提供的接入方式不同,代理程序中又提供了很多种不同的数据抓取方式。例如如果下层设备支持Http协议,那么可以通过Selenium组件采集数据;如果下层设备只支持TCP/UDP传输层协议,那么可以通过Nessus/Nmap这种扫描组件进行数据采集……

代理程序完成采集后,数据将被推送到数据汇聚组件中。需要注意的是,除了在采集代理程序中设定了相关(完善)规则的数据以外,默认情况下代理程序采集到了什么样的数据,就会向数据汇聚组件中推送什么样的数据,并不会要求这些数据一定需要满足什么样的结构、格式。

  • 数据采集处理层的设计思考

数据采集处理层部署了一套Flink集群,这套Flink集群是数据采集系统进行数据收集、数据过滤、数据清洗、数据完善和数据落库操作的核心集群。这个Flink集群中各个独立的数据流都具有不同的工作逻辑,可以支持具有相同数据采集过程的一个或者多个IoT设备/设备网关。Flink集群中如何进行数据流设计,也是本文主要讨论的内容。

  • 数据层的设计思考

经过初步处理的,用于后续正式数据分析的数据,需要进行落库保存。由于主要是为数据分析服务,所以我们选择一种湖仓一体化的OLAP型数据库进行数据落库,技术选型为Starrocks。由于Starroks原生支持从Kafka中主动拉取数据进行存储,也支持通过诸如JDBC这样的外部连接进行数据操作,那么从Flink-Sink端存储数据到Starrock就至少有两种方式。方式一,从Flink-Sink推送数据到Kafka,然后在Starrocks中创建数据表,再设定从Kafka中特定的Topic中拉取数据,如下图所示:

相关文章:

  • Shell中执行.sh文件的常见方式
  • 微服务中的相关概念
  • Qt QListView自定义树状导航控件
  • 【学习】程序员资源网址
  • ASP.NET MVC-简单例子
  • 使用QT绘制简单的动态数据折线图
  • Laravel 中 使用模型作为标志
  • 多路h265监控录放开发-(1)建立head窗口并实现鼠标拖动整个窗口
  • 聊聊系统架构之负载均衡优化实践
  • 【调试笔记-20240618-Windows-pnpm 更新出现 Cannot find module 问题的解决方法】
  • ​【数据结构与算法】冒泡排序:简单易懂的排序算法解析
  • 如何学习C语言
  • Excel 常用技巧(四)
  • Eureka 学习笔记(1)
  • 亿达中国武汉园区入选“武汉市科技金融工作站”及“武汉市线下首贷服务站”
  • 【干货分享】SpringCloud微服务架构分布式组件如何共享session对象
  • Angular2开发踩坑系列-生产环境编译
  • Go 语言编译器的 //go: 详解
  • HashMap ConcurrentHashMap
  • JavaScript对象详解
  • SpiderData 2019年2月23日 DApp数据排行榜
  • 规范化安全开发 KOA 手脚架
  • 容器服务kubernetes弹性伸缩高级用法
  • 深入浏览器事件循环的本质
  • 世界上最简单的无等待算法(getAndIncrement)
  • 正则学习笔记
  • 移动端高清、多屏适配方案
  • ​Spring Boot 分片上传文件
  • ${factoryList }后面有空格不影响
  • %@ page import=%的用法
  • (13)[Xamarin.Android] 不同分辨率下的图片使用概论
  • (C++17) std算法之执行策略 execution
  • (读书笔记)Javascript高级程序设计---ECMAScript基础
  • (过滤器)Filter和(监听器)listener
  • (转)VC++中ondraw在什么时候调用的
  • .NET Framework 3.5安装教程
  • .NET I/O 学习笔记:对文件和目录进行解压缩操作
  • .NET 中小心嵌套等待的 Task,它可能会耗尽你线程池的现有资源,出现类似死锁的情况
  • .Net--CLS,CTS,CLI,BCL,FCL
  • @Autowired和@Resource的区别
  • [ C++ ] STL---stack与queue
  • [2]十道算法题【Java实现】
  • [240621] Anthropic 发布了 Claude 3.5 Sonnet AI 助手 | Socket.IO 拒绝服务漏洞
  • [ACTF2020 新生赛]Include
  • [Bada开发]初步入口函数介绍
  • [bzoj1324]Exca王者之剑_最小割
  • [C# 开发技巧]实现属于自己的截图工具
  • [C++]: std::move
  • [dart学习]第四篇:函数
  • [hdu 4552] 怪盗基德的挑战书
  • [iOS]中字体样式设置 API
  • [iOS开发]事件处理与响应者链
  • [Java]面向对象-static继承
  • [JS7] 显示从0到99的100个数字
  • [Linux] Apache的配置与运用