书籍开源学习代码https://github.com/XL-lab-bigdata/BigDataArchitecture初识 MapReduce用并行的力量处理大数据在大数据时代我们面临着一个现实挑战**数据实在太多了**传统的单机处理方式早就力不从心我们必须换个思路用更多机器一起“并肩作战”来处理这些海量信息。这正是 MapReduce 发挥威力的地方。7.1什么是 MapReduceMapReduce 是由 Google 在 2004 年提出的一种分布式并行编程模型后来被 Apache Hadoop 项目实现并开源。我们可以把它看作是一种“工厂流水线”专门用于处理大规模数据集。这个模型主要分成两个阶段Map映射阶段先把任务拆解成多个“小任务”每个节点负责一部分输出键值对Key, Value。Reduce归约阶段把具有相同 Key 的所有值归并处理得出最终结果。这么设计的好处就是**可以横向扩展**我们可以在很多台机器上同时跑 Map 和 Reduce大大提升处理效率。Map 和 Reduce 到底怎么用在 MapReduce 编程模型中我们只需要写两个函数Map 函数定义接收一个K1, V1的键值对输出一组中间键值对K2, V2。比如我们有个文本文件Map 函数就会逐行读取把每个单词提取出来输出单词, 1表示该单词出现一次。伪代码长这样publicclassMapper{publicvoidmap(Longkey,Stringvalue){String[]wordsvalue.split( );for(Stringword:words){emit(word,1);// 输出 单词, 1}}}Reduce 函数定义接收 Map 阶段输出的K2, ListV2进行聚合操作最终输出K3, V3。继续上面的例子Reduce 就会把所有相同单词的值加起来得出每个单词的总次数。伪代码长这样publicclassReducer{publicvoidreduce(Stringkey,IterableIntegervalues){intcount0;for(Integervalue:values){countvalue;}write(key,count);// 输出 单词, 总次数}}举个例子单词计数假设我们有一个文本文件file01.txt内容是Hello World Bye WorldMap 阶段文件被转成如下键值对K 是行偏移量V 是行内容0, Hello World 12, Bye WorldMap 函数处理后输出Hello, 1 World, 1 Bye, 1 World, 1Shuffle 阶段自动完成MapReduce 系统自动把相同的 key 分组形成Hello, [1] World, [1, 1] Bye, [1]Reduce 阶段Reduce 对这些值求和最终输出Hello, 1 World, 2 Bye, 1就这么简单我们就实现了一个并行计算的“单词计数器”7.2 搞懂 MapReduce 的工作流程数据是怎么一步步被处理的简单来说MapReduce 的执行流程就像是一条流水线从数据输入到结果输出每一步都在大数据集群中有条不紊地进行着。从整体看MapReduce 的执行大致分几步数据输入阶段从分布式文件系统比如 HDFS中读取数据并切成多个小分片。Map 阶段每个数据分片会交给一个 Map 任务处理输出中间的键值对。Shuffle 阶段对这些中间结果进行归类、排序、分发为 Reduce 做准备。Reduce 阶段汇总每一类数据生成最终结果。输出阶段将最终结果写入分布式文件系统中。我们可以把整个流程看作是“多工并行 分工协作”既有自动调度也能保证处理效率Map 任务的四个小秘密并行处理的关键在 MapReduce 的工作流程中Map 阶段是我们处理数据的“第一道工序”也是整个并行计算的起点。那么Map 任务到底有什么特别之处呢我们总结出了四个关键点带你快速掌握 Map 阶段的核心机制1. Map 任务数量影响效率但不是越多越好首先Map 任务的数量是由输入数据被切成了多少个“分片”Input Split决定的。假设我们把一个超大的文件切成了 10 片那就会启动 10 个 Map 任务并行处理。并行任务多效率就高吗这在大数据处理时通常是对的但也有例外。如果数据量太小还硬要分成几十片反而会因为创建任务和管理资源的开销太大导致“用力过猛反而变慢”。所以我们要根据数据规模灵活设置 Map 数量找到处理效率和资源利用的平衡点。2. Map 有“就地加工”能力数据本地化MapReduce 有个非常聪明的设计数据在哪就在哪处理我们称之为“数据本地化”。比如数据A存在机器A上那就优先在这台机器上启动 Map 任务处理它这样可以大大减少网络传输的时间和成本。当然啦如果那台机器太忙系统也会退而求其次找一台“离得近的”机器来处理只不过这时候就得走一段“数据搬家”的流程效率会打点折扣。3. Map 的输出是啥中间的“半成品”Map 阶段处理完一个分片的数据会生成一堆Key, Value键值对——这就是我们说的“中间结果”。这些结果会临时保存在本地磁盘等待接下来的 Reduce 阶段进一步归并、统计或处理。你可以把它理解成是“工厂流水线上的中转产品”。4. Map 任务出错也不怕自动重启机制真实的大数据集群里不可避免会有某些节点偶尔“罢工”。如果某个 Map 任务执行失败Hadoop 会自动在其他空闲节点上重启它保证整个任务能顺利跑完。这也是 MapReduce 天生具备“容错性”的体现之一让我们在处理海量数据时更加放心。深入了解 Reduce 任务MapReduce 的“压轴好戏”在上一节我们聊了 Map 任务的处理逻辑相信你已经对数据的“分片并行处理”有了基本了解。现在轮到 MapReduce 的“下半场主角”登场了——Reduce 任务。这个阶段可以说是前面所有努力的“收官总结”。今天我们就来一起揭开 Reduce 的四大特点看它是如何把海量数据归整成我们最终需要的结果的1Reduce 没有“数据本地化”优势还记得我们说 Map 任务有“数据本地化”优势吗也就是说它可以“就地处理”不需要在节点之间搬来搬去。可惜的是Reduce 并不享有这种特权。为什么呢因为 Map 阶段的输出结果要被发送给不同的 Reduce 任务而这些任务大概率不在原来的 Map 节点上。所以Reduce 阶段就不可避免地要走一段“跨节点搬运工”的流程通过网络把数据拉过来再处理。这也意味着在 Reduce 阶段网络带宽成了影响性能的一个关键因素。2单个 Reduce 任务的处理流程全场数据一口吃掉如果我们只配置了1 个 Reduce 任务那会发生什么呢很简单所有 Map 输出的数据都集中到这一个 Reduce 任务处理相当于“全场唯一出品人”。虽然实现简单但这种方式容易成为瓶颈尤其是当数据量很大的时候。数据从多个 Map 节点通过网络传输到一个 Reduce 节点然后执行排序、归并、处理逻辑最后输出一个结果文件。适合小数据量处理或你确实只需要一个最终结果的情况比如统计总销售额之类的任务。3多个 Reduce 任务并行归并更高效在实际应用中我们往往会设置多个 Reduce 任务进行“并行归并”效率自然更高。那系统是怎么知道哪个Key, Value应该送到哪个 Reduce 呢这就靠分区函数来决定。默认的分区函数是“哈希分区”它会根据键的哈希值对 Reduce 任务总数取模也就是hash(key) % R结果一样的就归到同一个 Reduce。这样做的好处是相同 Key 的数据一定在同一个 Reduce 任务中处理不会漏不会重不会乱每个 Reduce 都独立处理自己的键值对各产一个输出文件相当于我们“多人分工合作”最后集合所有人的成果。4Reduce 输出结果不止保存还自动备份Reduce 任务处理完数据后输出的结果会先保存在本地磁盘上但这不是“完事大吉”。为了提高数据的可靠性和防止节点故障导致数据丢失系统还会自动将结果文件复制一份到其他节点上形成冗余备份。这就像把重要文件不仅保存本地还上传云盘一份确保“稳如老狗”。什么是 CombinerMapReduce 的“节流阀”来了Combiner 是一个介于 Map 和 Reduce 之间的“中间处理器”。它出现在每一个 Map 任务之后在数据发送到 Reduce 节点之前先做一轮本地的初步归约处理。换句话说它就像一个“迷你版的 Reduce 函数”帮我们提前做了一部分聚合工作从而大大减少后续要发送给 Reduce 节点的数据量。理解 MapReduce 执行流程一步步读懂大数据的幕后魔法MapReduce 这条“数据流水线”到底是怎么运作的下面我们一起来拆解 MapReduce 的整个执行流程看看它从读取数据到输出结果背后都做了哪些事。一图了解 MapReduce 的运行逻辑简单来说MapReduce 的执行过程可以分为五大阶段开始任务输入阶段划分 InputSplitMap 阶段生成中间结果Shuffle 阶段分区排序合并Reduce 阶段拉取并聚合输出阶段写入 HDFS任务完成输入阶段准备数据Map 阶段并行处理数据产出中间结果Shuffle 阶段对中间结果分类打包Reduce 阶段聚合计算输出阶段写入结果第一步输入阶段一切从数据开始。MapReduce 首先通过 InputFormat输入格式来定位并读取我们要处理的数据Step 1定位数据的存储路径比如 HDFS 路径Step 2遍历路径下的每个文件Step 3把文件逻辑上划分为多个“分片”Input Split默认每个分片大小是 HDFS 的一个块大小比如 128MB。注意这里只是划分“元数据”不会真的把文件切开。这些分片正是后面 Map 任务的“作业单”。️ 第二步Map 阶段到了 Map 阶段就开始动真格了。Step 4系统根据分片数向 YARN 申请资源并启动等数量的 Map 任务Step 5每个 Map 任务处理对应的分片内容通常按行读取执行我们自定义的 Map 函数生成Key, Value形式的中间结果。如果设置了 Combiner这时候还可以对结果做一次“本地聚合”减少后续网络传输量我们上一篇有详细讲解。第三步Shuffle 阶段重头戏Shuffle 是连接 Map 和 Reduce 的桥梁也是整个流程中最复杂、最关键的部分。它负责Step 6Map 输出的键值对先写入环形缓冲区默认大小 100MB按键排序并根据 Reduce 数量进行“分区”Step 7缓冲区数据到达阈值默认 80%后写入本地磁盘生成多个“溢写文件”Step 8最终这些溢写文件会被合并成一个大文件每个分区的数据已经排好序准备好传给相应的 Reduce 任务。 Map 端的 Shuffle 工作就像在打包快递每个包裹键值对按收件人Reduce分类包装好、贴好地址标签等快递员Reduce来取件。第四步Reduce 阶段到了 Reduce 阶段就是“汇总和出报告”的时候了。Step 9每个 Reduce 任务会从各个 Map 节点“拉取”自己的分区数据Step 10拉取的数据会先在本地排序、聚合然后执行我们自定义的 Reduce 函数比如求和、平均值、最大最小等。在这个阶段所有同一个 Key 的 Value 列表都会被聚在一起统一处理最终得出结果。第五步输出阶段最后的成果也不能随便扔需要通过 OutputFormat 进行验证和格式化Step 11Reduce 的输出结果会被写入到 HDFS 或其他分布式存储系统中也会做备份来保证可靠性。至此一整个 MapReduce 任务就宣告完成啦7.3MapReduce 数据类型与输入输出格式解析从源码到实际应用在我们使用 MapReduce 处理大数据的过程中数据的输入、传输和输出都围绕着一套特定的“键值对”格式在运作。那么这些键值对到底是什么类型它们是怎么从文件变成我们程序中能处理的格式的又是如何被最终写入结果文件或数据库的现在就带大家一探 MapReduce 的“数据之路”从数据类型的选用到输入/输出格式的转换帮你打通大数据处理流程的“任督二脉”。一切皆键值MapReduce 的核心数据结构MapReduce 的数据传递离不开Key, Value键值对这一形式。Map 函数输入输出K1, V1 → List(K2, V2)Reduce 函数输入输出K2, List(V2) → K3, V3这意味着从读取数据开始到最终写出结果中间的每一个阶段都在处理键值对只不过类型可能不同。数据类型是怎么决定的Hadoop 为我们定义了一整套可序列化的数据类型它们和 Java 的基础类型一一对应例如Hadoop 类型Java 类型用途说明IntWritableint整数值LongWritablelong长整型偏移量等TextString文本行内容NullWritablenull空值不需要 key 或 valueMapWritable / ArrayWritableMap / Array复杂数据结构存储输入格式 InputFormat文件如何变成键值对在 MapReduce 中我们不能直接把文本文件交给 Map 函数处理。得先把文件“翻译”成Key, Value的结构。这正是InputFormat的工作。InputFormat做了两件事分片Split数据把输入文件逻辑上划分为若干分片每个分片对应一个 Map 任务。生成键值对把每个分片进一步切成一条条记录每条记录对应一个Key, Value类名说明TextInputFormat默认格式每行作为一条记录KeyValueTextInputFormat用“\t”切分键和值SequenceFileInputFormat读取二进制键值文件DBInputFormat从数据库中读取记录输出格式 OutputFormat如何保存最终结果处理完数据后结果去哪儿了这就交给OutputFormat来决定。OutputFormat 实现类输出形式TextOutputFormat默认以文本形式输出SequenceFileOutputFormat输出为 Hadoop 二进制文件DBOutputFormat直接输出到数据库表中番外分片大小是怎么定的默认情况下一个分片的大小等于 HDFS 的 blockSize128MB。但 MapReduce 会做一些聪明的判断来避免出现太多“碎片”如果最后一个分片太小比如 blockSize × 0.1MapReduce 可能会不再切分------------------- | ------------------------ ||TextOutputFormat| 默认以文本形式输出 ||SequenceFileOutputFormat| 输出为 Hadoop 二进制文件 ||DBOutputFormat| 直接输出到数据库表中 |番外分片大小是怎么定的默认情况下一个分片的大小等于 HDFS 的 blockSize128MB。但 MapReduce 会做一些聪明的判断来避免出现太多“碎片”如果最后一个分片太小比如 blockSize × 0.1MapReduce 可能会不再切分系统使用了一个叫SPLIT_SLOP的比例默认 1.1来判断分片是否合理避免浪费计算资源。
大数据管理与应用系列丛书《大数据平台架构》(吕欣等著)读书笔记-MapReduce
书籍开源学习代码https://github.com/XL-lab-bigdata/BigDataArchitecture初识 MapReduce用并行的力量处理大数据在大数据时代我们面临着一个现实挑战**数据实在太多了**传统的单机处理方式早就力不从心我们必须换个思路用更多机器一起“并肩作战”来处理这些海量信息。这正是 MapReduce 发挥威力的地方。7.1什么是 MapReduceMapReduce 是由 Google 在 2004 年提出的一种分布式并行编程模型后来被 Apache Hadoop 项目实现并开源。我们可以把它看作是一种“工厂流水线”专门用于处理大规模数据集。这个模型主要分成两个阶段Map映射阶段先把任务拆解成多个“小任务”每个节点负责一部分输出键值对Key, Value。Reduce归约阶段把具有相同 Key 的所有值归并处理得出最终结果。这么设计的好处就是**可以横向扩展**我们可以在很多台机器上同时跑 Map 和 Reduce大大提升处理效率。Map 和 Reduce 到底怎么用在 MapReduce 编程模型中我们只需要写两个函数Map 函数定义接收一个K1, V1的键值对输出一组中间键值对K2, V2。比如我们有个文本文件Map 函数就会逐行读取把每个单词提取出来输出单词, 1表示该单词出现一次。伪代码长这样publicclassMapper{publicvoidmap(Longkey,Stringvalue){String[]wordsvalue.split( );for(Stringword:words){emit(word,1);// 输出 单词, 1}}}Reduce 函数定义接收 Map 阶段输出的K2, ListV2进行聚合操作最终输出K3, V3。继续上面的例子Reduce 就会把所有相同单词的值加起来得出每个单词的总次数。伪代码长这样publicclassReducer{publicvoidreduce(Stringkey,IterableIntegervalues){intcount0;for(Integervalue:values){countvalue;}write(key,count);// 输出 单词, 总次数}}举个例子单词计数假设我们有一个文本文件file01.txt内容是Hello World Bye WorldMap 阶段文件被转成如下键值对K 是行偏移量V 是行内容0, Hello World 12, Bye WorldMap 函数处理后输出Hello, 1 World, 1 Bye, 1 World, 1Shuffle 阶段自动完成MapReduce 系统自动把相同的 key 分组形成Hello, [1] World, [1, 1] Bye, [1]Reduce 阶段Reduce 对这些值求和最终输出Hello, 1 World, 2 Bye, 1就这么简单我们就实现了一个并行计算的“单词计数器”7.2 搞懂 MapReduce 的工作流程数据是怎么一步步被处理的简单来说MapReduce 的执行流程就像是一条流水线从数据输入到结果输出每一步都在大数据集群中有条不紊地进行着。从整体看MapReduce 的执行大致分几步数据输入阶段从分布式文件系统比如 HDFS中读取数据并切成多个小分片。Map 阶段每个数据分片会交给一个 Map 任务处理输出中间的键值对。Shuffle 阶段对这些中间结果进行归类、排序、分发为 Reduce 做准备。Reduce 阶段汇总每一类数据生成最终结果。输出阶段将最终结果写入分布式文件系统中。我们可以把整个流程看作是“多工并行 分工协作”既有自动调度也能保证处理效率Map 任务的四个小秘密并行处理的关键在 MapReduce 的工作流程中Map 阶段是我们处理数据的“第一道工序”也是整个并行计算的起点。那么Map 任务到底有什么特别之处呢我们总结出了四个关键点带你快速掌握 Map 阶段的核心机制1. Map 任务数量影响效率但不是越多越好首先Map 任务的数量是由输入数据被切成了多少个“分片”Input Split决定的。假设我们把一个超大的文件切成了 10 片那就会启动 10 个 Map 任务并行处理。并行任务多效率就高吗这在大数据处理时通常是对的但也有例外。如果数据量太小还硬要分成几十片反而会因为创建任务和管理资源的开销太大导致“用力过猛反而变慢”。所以我们要根据数据规模灵活设置 Map 数量找到处理效率和资源利用的平衡点。2. Map 有“就地加工”能力数据本地化MapReduce 有个非常聪明的设计数据在哪就在哪处理我们称之为“数据本地化”。比如数据A存在机器A上那就优先在这台机器上启动 Map 任务处理它这样可以大大减少网络传输的时间和成本。当然啦如果那台机器太忙系统也会退而求其次找一台“离得近的”机器来处理只不过这时候就得走一段“数据搬家”的流程效率会打点折扣。3. Map 的输出是啥中间的“半成品”Map 阶段处理完一个分片的数据会生成一堆Key, Value键值对——这就是我们说的“中间结果”。这些结果会临时保存在本地磁盘等待接下来的 Reduce 阶段进一步归并、统计或处理。你可以把它理解成是“工厂流水线上的中转产品”。4. Map 任务出错也不怕自动重启机制真实的大数据集群里不可避免会有某些节点偶尔“罢工”。如果某个 Map 任务执行失败Hadoop 会自动在其他空闲节点上重启它保证整个任务能顺利跑完。这也是 MapReduce 天生具备“容错性”的体现之一让我们在处理海量数据时更加放心。深入了解 Reduce 任务MapReduce 的“压轴好戏”在上一节我们聊了 Map 任务的处理逻辑相信你已经对数据的“分片并行处理”有了基本了解。现在轮到 MapReduce 的“下半场主角”登场了——Reduce 任务。这个阶段可以说是前面所有努力的“收官总结”。今天我们就来一起揭开 Reduce 的四大特点看它是如何把海量数据归整成我们最终需要的结果的1Reduce 没有“数据本地化”优势还记得我们说 Map 任务有“数据本地化”优势吗也就是说它可以“就地处理”不需要在节点之间搬来搬去。可惜的是Reduce 并不享有这种特权。为什么呢因为 Map 阶段的输出结果要被发送给不同的 Reduce 任务而这些任务大概率不在原来的 Map 节点上。所以Reduce 阶段就不可避免地要走一段“跨节点搬运工”的流程通过网络把数据拉过来再处理。这也意味着在 Reduce 阶段网络带宽成了影响性能的一个关键因素。2单个 Reduce 任务的处理流程全场数据一口吃掉如果我们只配置了1 个 Reduce 任务那会发生什么呢很简单所有 Map 输出的数据都集中到这一个 Reduce 任务处理相当于“全场唯一出品人”。虽然实现简单但这种方式容易成为瓶颈尤其是当数据量很大的时候。数据从多个 Map 节点通过网络传输到一个 Reduce 节点然后执行排序、归并、处理逻辑最后输出一个结果文件。适合小数据量处理或你确实只需要一个最终结果的情况比如统计总销售额之类的任务。3多个 Reduce 任务并行归并更高效在实际应用中我们往往会设置多个 Reduce 任务进行“并行归并”效率自然更高。那系统是怎么知道哪个Key, Value应该送到哪个 Reduce 呢这就靠分区函数来决定。默认的分区函数是“哈希分区”它会根据键的哈希值对 Reduce 任务总数取模也就是hash(key) % R结果一样的就归到同一个 Reduce。这样做的好处是相同 Key 的数据一定在同一个 Reduce 任务中处理不会漏不会重不会乱每个 Reduce 都独立处理自己的键值对各产一个输出文件相当于我们“多人分工合作”最后集合所有人的成果。4Reduce 输出结果不止保存还自动备份Reduce 任务处理完数据后输出的结果会先保存在本地磁盘上但这不是“完事大吉”。为了提高数据的可靠性和防止节点故障导致数据丢失系统还会自动将结果文件复制一份到其他节点上形成冗余备份。这就像把重要文件不仅保存本地还上传云盘一份确保“稳如老狗”。什么是 CombinerMapReduce 的“节流阀”来了Combiner 是一个介于 Map 和 Reduce 之间的“中间处理器”。它出现在每一个 Map 任务之后在数据发送到 Reduce 节点之前先做一轮本地的初步归约处理。换句话说它就像一个“迷你版的 Reduce 函数”帮我们提前做了一部分聚合工作从而大大减少后续要发送给 Reduce 节点的数据量。理解 MapReduce 执行流程一步步读懂大数据的幕后魔法MapReduce 这条“数据流水线”到底是怎么运作的下面我们一起来拆解 MapReduce 的整个执行流程看看它从读取数据到输出结果背后都做了哪些事。一图了解 MapReduce 的运行逻辑简单来说MapReduce 的执行过程可以分为五大阶段开始任务输入阶段划分 InputSplitMap 阶段生成中间结果Shuffle 阶段分区排序合并Reduce 阶段拉取并聚合输出阶段写入 HDFS任务完成输入阶段准备数据Map 阶段并行处理数据产出中间结果Shuffle 阶段对中间结果分类打包Reduce 阶段聚合计算输出阶段写入结果第一步输入阶段一切从数据开始。MapReduce 首先通过 InputFormat输入格式来定位并读取我们要处理的数据Step 1定位数据的存储路径比如 HDFS 路径Step 2遍历路径下的每个文件Step 3把文件逻辑上划分为多个“分片”Input Split默认每个分片大小是 HDFS 的一个块大小比如 128MB。注意这里只是划分“元数据”不会真的把文件切开。这些分片正是后面 Map 任务的“作业单”。️ 第二步Map 阶段到了 Map 阶段就开始动真格了。Step 4系统根据分片数向 YARN 申请资源并启动等数量的 Map 任务Step 5每个 Map 任务处理对应的分片内容通常按行读取执行我们自定义的 Map 函数生成Key, Value形式的中间结果。如果设置了 Combiner这时候还可以对结果做一次“本地聚合”减少后续网络传输量我们上一篇有详细讲解。第三步Shuffle 阶段重头戏Shuffle 是连接 Map 和 Reduce 的桥梁也是整个流程中最复杂、最关键的部分。它负责Step 6Map 输出的键值对先写入环形缓冲区默认大小 100MB按键排序并根据 Reduce 数量进行“分区”Step 7缓冲区数据到达阈值默认 80%后写入本地磁盘生成多个“溢写文件”Step 8最终这些溢写文件会被合并成一个大文件每个分区的数据已经排好序准备好传给相应的 Reduce 任务。 Map 端的 Shuffle 工作就像在打包快递每个包裹键值对按收件人Reduce分类包装好、贴好地址标签等快递员Reduce来取件。第四步Reduce 阶段到了 Reduce 阶段就是“汇总和出报告”的时候了。Step 9每个 Reduce 任务会从各个 Map 节点“拉取”自己的分区数据Step 10拉取的数据会先在本地排序、聚合然后执行我们自定义的 Reduce 函数比如求和、平均值、最大最小等。在这个阶段所有同一个 Key 的 Value 列表都会被聚在一起统一处理最终得出结果。第五步输出阶段最后的成果也不能随便扔需要通过 OutputFormat 进行验证和格式化Step 11Reduce 的输出结果会被写入到 HDFS 或其他分布式存储系统中也会做备份来保证可靠性。至此一整个 MapReduce 任务就宣告完成啦7.3MapReduce 数据类型与输入输出格式解析从源码到实际应用在我们使用 MapReduce 处理大数据的过程中数据的输入、传输和输出都围绕着一套特定的“键值对”格式在运作。那么这些键值对到底是什么类型它们是怎么从文件变成我们程序中能处理的格式的又是如何被最终写入结果文件或数据库的现在就带大家一探 MapReduce 的“数据之路”从数据类型的选用到输入/输出格式的转换帮你打通大数据处理流程的“任督二脉”。一切皆键值MapReduce 的核心数据结构MapReduce 的数据传递离不开Key, Value键值对这一形式。Map 函数输入输出K1, V1 → List(K2, V2)Reduce 函数输入输出K2, List(V2) → K3, V3这意味着从读取数据开始到最终写出结果中间的每一个阶段都在处理键值对只不过类型可能不同。数据类型是怎么决定的Hadoop 为我们定义了一整套可序列化的数据类型它们和 Java 的基础类型一一对应例如Hadoop 类型Java 类型用途说明IntWritableint整数值LongWritablelong长整型偏移量等TextString文本行内容NullWritablenull空值不需要 key 或 valueMapWritable / ArrayWritableMap / Array复杂数据结构存储输入格式 InputFormat文件如何变成键值对在 MapReduce 中我们不能直接把文本文件交给 Map 函数处理。得先把文件“翻译”成Key, Value的结构。这正是InputFormat的工作。InputFormat做了两件事分片Split数据把输入文件逻辑上划分为若干分片每个分片对应一个 Map 任务。生成键值对把每个分片进一步切成一条条记录每条记录对应一个Key, Value类名说明TextInputFormat默认格式每行作为一条记录KeyValueTextInputFormat用“\t”切分键和值SequenceFileInputFormat读取二进制键值文件DBInputFormat从数据库中读取记录输出格式 OutputFormat如何保存最终结果处理完数据后结果去哪儿了这就交给OutputFormat来决定。OutputFormat 实现类输出形式TextOutputFormat默认以文本形式输出SequenceFileOutputFormat输出为 Hadoop 二进制文件DBOutputFormat直接输出到数据库表中番外分片大小是怎么定的默认情况下一个分片的大小等于 HDFS 的 blockSize128MB。但 MapReduce 会做一些聪明的判断来避免出现太多“碎片”如果最后一个分片太小比如 blockSize × 0.1MapReduce 可能会不再切分------------------- | ------------------------ ||TextOutputFormat| 默认以文本形式输出 ||SequenceFileOutputFormat| 输出为 Hadoop 二进制文件 ||DBOutputFormat| 直接输出到数据库表中 |番外分片大小是怎么定的默认情况下一个分片的大小等于 HDFS 的 blockSize128MB。但 MapReduce 会做一些聪明的判断来避免出现太多“碎片”如果最后一个分片太小比如 blockSize × 0.1MapReduce 可能会不再切分系统使用了一个叫SPLIT_SLOP的比例默认 1.1来判断分片是否合理避免浪费计算资源。