计算机系统应用教程网站

网站首页 > 技术文章 正文

读书笔记丨《离线和实时大数据开发实战》

btikc 2024-10-30 02:07:58 技术文章 31 ℃ 0 评论


总结


本书主要介绍大数据的[基本概念][架构体系],受众偏向于[数据分析师][使用者](例如何查询优化),对于架构内部的实现细节介绍并不深入,非常适合入门;

本书主要分为三章,概览 + 离线大数据 + 实时大数据,其中离线部分的讲解收获最大,实时部分过于浅尝辄止。


概览


总体来说可以用三张图分别展示 [数据大图]、[离线数据平台]、[实时数据平台] 全貌:



DWD:Data Warehouse Detail 明细

DWS:Data Warehouse Summary 汇总

DS:Data Mart


离线数据根据应用类型数据仓库可以分为两类:

· OLTP:毫秒级、事务

· OLAP:TB/PB 级数据、毫秒/分钟/小时级


实时大数据相对离线大数据的特点:

数据无边界、(源头)触发器复杂、延迟敏感、历史数据不可(易)修复。


数据管理常见维度:

· 数据集成 ETL:extract、transform、load

· 数据质量:完整、一致、准确、及时

· 数据屏蔽:替换、发牌(shuffle 行与行洗牌算法替换)、删除、加扰(身份证 xxx)、加密


离线


离线部分主要是介绍围绕 Hadoop 生态介绍[基本原理][查询优化的手段][数仓建模理论]


一、HDFS

HDFS 是雅虎基于 GFS 灵感设计,其特点有:

· 优:TP/PB级文件、低廉处理器、高容错高可靠、一次写入多次访问

· 劣:不能低延迟 (更多是高吞吐)、无法高效处理小文件 (namenode 内存元数据爆炸,可以多 master 分片处理)、不支持并发写和随机写;低延迟和小文件更适合 HBase (HBase 没介绍)

文件被分为若干块存在 datanode,namenode 作为主管理文件的命名空间 (架构如图)


二、MR

HDFS之上是离线计算框架 MapReduce,其特点有:

· 优:易编程、扩展性、自动容错(重试)

· 劣:无法秒级响应、只能接收静态(非流)数据、不适合复杂 DAG (中间结果入盘而性能低下)

MapReduce 架构如图:

· taskTracker 以 slot 为单位调度 task

· jobTracker 发现作业失败后会重新调度。


MapReduce 运行流程如图:

· split=分片长度 + 起始位置;假设输入文件 150M,HDFS block 64M,则分片=64+64+22

· shuffle 分为 map 端和 reduce 端

→map 端首先会将结果存在内存缓冲区,到达阈值后输出到磁盘(即 spill):写磁盘过程执行 shuffle

→reduce 端先从(多个) taskTracker 本地磁盘读数据,和 map 相同 (先内存再磁盘);写磁盘过程执行 shuffle

· jobTracker 记录 map 输出和 taskTracker 关系,reduce 定期查询获知

· reduce 执行完 shuffle 后就开始执行逻辑


三、Hive

裸写 MR 成本较高,所以 Facebook 在其上抽象出类 SQL 语法的 Hive;核心逻辑是将 SQL 转化为 MR 任务。

Hive 里头的表分为内部表和外部表:

· 内部表:物理表,删除则数据也删除

· 外部表:逻辑表,删除只是删除 DDL

Hive 里头的数据通过[分区][分桶]的方式提高查询效率。

· 分区:partition,根据某字段(比如时间戳)拆分到不同的文件

· 分桶:例如基于 ID hash 拆分到不同的文件 (可以优化两个相同分桶的表间 map-join 操作)


1.查询原理

Hive 的 DDL 和 DML 操作不详细记录,用时查询即可;

重点关注 [select][group by][join] 操作的实现原理:

· select:重点是 map 操作,无 reduce & shuffle

· group by:重点是 shuffle,通常是通过 hash 作为 shuffle 方式将数据灌给 reduce

· join:和 group by 类似,区别在于这里是将两张表的相同字段作为 hash shuffle 的输入

→如果是多表在相同字段 join 则和上述一样;否则表 1 和 表 2 执行完后,再用中间结果和表 3 join。

另外可以关注下类似 impala/drill/presto/dremel 等系统,是和 Hive 对标的离线大数据查询引擎。


2.查询优化:数据倾斜

Hive 最关键的点在于查询优化,重点是[数据倾斜]带来的 reduce 不均衡的问题

· group by 导致

→将一个 MR 拆成两个,第一个随机 shuffle;第二个才是按照 key shuffle

→原理是预处理:

hive.map.aggr=true

hve.groupby.skewindata=tru


· count distinct (eg. user)

→得把所有都 shuffle 到唯一 reduce

→一般是先用 group by (eg. user) 去重再 count distinct

· 大表 join 小表

→mapjion 优化:在 map 阶段进行 join,即将小表全量发到所有的 map 节点

→例子:销售明细表 (seller, order) * 商家表 (seller, start),得到 (start, order_cnt),将商家表全量发给 map 节点

· 大表 join 大表

→转化为 mapjoin:通过限制列将某张大表先做出来一张小表

→倍数 b 表

增加无意义的 numbers 字段来作为 shuffle 的依据,减少倾斜

或者,只对 "占80%数据的选项" 填充无意义的 numbers 字段

→拆表:把 b 表分为 "多数项(大表但无倾斜)" 和 "少数项(小表)" 分别计算


3.数仓建模

数据仓库的构建本书着重介绍 Kimball 的维度建模理论(相对应是 inmon 的信息化工厂模式);该部分内容偏理论化,所以没有过于深入研究;维度建模理论中数仓主要分为两类表

· 事实表:事实,简单理解是数字

· 维度表:上下文,简单理解是特征

根据维度表设计的方式,又分为两种架构

· 星型:维度表直接连到事实表,宽表,存在数据冗余,但是用起来比较方便

· 雪花:分解更清晰,部分维度表通过其他维度表连到事实表,节省存储空间

表命名规范:dws_sls_item_m:DWS/DWS_业务领域_自定义标签_时间标签。


实时


实时部署主要是介绍[流式数据处理框架]概述各自的架构,整体讲解比较浅,所以读完后更多是对各种框架有个基本的概念,如果想要完整掌握还需要进一步查阅更多资料。


一、Storm

Storm 是 Twitter(BackType) 开源的实时数据处理框架,其对数据处理的抽象奠定了流式处理的基础

整体架构如下,整体上仍然是 master-slave 结构进行作业的分配和管理

· topology:一个作业称为一个 topology

· tuple:Storm 中传递的数据成为 tuple

· stream:一个作业的数据流称为一个 stream

· spot:源头的数据采集组件

· bolt:中间执行算子的组件

单机视角的架构如下:

一个拓扑可能有多个 worker;

worker 里的每个 executor 都是一个线程,executor=spot/bolt;

executor 里的每个 task 只能同步执行:


1.Trident

原生 Storm 只能支持 at least once 语义,所以后续版本 Storm 数据处理单位为单条记录,Trident 将源头数据分成批来处理(可以提高吞吐);每批元数据分配唯一 id(transaction id/txid),批的状态更新是有序的(批 2 更新成功前批 3 状态不会更新),重放时重放该批所有数据,通过引入事务保证 exactly once;例子:


假如当前中间状态

man -> [cnt=3, txid=1]

dog -> [cnt=4, txid=3]

apple -> [cnt=10, txid=12]

收到的批数据(txid=3)

man/man/dog

则处理完的结果如下,man 会更新但是 dog 不会再更新了。

man -> [cnt=5, txid=3]

dog -> [cnt=4, txid=3]

apple -> [cnt=10, txid=2]


2.可靠性/反压机制

spout/bolt 间会形成树状关系,可以将 tuple 中插入 msgID,通过[链式]的 ack/fail 机制来追踪该 tuple 执行情况;spout 则是自行决定是否需要重试。

流式计算的反压(back pressure)可以处理 "下游处理跟不上上游灌数据速度" 避免数据挤压导致上游内存爆涨;既可以手动设置 spout 的 max-pending,也可通过自动检测 bolt(配合 ZK watch 机制通知 spout) 的方式实现自动限制 spout 发送数据频率。


二、SparkStreaming

Spark 是伯克利大学实验室孵化的项目,起初对标的是 Hadoop,引入 RDD 支持了 DAG 运算;本书没有系统性介绍 Spark 内部实现机制(甚至概述),所以相对讲述更浅。

RDD 即 Resilient Distributed Dataset,即分布式的数据集,可以在 SparkContext 初始化时从外部数据源加载构建,后续 Spark 算子的行为就是对 RDD 进行转换(transformation)和行动(action);Spark 流计算的支持通过 mini batch 的方式实现,即构建由连续的 RDD 构建 DStream:


Spark 优化的方式:

· RDD 尽可能复用,减少重复计算;

· 算子能优化、类似 MR 的 mapjoin 优化;

· 优化并发(数据源、任务、输出),合理设置 batch size(过大则内存大单吞吐高、过小则延迟低但吞吐低);

· 解决[数据倾斜]的方式是 add salt,即 "增加无意义的 numbers 字段作为 shuffle 的依据"。


Spark 支持 exactly once 语义,因为 RDD 承担起了事务的作用;反压机制基本同 Storm。


三、Flink

Flink 是柏林理工大学孵化的项目,能够同时处理[流]和[批],[无界数据集]和[有界数据集]。

从概念上说,Flink Stream = Storm Stream = Spark DStream;此外还有 source=数据输入,sink=数据输出,transformation=数据处理,streaming dataflow 构成 "起于 source 止于 sink" 的 DAG。


Flink 里的容错机制通过 barrier 实现:在数据流中随机插入 barrier 来区分组,operator 收到数据后会进行缓存,只有收到所有数据流的 barrier 后才会做 checkpoint (本地 rockDB,并将单机同步到 HDFS),然后才继续往后发射;示意流程图如下:


Flink 里最重要也是最难以理解的是窗口的概念;Flink 数据源的数据可能因为各种原因导致[事件时间]乱序到达,实际的[处理时间]可能与其存在偏差,[事件实现斜率]代表了偏差的大小;通常做法是设置最大允许乱序时间,例如 10,那么基于 1h 的时间窗口在 08:00:10 时可以认为 08:00:00 前的数据都已经到达,可以开始执行逻辑;Flink 支持 [翻滚]、[滑动]、[session] 等多种窗口的机制:


Flink 的反压是通过组件的分布式阻塞队列实现的(队列不满才能继续发送数据)。


四、Beam

Beam 是 Google 开源的统一批流处理的编程范式,可以支持多种数据处理框架作为 Runner;Beam Model 包括四种维度的概念,开发者只需要根据 WWWH 将业务需求映射成四个维度:

· What:单行数据 or 数据聚合

· Where:采用何种窗口模式

· When:何时触发计算 (过快可能事件时间未到丢失数据,过慢延迟变长数据囤积)

· How:如何处理延迟的数据


最后, (截至本书出版时)流式处理框架中尚不存在离线大数据体系中的 "Hive" 来统一流式 SQL 引擎。


感受


本书约在半年前完成第一遍阅读,当时比较细致,最近为了整理刚完成二次阅读,主要是复习,但是效果不好,因为总觉得之前已经读过所以想快速翻阅,但是总感觉反而遗漏了很多细节,下次打算尝试随手整理;可能比较麻烦,不知道是否容易实施。


[阅读][做笔记]还是存在很大差异,后者难度明显更大(需要总结归纳),耗费精力明显更多(用清晰图例和语言重构);但是仍然整理的原因是,提炼后的内容查阅起来比翻阅原版更加直观和便捷,另外理解自己的语言会比理解别人的语言更加容易。


本书最大的特点是入门,所以很多系统介绍不够深入,后续有必要的话需要深入了解后再针对性做一些整理。



谢谢观看


文案:Wayne

编辑:Winfreg

Tags:

本文暂时没有评论,来添加一个吧(●'◡'●)

欢迎 发表评论:

最近发表
标签列表