数据密集型应用系统设计-批处理系统

MapReduce:批处理的基石

MapReduce 的核心思想

  • Map 阶段:将输入数据拆分为多个分片(Split),并行处理生成中间键值对(Key-Value Pairs)。

  • Shuffle 阶段:隐式阶段,负责将 Map 输出排序、分组并传输到 Reduce 节点。

  • Reduce 阶段:对中间结果按 Key 分组,进行聚合或转换,输出最终结果。

  • 编程模型

    # Map 函数:处理输入,生成中间键值对
    def map(key, value):
        for item in process(value):
            yield (intermediate_key, intermediate_value)
    # Reduce 函数:聚合相同 Key 的值
    def reduce(key, values):
        result = aggregate(values)
        yield (key, result)
    

MapReduce 执行流程

  • 输入分片(Input Splits)

    • 数据存储于分布式文件系统(如 HDFS),按固定大小(如 128MB)分片。
    • 每个分片启动一个 Map 任务,由框架自动调度到集群节点。
  • Map 阶段

    • 读取输入:从 HDFS 读取分片数据(如文本文件的一行)。
    • 执行 Map 函数:用户自定义逻辑处理数据,输出中间键值对。
    • 写入本地磁盘:Map 结果按 Key 分区(Partition)后写入节点本地磁盘(非 HDFS)。
  • Shuffle 与排序

    • Fetch 阶段:Reduce 任务从所有 Map 节点拉取对应分区的数据。
    • 排序与合并:拉取的数据按 Key 排序,合并相同 Key 的值列表。
  • Reduce 阶段

    • 执行 Reduce 函数:对排序后的键值对进行聚合(如求和、去重)。
    • 输出结果:结果写入 HDFS,每个 Reduce 任务生成一个输出文件。

MapReduce 的关键机制

  • 容错与恢复

    • Task 失败

      Map/Reduce 任务失败时,框架重新调度到其他节点执行

      已完成的 Map 任务需重新执行(因中间结果存储在失败节点的本地磁盘)。

    • 节点故障:通过心跳检测(Heartbeat)发现宕机节点,重新分配其任务。

  • 数据本地性优化

    • 将 Map 任务调度到存储输入分片的节点,避免跨网络读取数据。
    • 若本地节点繁忙,选择同一机架内的节点(机架感知策略)。
  • Combiner 优化

    • 局部聚合:在 Map 阶段后、Shuffle 前,对中间结果进行预聚合(类似 Reduce)。
    • 减少数据传输:例如 WordCount 中,Map 节点先合并相同单词的计数。

现代批处理框架

Apache Spark

  • 内存计算

    • 将中间数据缓存到内存(RDD),减少磁盘I/O。
    • 相比MapReduce,迭代算法性能提升10-100倍。
  • DAG执行引擎

    • 将作业拆分为有向无环图(DAG),优化任务调度。
    • 支持多阶段任务合并(如Map后直接Reduce,跳过Shuffle)。
  • 统一API:支持批处理(Spark Core)、流处理(Spark Streaming)、机器学习(MLlib)。

执行引擎优化

  • 向量化处理:使用SIMD指令批量处理数据(如Apache Arrow内存格式)。
  • 动态资源分配:根据任务负载动态调整CPU/内存(如YARN或Kubernetes调度器)。

存储优化:列式存储

  • Parquet/ORC格式

    • 按列存储,高压缩率(同列数据类型一致)。
    • 支持谓词下推(Predicate Pushdown),仅读取需要的列。
  • 数据分区分桶:按时间或哈希分区,加速过滤和聚合。

批处理系统架构

数据存储层

  • 分布式文件系统

    • HDFS(Hadoop Distributed File System) :分块存储(128MB/块),多副本冗余;适合存储大文件,如日志、原始数据。
    • 云存储(S3、GCS) :对象存储服务,弹性扩展,按需付费。
  • 数据湖(Data Lake)

    • 原始数据存储:支持结构化(CSV)、半结构化(JSON)、非结构化(图片)数据。
    • 列式存储格式:Parquet-高压缩率,适合OLAP查询;ORC-优化Hive查询性能,支持谓词下推。
  • 数据仓库(Data Warehouse)

    • 结构化存储:基于星型/雪花模型,优化聚合查询。
    • 代表系统:Snowflake、Redshift(云原生数仓);Hive(基于HDFS的SQL查询引擎)。

计算引擎层

  • MapReduce(Hadoop)

    • 经典批处理模型:分Map、Shuffle、Reduce三阶段。
    • 适用场景:简单ETL、离线分析。
  • Apache Spark

    • 内存计算:通过RDD(弹性分布式数据集)减少磁盘I/O。
    • DAG调度:优化任务依赖,支持多阶段流水线执行。
    • 统一API:支持批处理(Spark SQL)、流处理(Structured Streaming)、机器学习(MLlib)。
  • Apache Flink(批处理模式)

    • 流批一体:同一API处理批和流数据(DataSet API)。
    • 增量计算:优化迭代任务(如图计算、机器学习)。
  • Presto/Trino

    • 分布式SQL引擎:直接查询数据湖(如Hive表、S3文件)。
    • 联邦查询:跨数据源联合分析(如MySQL + Hive)。

资源管理层

  • Hadoop YARN

    • 资源调度:将集群资源划分为容器(Container),分配给MapReduce、Spark等任务。
    • 队列管理:支持多租户资源隔离(如生产队列 vs. 实验队列)。
  • Kubernetes

    • 容器化部署:将批处理作业封装为Pod,动态扩缩容。

    • Operator模式

      Spark Operator:在K8s上原生运行Spark作业。

      Flink Kubernetes Session:管理Flink集群生命周期。

工作流调度层

  • Apache Airflow

    • DAG定义:通过Python代码定义任务依赖关系。
    • 监控与重试:可视化任务状态,自动重试失败任务。
  • Oozie(Hadoop生态)

    • XML配置:定义MapReduce、Hive、Sqoop任务流。
    • 协调器(Coordinator) :定时触发工作流(如每天凌晨执行ETL)。

服务层

  • 数据服务API

    • RESTful API:通过HTTP接口暴露聚合结果(如统计报表)。
    • GraphQL:灵活查询数据湖中的多源数据。
  • BI与可视化工具

    • Tableau/Power BI:连接数据仓库,生成交互式仪表盘。
    • Superset:开源BI工具,支持SQL Lab直接查询。
  • 机器学习模型服务

    • 批量预测:定期生成用户推荐列表、风险评分。
    • 模型更新:每天训练新模型并发布到生产环境。

批处理应用场景

ETL(Extract, Transform, Load)

  • 数据清洗:过滤无效记录(如空值、异常值)、标准化格式(日期、货币单位)。
  • 数据转换:合并多源数据(如用户信息与订单记录关联)、计算衍生字段(如用户年龄=当前日期-出生日期)。
  • 数据加载:将处理后的数据写入目标存储(如Hive表、Snowflake数仓)。

离线机器学习

  • 特征工程:批量生成特征(如用户过去30天的购买总额)。
  • 模型训练:在分布式集群上训练分类、回归或聚类模型。
  • 离线评估:计算模型指标(如准确率、AUC)。

数据仓库构建

  • 贴源层(ODS,Operational Data Store)

    • 全量/增量同步:通过ETL工具从业务库(MySQL、Oracle)实时或定期抽取数据。
    • 数据原样存储:保留原始格式(如JSON日志、数据库表结构),不做业务逻辑处理。
    • 短期存储:通常保留最近7~30天的数据,供问题回溯使用。
  • 明细层(DWD,Data Warehouse Detail)

    • 数据清洗:处理缺失值、去重、统一格式(如时间戳标准化)。
    • 维度退化:将多张表关联为宽表(如订单表+商品表→订单明细宽表)。
    • 业务逻辑解耦:屏蔽底层业务系统的表结构差异(如不同系统的用户ID映射)。
  • 汇总层(DWS,Data Warehouse Summary)

    • 维度聚合:按时间、地域、产品等维度统计指标(如每日销售额、用户活跃数)。
    • 主题域划分:按业务主题(如交易、流量、用户)组织数据。
    • 中间结果复用:避免重复计算,加速上层应用查询。
  • 应用层(ADS,Application Data Service)

    • 业务指标封装:生成报表、BI看板所需的数据(如GMV、转化率)。
    • 跨主题整合:融合多个主题数据(如用户画像+交易数据→高价值用户列表)。
    • 数据服务化:通过API或数据接口暴露给业务系统(如推荐系统、风控系统)。
  • 维度层(DIM,Dimension)

    • 维度一致性:统一各层的维度定义(如地区、时间、产品分类)。
    • 缓慢变化维(SCD)管理:处理维度属性变化(如用户地址变更)。
    • 字典表存储:码值映射表(如状态码→中文描述)。

批处理系统优化

计算性能优化

优化方向具体措施案例/工具
内存计算 将中间数据缓存至内存,减少磁盘I/O。 Spark RDD缓存、Flink托管内存
向量化执行 使用SIMD指令批量处理数据,提升CPU利用率。 Apache Arrow、Presto向量化引擎
动态代码生成 运行时生成优化代码,避免解释执行开销。 Spark Catalyst优化器、LLVM编译
数据本地性 调度任务到数据所在节点,减少网络传输。 Hadoop机架感知、Kubernetes拓扑调度

数据倾斜处理

优化方向具体措施适用场景
Salting(加盐) 为Key添加随机前缀,将热点数据分散到多个分区。 大Key聚合(如用户ID热点)
两阶段聚合 先局部聚合(Map端Combiner),再全局聚合(Reduce端)。 高基数Key统计(如PV计数)
动态分区调整 根据数据分布自动调整分区策略(如范围分区→哈希分区)。 Spark自适应查询(AQE)
倾斜Key隔离 识别热点Key单独处理,其余正常计算。 电商大促期间头部商品订单分析

容错与一致性保障

优化方向具体措施技术实现
检查点机制 定期保存任务状态,故障时从检查点恢复。 Spark Checkpoint、Flink Savepoints
幂等性设计 确保任务重试不会导致重复结果。 数据库UPSERT、Kafka生产者幂等配置
输出提交协议 仅在所有任务成功后提交最终结果,避免部分输出。 Hadoop _SUCCESS文件、S3一致性模型
副本冗余 关键数据多副本存储,预防节点故障。 HDFS 3副本策略、RAID存储

资源效率提升

优化方向具体措施工具/框架
动态资源分配 根据负载自动扩缩容,空闲时释放资源。 Kubernetes HPA、YARN弹性调度
资源隔离 通过容器化(Docker)或队列隔离(YARN队列)避免作业间干扰。 YARN Capacity Scheduler、Mesos资源隔离
流批资源复用 共享集群运行批处理和流任务,提高资源利用率。 Flink统一运行时、Spark Structured Streaming

存储与数据管理优化

优化方向具体措施技术方案
列式存储 按列压缩存储,提升扫描效率。 Parquet、ORC格式
数据分层存储 冷热数据分离,热数据存SSD,冷数据归档低成本存储 HDFS分层存储、S3 Intelligent-Tiering
增量处理 仅处理新增数据,避免全量重跑。 Hudi/Iceberg增量更新、CDC(Change Data Capture)
数据压缩 使用高效压缩算法减少存储与传输开销。 Spark压缩配置、Kafka消息压缩

流批一体

Lambda 架构

  • 批处理层(Batch Layer):处理全量历史数据(如Hadoop、Spark),生成精准结果。
  • 速度层(Speed Layer):处理实时数据(如Flink、Kafka Streams),生成近似结果。
  • 服务层(Serving Layer):合并批和流的结果(如HBase、Redis),供查询使用。

Kappa 架构

  • 仅保留流处理层:通过流处理引擎(如Flink)重放历史数据,替代批处理层。
  • 依赖持久化事件日志:如Kafka长期存储原始数据(支持全量回放)。

流批一体的核心思想

  • 统一的数据模型

    • 批数据:视为有界流(Bounded Stream),即流的一个有限子集。
    • 流数据:视为无界流(Unbounded Stream),持续追加。
    • 统一处理语义:无论数据来自历史还是实时,均通过 事件时间(Event Time)处理时间(Processing Time) 统一管理。
  • 统一的 API

    • 声明式编程:通过同一套API(如SQL、DataStream/DataSet API)描述批和流任务。
    • 代码复用:业务逻辑(如聚合、过滤)无需为批和流分别实现。
  • 统一的运行时引擎

    • 共享执行引擎:批和流任务在同一运行时中执行(如Flink的流式运行时支持批处理优化)。
    • 资源动态分配:根据负载自动调配资源(如夜间跑批时分配更多资源)。

流批一体的技术实现

  • Apache Flink

    • 流式优先,批是流的特例

      流处理DataStream API 处理无界数据,支持事件时间、状态管理、精确一次语义。

      批处理DataSet API(旧版)或直接使用DataStream API处理有界数据,自动优化执行计划。

    • 批处理优化:对有界数据关闭冗余容错机制(如Checkpoint),减少开销。
    • 动态延迟调度:批任务优先处理关键路径数据,缩短作业完成时间。
  • Apache Spark(Structured Streaming)

    • 微批处理:将流数据切分为小批次(如1秒窗口),复用批处理引擎。
    • 连续处理模式:实验性支持低至毫秒级的延迟(类似流处理)。
全部评论

相关推荐

评论
1
1
分享

创作者周榜

更多
牛客网
牛客企业服务