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

第12章:【系统架构设计师】系统架构设计-数据流风格

1.概述

1.1基本概念

数据流风格将软件系统视为一系列的处理单元,这些处理单元接收输入数据,对其进行处理,并产生输出数据,数据就像在一条管道中流动一样,从一个处理单元传递到下一个处理单元。

1.2特点

数据驱动:系统的行为是由数据的流动和处理来驱动的,处理单元根据输入数据的可用性来决定是否执行相应的处理操作。

顺序性:数据在处理单元之间按照一定的顺序流动,每个处理单元完成特定的任务,就像生产线上的各个工序一样,前一个处理单元的输出作为后一个处理单元的输入,依次进行处理。

模块化:处理单元通常是相互独立的模块,具有明确的输入和输出接口,模块之间通过数据传递进行通信,这种模块化结构使得系统易于理解、开发和维护。

可扩展性:可以方便地添加新的处理单元或修改现有处理单元,只要不影响数据的流动和处理逻辑,就可以对系统进行扩展和升级,以满足不同的业务需求。

1.3优势

清晰的流程:数据的流动和处理过程清晰明了,易于理解和分析系统的功能和行为,有助于开发人员进行系统设计和调试。

模块独立性:处理单元之间的耦合度较低,每个模块可以独立开发、测试和维护,提高了软件开发的效率和质量,降低了维护成本。

可复用性:处理单元具有较高的复用性,可以在不同的数据流中重复使用,避免了重复开发,提高了软件的复用率。

1.4局限性

不适合交互式系统:对于需要实时响应用户交互的系统,数据流风格可能不太适用,因为数据的处理是按照顺序进行的,可能会导致响应延迟。

性能问题:在处理大量数据时,由于数据需要在各个处理单元之间传递和处理,可能会产生较高的性能开销,尤其是在管道 - 过滤器架构中,数据的复制和传输可能会影响系统的性能。

复杂的控制逻辑:当数据处理流程较为复杂,涉及到多个分支、循环等控制逻辑时,数据流风格的设计和实现可能会变得较为复杂,需要对数据的流动和处理进行精细的控制和管理。

2. 批处理序列

2.1核心概念

独立程序(Components): 系统被分解成一组自包含的程序(或模块、进程)。每个程序负责一个特定的、定义明确的处理功能(例如:数据验证、数据转换、计算、报告生成)。

顺序执行(Control Flow): 程序严格按照预定义的顺序执行。前一个程序必须完全完成其执行并生成输出文件后,下一个程序才能开始执行。执行顺序通常是线性的(A -> B -> C)。

文件传递(Connectors/Data Flow): 程序之间不直接通信。数据交换完全通过文件系统进行。一个程序的输出文件(作为其处理结果)成为下一个程序的输入文件。

批处理(Batch Processing): 整个序列通常作为一个作业(Job) 启动,处理一批输入数据(可能很大),最终产生一批输出结果。处理过程在用户交互之外进行(离线)。

松耦合: 程序之间通过文件接口连接,彼此独立。只要输入/输出文件的格式约定不变,程序内部实现可以独立修改。

2.2关键特征

高内聚,松耦合: 每个程序专注于单一功能(高内聚),通过文件传递数据实现松耦合。

显式数据流: 数据流通过文件非常清晰可见。

简单性: 概念简单易懂,易于设计、实现和理解。

容错(部分): 如果在某个步骤失败,可以从前一个步骤生成的输出文件重启,无需从头开始(如果初始输入文件保留)。

可重用性: 设计良好的独立程序可以在不同的批处理序列中重用。

可维护性: 由于松耦合,修改或替换单个程序相对容易,只要接口文件格式不变。

资源管理: 程序顺序执行,简化了资源(如内存、CPU)的管理和调度(尽管可能不是最有效的)。

2.3使用场景

批处理序列适合实时性要求低、数据量大、处理逻辑固定的场景,典型案例包括:

  • 金融领域:银行日终结算(每日批量处理当天所有交易,计算账户余额)、信用卡账单生成(每月汇总消费记录并生成账单)。
  • 电商领域:每日订单汇总(统计当日销售额、销量)、用户行为分析(批量处理日志生成用户画像)。
  • 数据仓库:ETL 过程(抽取 Extract、转换 Transform、加载 Load,如每日从业务库抽取数据,清洗后加载到数据仓库)。
  • 运维领域:日志分析(每晚批量处理全天系统日志,生成异常报告)、数据备份(定期批量备份数据库)。

2.4总结

批处理序列是一种历史悠久、结构清晰、模块化程度高的架构风格,特别适合处理离线、数据量大、流程定义明确且相对固定的任务。它的核心优势在于简单性、松耦合和容错重启能力。然而,其显著的性能瓶颈(由顺序执行和文件I/O引起)、灵活性不足以及不适合实时场景等缺点,使得它在现代追求高性能、低延迟、高灵活性的系统中应用受限。虽然纯粹的批处理序列架构现在较少用于构建全新的核心业务系统,但其分阶段、松耦合、通过显式接口传递数据的思想,深刻影响了后续的管道-过滤器、工作流引擎等架构模式,并且在数据处理、ETL、后台报表等特定离线场景中仍有其用武之地。

3.管道-过滤器

管道 - 过滤器(Pipe-Filter)是一种将系统功能分解为一系列数据处理组件(过滤器) 和连接组件的数据流通道(管道) 的架构风格,核心是通过 “数据流式传递 + 组件独立处理” 实现复杂流程的解耦与灵活组合。它广泛应用于数据转换、分析、处理等场景,尤其适合 “输入数据经过多步处理后生成输出” 的业务流程。

3.1核心定义

3.1.1过滤器(Filter)

定义:独立的功能组件,负责接收输入数据、对数据进行特定处理(如转换、过滤、解析、计算等),并生成输出数据。

核心特征

只关注自身的输入 / 输出数据格式,不依赖其他过滤器的内部实现(“黑盒” 特性);

增量处理数据(无需等待所有输入数据到达,处理一部分后即可输出),也可批量处理(视场景而定);

输入输出通常为 “数据流”(如字节流、对象流、记录流),格式可以是结构化(如 JSON、CSV)或非结构化(如文本、二进制)。

3.1.2管道(Pipe)

定义:连接两个过滤器的 “数据通道”,负责将前一个过滤器的输出数据传递给后一个过滤器的输入。

核心特征

单向传递数据(通常从上游过滤器到下游过滤器,极少双向);

可缓冲数据(当上游处理速度快于下游时,暂存数据避免阻塞);

不处理数据,仅负责传输(“透明” 特性),不改变数据内容。

3.2工作原理

管道 - 过滤器的运作遵循 “数据驱动的流式处理” 逻辑,流程如下:

1.数据输入:原始数据(如文件、网络流、用户输入)首先进入第一个过滤器(“起始过滤器”);

2.过滤器处理:起始过滤器对输入数据进行处理(如解析、清洗),生成中间数据;

3.管道传递:中间数据通过管道传递给下一个过滤器;

4.链式处理:后续过滤器依次重复 “处理→传递” 过程,每个过滤器仅基于前一个过滤器的输出进行处理;

5.结果输出:最后一个过滤器(“终止过滤器”)生成最终结果(如文件、报表、响应)。

3.3关键特征

1. 组件独立性(松耦合)

  • 过滤器仅依赖输入 / 输出数据的格式(接口),不关心其他过滤器的实现逻辑(例如:一个 “数据清洗” 过滤器无需知道后续 “数据聚合” 过滤器是用 Python 还是 Java 实现的);
  • 优势:修改或替换一个过滤器(如优化 “数据解析” 逻辑)时,无需调整其他过滤器,降低维护成本。

2. 可重用性

  • 同一过滤器可在不同管道中复用(只要输入输出格式匹配)。例如:一个 “JSON 转 CSV” 的过滤器,既可以用在 “日志分析” 管道,也可以用在 “报表生成” 管道。

3. 可扩展性

  • 可通过添加新过滤器扩展功能(如在 “数据清洗” 和 “数据聚合” 之间插入 “数据脱敏” 过滤器);
  • 可通过调整过滤器顺序改变流程(如将 “排序” 过滤器从 “聚合” 后移到 “清洗” 后),灵活性高。

4. 并行性

  • 只要数据就绪,多个过滤器可并行处理(例如:前一个过滤器处理第 1-100 条数据时,后一个过滤器可同时处理第 1-50 条已输出的数据),尤其适合大数据量场景。

5. 流式处理

  • 数据无需全部加载到内存即可处理(增量传递),适合处理超大规模数据(如 GB 级日志文件)或实时生成的数据流(如传感器数据)。

3.4使用场景

管道 - 过滤器适合 “数据需要经过多步连续处理,且步骤可拆分、顺序可调整” 的场景,典型包括:

1.数据转换与处理

日志分析流程(原始日志→解析→过滤敏感信息→提取关键词→统计频次→生成报告);每个步骤对应一个过滤器(解析过滤器、脱敏过滤器、提取过滤器等),管道传递日志流。

2.编译器

源代码→词法分析器(过滤器1,将代码拆分为 token)→管道→语法分析器(过滤器2,生成语法树)→管道→语义分析器(过滤器 3,检查逻辑错误)→管道→代码生成器(过滤器 4,生成机器码)。

3.ETL(抽取 - 转换 - 加载)的流式处理

与批处理 ETL 不同,流式 ETL 常用管道 - 过滤器:业务数据→抽取过滤器(从数据库抽流)→转换过滤器(清洗、格式转换)→加载过滤器(写入数据仓库),数据逐条 / 逐批传递,而非等待全量。

3.5总结

管道 - 过滤器架构通过 “过滤器独立处理 + 管道传递数据” 的模式,实现了系统的解耦、可重用、可扩展和并行处理能力,特别适合数据转换、分析、处理等 “流程化” 场景。其核心价值在于将复杂流程拆分为独立组件,通过灵活组合满足不同需求(如 Unix 管道的命令组合)。但需注意其在交互性、格式兼容性、状态共享等方面的局限性,避免在不适用场景中强行使用。

4.对比

对比维度批处理序列(Batch Processing)管道 - 过滤器(Pipe-Filter)
核心定义将数据积累为 “批次”,按预设顺序依次执行完整处理步骤,整批数据处理完成后进入下一环节。将系统拆分为独立的数据处理组件(过滤器),通过数据流通道(管道)传递数据,数据逐条 / 逐段流式处理,前序处理一部分后序即可开始。
数据处理方式批次化处理:等待数据积累到一定量(或时间点)形成 “批次”,整批数据一次性进入处理流程。流式处理:数据无需等待全量,逐条 / 逐段进入流程,前序过滤器处理一部分数据后,立即通过管道传递给后序过滤器处理。
步骤依赖性强依赖:必须等待前一个步骤完全处理完整个批次,后一个步骤才能启动(顺序阻塞)。弱依赖:只要前序过滤器输出部分数据,后序过滤器即可开始处理(可并行,非完全阻塞)。
数据传递单位以 “整个批次” 为单位传递(如 “当日所有交易记录”“月度通话日志”)。以 “数据片段” 为单位传递(如单条日志、单个 token、图像像素块)。
核心组件- 批次管理器(触发批次、监控状态)
- 处理步骤(按顺序执行的批处理单元)
- 中间存储(持久化批次数据)
- 数据源 / 输出目标(批量读写)
- 过滤器(独立数据处理组件,如解析、转换、过滤)
- 管道(连接过滤器的数据流通道,负责传输)
- (可选)格式转换过滤器(适配不同数据格式)
工作流程示例数据收集→批次打包→步骤 1(全量处理)→步骤 2(全量处理)→…→结果输出(如 “日终结算:收集当日交易→校验→计算余额→生成报表”)数据输入→过滤器 1(处理部分数据)→管道→过滤器 2(处理部分数据)→管道→…→结果输出(如 “编译器:词法分析→语法分析→语义分析→代码生成”)
数据实时性低:依赖批次积累,处理结果存在延迟(如日终结算需次日可见)。高:数据流式传递,近实时处理(如 Unix 管道命令可即时输出结果)。
中间数据处理中间结果持久化存储(如文件、数据库表),供后续步骤读取,支持故障重试(重新运行批次)。中间数据临时缓冲(内存或短生命周期存储),随流传递,不刻意持久化(除非添加专门的日志过滤器)。
并行能力弱:步骤间必须顺序执行,仅可对不同批次并行(如多日数据分批处理),同一批次内无并行。强:同一批次内的过滤器可并行执行(如过滤器 1 处理第 1-100 条数据时,过滤器 2 可同时处理第 1-50 条)。
组件可重用性低:处理步骤与批次逻辑强绑定(如 “日终结算步骤” 难以直接用于 “月度结算”)。高:过滤器仅依赖输入 / 输出格式,可跨流程重用(如 “JSON 解析过滤器” 可用于日志分析、报表生成等多个管道)。
适用场景- 非实时、大规模数据处理(如银行日终结算、电商每日销量统计)
- 周期性任务(月度账单、年度报表)
- 数据量远超内存的离线处理(PB 级数据仓库 ETL)
- 实时 / 近实时流程化处理(如编译器、图像处理 pipeline)
- 数据转换 / 过滤场景(Unix 命令行管道、日志实时分析)
- 步骤可拆分且无需全局状态的任务(流式 ETL、传感器数据处理)
典型优势1. 资源利用率高(可在业务低峰期执行)
2. 适合超大规模数据(分批降低内存压力)
3. 容错性强(批次可重跑)
1. 并行处理提升效率(数据就绪即处理)
2. 组件解耦,易扩展(增删过滤器即可调整流程)
3. 可重用性高,降低开发成本
典型局限性1. 实时性差(无法响应即时需求)
2. 灵活性低(批次规则 / 步骤修改成本高)
3. 中间存储依赖强(磁盘故障影响大)
1. 不适合强交互场景(如 GUI 实时操作响应)
2. 数据格式不匹配时需添加转换过滤器(增加复杂度)
3. 中间状态难监控(流式数据难追踪)
数据传递比喻类似 “快递批量配送”:积累多个包裹→集中分拣→集中运输→集中派送(必须等所有包裹准备好)。类似 “流水线生产”:原料逐个进入→第一道工序加工→立即传递给第二道→…→成品输出(前序未完成,后序可启动)。
http://www.lryc.cn/news/587625.html

相关文章:

  • Oracle中的INSTR函数
  • 衡石科技技术手册--仪表盘过滤控件详解
  • 空间智能-李飞飞团队工作总结(至2025.07)
  • Spring Cloud分布式配置中心:架构设计与技术实践
  • 2025前端面试题
  • (懒人救星版)CNN_Kriging_NSGA2_Topsis(多模型融合典范)深度学习+SCI热点模型+多目标+熵权法 全网首例,完全原创,早用早发SCI
  • 【前端:Typst】--let关键字的用法
  • ethers.js-5–和solidity的关系
  • Popover API 实战指南:前端弹层体验的原生重构
  • 七、深度学习——RNN
  • C语言-流程控制
  • 详解从零开始实现循环神经网络(RNN)
  • 使用 keytool 在服务器上导入证书操作指南(SSL 证书验证错误处理)
  • kafka的部署
  • Android系统的问题分析笔记 - Android上的调试方式 bugreport
  • 论文阅读:WildGS-SLAM:Monocular Gaussian Splatting SLAM in Dynamic Environments
  • 深入浅出Kafka Consumer源码解析:设计哲学与实现艺术
  • Angular 框架下 AI 驱动的企业级大前端应用开
  • Kafka 时间轮深度解析:如何O(1)处理定时任务
  • 【Python】-实用技巧5- 如何使用Python处理文件和目录
  • 计算机网络通信的相关知识总结
  • 基于GA遗传优化的多边形拟合算法matlab仿真
  • vscode/cursor怎么自定义文字、行高、颜色
  • PHP password_hash() 函数
  • 仓储智能穿梭车:提升仓库效率50%的自动化核心设备
  • Ubuntu系统下Conda的详细安装教程与Python多版本管理指南
  • 【软件架构】软件体系结构风格实现
  • I2C设备寄存器读取调试方法
  • 卷绕/叠片工艺
  • React源码3:update、fiber.updateQueue对象数据结构和updateContainer()中enqueueUpdate()阶段