读《MapReduce设计模式》

最近读了《MapReduce设计模式》,在这里记录和分享一下书中的一些思路和操作以及自己的看法,需要本书pdf的可以点击下载《MapReduce设计模式》


MapReduce是一种分布式海量数据处理的编程框架,是解决数据处理问题的通用模板

MapReduce&Hadoop

  • MapReduce(MR)作业被分为一系列运行在集群中的map和reduce任务,每个任务都运行在指定的小的数据集

  • map主要负责数据的载入,解析,转换和过滤;每个reduce任务负责处理map任务输出结果的一个子集

  • Hadoop中的map可以细分为4个阶段:record reader(解析时输入)、mapper(生成键值)、combiner(在map端预聚合,是可选的)、partitioner(根据键进行分区,每个reducer对应一个分片)

  • map的输出为中间键和中间值,会发送到reduce做后续的处理。map任务的运行会优先选择数据所在的节点,以减少数据的网络传输

  • reduce阶段分为4个阶段:shuffle(数据传输/读写)、sort(根据key排序方便后续处理)、reducer(为每个键对应的分组执行reduce)、output format(通过record writer写出结果)

概要模式

数值概要

  • 基于某个键将记录分组,并对分组结果计算一系列的聚合值。适用于要处理的是数值数据或者计数;数据可以按照某些特定的字段分组
  • 大多数情况可以通过combiner来减少网络传输的数据量;经常需要自定义partitioner来实现更好的键值分发解决数据倾斜

倒排索引概要

  • 倒排索引是:一个项标识符列表映射的一种实现。适用于快速搜索查询响应的场景,最终输出的结果是字段值到一系列包含这些字段值的记录的映射

  • 过程:mapper输出键值 -> combiner预聚合 -> partitioner分组 -> reduce聚合

  • 建立一个倒排索引的性能由以下指标决定:mapper端内容解析的计算成本、索引键的基数、每个键对应的标识符数目

  • 实现时也可以进行预聚合减少数据的传输、如果存在热点数据可以通过自定义partitioner来解决

计数器计数

  • MR框架自身提供了计数器,可以实现在map端计算一个全局的计数。不需要reduce过程聚合,提高了计数的效率。分析的效率很大程度上取决于map任务的数量以及每条记录的处理时间
// Map端获取计数器
context.getCounter(计数器名, 键值)
// Driver中获取计数结果
job.getCounters().getGroup(计数器名)

过滤模式

过滤不会改变原有的记录,通过条件筛选满足条件的子集

过滤

  • 过滤是抽取数据的子集供后续分析使用的一种机制,使用的唯一条件就是数据可以被解析为记录并且可以通过一定的准则来确定它们是否被保留
  • 过程:输入数据 -> 给定评估函数 -> 判断是否保留数据
  • 过滤只有map端,输出的结果数量和mapper的数量一致,如果文件数量过多,可以使用reducer来收集结果

布隆过滤器

  • 布隆过滤器使我们保留了属于某个预定义集合的记录,在判断的时候可能出现误判、但不会漏判
  • 过程:训练布隆过滤器 -> 进行过滤操作

Top k

  • 对于每一个mapper分别取top k,然后使用一个reducer来处理最后的运算
  • 每个mapper会产生k条记录,当有m个map任务时,reducer就需要处理m*k条记录。当k较大的时候,reducer可能会出现问题。top k只适合应用于k较小的情况

去重

  • 过滤掉数据集中重复的元素,reducer的数量可以有多个(键相同的记录会被分到同一个reducer上)
  • reducer的数目取决于每条记录的条数以及从mapper端输出的字节数
  • 也可以使用combiner,在map端进行去重,减少传输的数据量

数据组织模式

分布式系统的性能可以通过分区、分片及排序方式优化

分层模式

  • 分层模式是从数据中创建不同于原结构的新纪录,需要将数据转换为对计算更有利的结构,避免后续运算的连接操作
  • 适合数据源被外键连接或者数据是结构化且是基于行的
  • 实现:设置多个mapper,根据关联键进行分发,在reducer中对数据进行连接

分区

  • 分区是将记录进行分类,但并不关心记录的顺序,将数据集中相似的记录分成不同的、更小的数据集
  • 数据通过分区器进行分区,分区器决定每条记录发送给哪个reducer,每个reducer对应哪些分区

分箱

  • 将数据集中的每条记录归档到一个或多个类别,与分区的不同在于分区/分箱的实现方法不同。分箱模式是在map阶段对数据进行划分,减少了reduce阶段的工作量。缺点是每个mapper将为每个可能输出的箱子创建文件

全排序(p86)

  • 全排序关注的是数据从记录到记录的顺序

  • 对整个大数据集,先根据取值的范围划分一组分区,然后从最低范围内的分区开始排序,最终得到全排序的数据集

  • 主要分为两个阶段:分析阶段和排序阶段。分析阶段确定每个分区的范围;排序阶段按照范围区域的全排序分区,分别对每个分区内部进行排序,输出即为全排序

混排

  • 将一个给定的数据集完全随机化
  • 实现:map端将输入记录作为值和产生的随机键一起输出 -> reduce端对随机键进行排序,从而使得数据随机分布 -> 对值进行转换输出

连接模式

连接可以通过与小数聚集的关联来丰富数据集

连接模式的选择:取决于数据集的大小、数据的格式以及连接的类型

reduce端连接、基于布隆过滤器的reduce端连接、map端连接、笛卡尔积

内连接:两表满足关联条件的数据将被保留

左外连接:相较于内连接,左外连接还会保留左表中没有保留的数据

右外连接:相较于内连接,右外连接还会保留右表中没有保留的数据

全外连接:相较于内连接,量表没有匹配的记录都会被保留下来

反连接:全外连接减去内连接的结果

笛卡尔积:用一个表中的每一条记录匹配另一个表中的每一条记录,结果将会包含m * n条记录

reduce端连接

  • 需要将大块的数据集发送到reduce阶段,需要耗费大量的网络带宽
  • 如果数据集都非常大,reduce端连接可能是唯一的选择
  • map端如果有多个输入,需要提取外键作为键,再对记录进行标识作为值,落到reduce端处理

使用布隆过滤器的map端连接

  • 在内连接中,在map端对于不需要的数据进行过滤,可以极大的减少网络I/O损耗

  • 实现:根据满足条件的所有外键训练一个布隆过滤器,在map端根据布隆过滤器来判断记录是否满足条件

复制连接

  • 复制连接是在一个大数据集和许多的小数据集之间通过map端连接的操作

  • 除了大数据集以外,所有的数据都要在map启动阶段读入内存;只对内连接或者左外连接起作用

  • 如果发生了内存不足,需要增加JVM的大小或者使用reduce端连接

组合连接(p116)

组合连接可以在map端对许多非常大的格式化输入左连接

不需要reduce端处理,但是需要数据是预先组织好的或者是使用特定的方式预处理过得

笛卡尔积(p121)

笛卡尔积简单的将数据集中的每一条记录与其他数据集的所有记录配对


对这本书的收获就到这里了,后面还有三章,啃不动加上不常用,暂时先放一放。

你可能感兴趣的:(文能登峰)