MapReduce工作机制——MapReduce的切片和数据读取

MapReduce的切片和数据读取

1. 数据块(Block)

定义:数据块是HDFS在物理上将数据分成一块一块来存储的基本单位。

作用:它是HDFS存储数据的基本单位。在HDFS中,文件会被拆分成若干个数据块,然后分别存储在不同的节点上。这种设计有助于提高数据的可靠性和读取速度。

大小:默认情况下,HDFS中的数据块大小为128 MB,但可以根据需要进行配置。

存储:每个数据块在HDFS中会有多个副本(默认情况下是3个),这些副本会存储在不同的节点上,以保证数据的高可用性和容错性。

2. 切片(split)

定义:数据切片是在逻辑上对输入数据进行的分片,它不会在磁盘上实际将数据切分成片来存储。数据切片是MapReduce程序计算输入数据的基本单位。

作用:它用于决定MapReduce作业中的Map任务(MapTask)的数量。每个数据切片通常会启动一个MapTask。

逻辑划分:数据切片根据输入数据的逻辑划分而定,它不一定与物理上的数据块边界对齐。

配置:数据切片的大小和数量可以通过配置来调整,以优化MapReduce作业的性能。

3. Mapreduce的切片机制

MapReduce的切片机制主要是指如何将输入数据划分成若干个逻辑上的片段(数据切片),以便分配给各个Map任务(MapTask)进行并行处理。切片(Split)是对输入数据的逻辑划分,每个切片对应一个Map任务。切片的大小和数量决定了Map任务的并行度和处理效率。

切片机制的工作原理主要包括四个部分:

(1) 输入格式(InputFormat)

MapReduce 框架使用输入格式来定义如何读取输入数据。常见的输入格式有:

  • FileInputFormat
  • TextInputFormat
  • CombineFileInputFormat

输入格式不仅定义了数据的读取方式,还定义了如何将数据分片。

(2) 计算切片(Calculate Splits)

当 MapReduce 作业启动时,框架会根据输入格式和输入数据的位置来计算数据切片。每个切片通常对应一个 HDFS 块,但这不是必须的,切片可以跨越多个块,也可以在一个块内生成多个切片。

(3) 生成切片(Generate Splits)

输入格式的 getSplits() 方法负责生成切片。这个方法会根据输入数据的大小和配置的切片大小来创建适当数量的切片。切片的大小可以通过以下参数来配置:

  • mapreduce.input.fileinputformat.split.minsize
  • mapreduce.input.fileinputformat.split.maxsize

(4) 分配任务(Assign Tasks)

每个生成的切片会分配给一个 Map 任务。框架会启动相应数量的 Map 任务,每个任务处理一个切片。Map 任务从切片中读取数据并进行映射操作。

4. 不同输入格式的切片机制

a. FileInputFormat

根据FileInputFormat源码分析(getSplits())

总结切片流程

(1)  程序先找到你数据存储的目录

(2)  遍历目录下的每一个文件

(3)  遍历到第一个文件      

         a:获取文件大小(size)      

         b:计算切片大小  computeSplitSize(blockSize, minSize, maxSize)   = Math.max(minSize, Math.min(maxSize, blockSize))      

        c: 默认情况下,切片大小等于块大小(blockSize) 本地模式是32M,yarn模式是128M               d: 根据切片大小开始切片(每次切片时,都要判断切完之后 剩余部分是否大于块的1.1倍,如果大于就新切一片)

        e:将切片信息写到一个规划文件中,InputSplit只记录切片的元数据信息(metadata),例如起始位置、长度、所在节点列表等

        f: 整个切片的核心过程都在getSplit()方法中完成    

执行完以上操作后把切片规划提交到yarn上,yarn的MrAppMaster根据切片规划计算开启多少个MapTask

源码中计算切片大小的方式    Math.max(minSize, Math.min(maxSize, blockSize))    

minSize由mapreduce.input.fileinputformat.split.minsize设置,不设置的默认值是1     maxSize由mapreduce.input.fileinputformat.split.maxsize 设置,不设置的默认值是Long.MaxValue 

job在提交yarn前 已经计算完成文件的切片数量 

b. TextInputFormat

TextInputFormat是FileInputFormat的若干个实现类之一。

TextInputFormat在切片时不考虑数据集整体,也就是不考虑输入路径下其他文件,而是逐个对每一个文件单独切片

它在读取单个文件数据时是按行读取的,其用来存储读取的数据的数据结构固然是键值对,键存储的是该行在整个文件中的起始字节的偏移量,键的数据类型是LongWritable。而值是这行的内容,不包括任何的行终止符,即换行符和回车符,值的数据类型是Text。

示例:(常见的TextInputFormat,同时也是框架默认选择切片策略)

#文本内容

abc def ghi

hello world

Sadge Sadge Sadge

#键值对内容

< 0, abc def ghi >

< 13, hello world >

< 26, Sadge Sadge Sadge> 

c. CombineTextInputFormat

框架默认的TextInputFormat切片机制是对任务按文件规划切片,不管文件多小,都会是一个单独的切片,都会交给一个MapTask,这样如果有大量小文件,就会产生大量的MapTask,处理效率极其低下。

CombineTextInputFormat用于小文件过多的场景,它可以将多个小文件从逻辑上规划到一个切片中,这样,多个小文件就可以交给一个MapTask处理。

若要使用,需添加以下内容(虚拟存储切片最大值可选)

示例 :

 

虚拟存储过程: 

        将输入目录下所有文件大小,依次和设置的setMaxInputSplitSize值比较,如果不大于设置的最大值,逻辑上划分一个块。如果输入文件大于设置的最大值且大于两倍,那么以最大值切割一块;当剩余数据大小超过设置的最大值且不大于最大值2倍,此时将文件均分成2个虚拟存储块(防止出现太小切片)。    

         例如setMaxInputSplitSize值为4M,输入文件大小为8.02M,则先逻辑上分成一个4M。剩余的大小为4.02M,如果按照4M逻辑划分,就会出现0.02M的小的虚拟存储文件,所以将剩余的4.02M文件切分成(2.01M和2.01M)两个文件。

切片过程:

        判断虚拟存储的文件大小是否大于setMaxInputSplitSize值,大于等于则单独形成一个切片。如果不大于则跟下一个虚拟存储文件进行合并,共同形成一个切片。

总结:

        如果文件的大小小于MaxInputSplitSize , 则文件规划成一个 如果文件的大小大于MaxInputSplitSize ,但是小于 MaxInputSplitSize*2 , 则文件规划成两个(对半分)    

        如果文件的大小大于 MaxInputSplitSize*2 ,先按照MaxInputSplitSize的大小规划一个,剩余的再进行规划.    最终按照 MaxInputSplitSize 大小来生成切片。

        将规划好的每个虚拟文件逐个累加,只要不超过 MaxInputSplitSize大小,则都是规划到一个切片中的。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值