Hadoop Block数据块详解

分块

磁盘也是由数据块组成的,一般默认大小是512字节,构建磁盘之上的文件系统一般是磁盘块的整数倍。

在HDFS系统中,为了便于文件的管理和备份,引入分块概念(block)。这里的 块 是HDFS存储系统当中的最小单位,HDFS默认定义一个块的大小为64MB。当有文件上传到HDFS上时,若文件大小大于设置的块大小,则该文件会被切分存储为多个块,多个块可以存放在不同的DataNode上,整个过程中 HDFS系统会保证一个块存储在一个datanode上 。但值得注意的是 如果某文件大小没有到达64MB,该文件并不会占据整个块空间 。

HDFS中的NameNode会记录在上述文件分块中文件的各个块都存放在哪个dataNode上,这些信息一般也称为 元信息(MetaInfo) 。元信息的存储位置由dfs.name.dir指定。

分片

当一个作业提交到Hadoop运行的时候,其中的核心步骤是MapReduce,在这个过程中传输的数据可能会很多,Hadoop会将MapReduce的输入数据划分为等长的小数据块,称为输入分片或者分片。hadoop为每个分片构建一个map任务,分片的默认实现由InputSplitFormat 类的 getSplits() 方法指定:

 

hadoop计算的分片大小不小于blockSize,并且不小于mapred.min.split.size。默认情况下,以HDFS的一个块的大小

(HDFS也是采用块管理的,但是比较大,在Hadoop1.x中默认大小是64M,Hadoop2.x中大小默认为128M)

为一个分片,即分片大小等于分块大小。当某个分块分成均等的若干分片时,会有最后一个分片大小小于定义的分片大小,则该分片独立成为一个分片。

protected static long computeSplitSize(long goalSize, long minSize,
                                long blockSize) {
    return Math.max(minSize, Math.min(goalSize, blockSize));
}

源码:

public static long max(long a, long b) {
    return (a >= b) ? a : b;
}

其中goalSize的值为:(InputFile的大小)/(配置文件中定义的mapred.map.tasks的值)

minsize的值为:配置文件mapred.min.split.size的值

blockSize的值为:128(默认情况)

其中几个变量的解释如下:

· blockSize:HDFS存储的基本单元,默认为64MB或者128MB;

· minSize:由用户设置的最小切分大小,配置项为mapred.min.split.size;

· goalSize:计算公式为"文件总大小/用户设定的Map任务个数",即用户间接期望的大小;

可以通过上述计算了解到,hadoop计算的分片大小不小于blockSize,并且不小于mapred.min.split.size。默认情况下,以HDFS的一个块的大小(默认为128M)为一个分片,即分片大小等于分块大小。当某个分块分成均等的若干分片时,会有最后一个分片大小小于定义的分片大小,则该分片独立成为一个分片。

在Hadoop1.x中默认大小是64M,Hadoop2.x中大小默认为128M,那为什么HDFS块这么大呢,又为什么Hadoop2.x中数据块更大了呢?

权威指南中说,为了最小化寻址开销,也就是让文件传输时间明显大于块的寻址时间,还有就是减轻NameNode的负担,因为在NameNode中存储这块所在数据节点的信息。但是也不能过于大,因为MapReducer中一般一个map处理一个块上的数据,如果块很大,任务数会很少(少于集群中的节点个数)这样执行效率会明显降低。

使用块有什么好处

假如上传的一个文件非常大,没有任何一块磁盘能够存储,这样这个文件就没法上传了,如果使用块的概念,会把文件分割成许多块,这样这个文件可以使用集群中的任意节点进行存储。数据存储要考虑容灾备份,以块为单位非常有利于进行备份,HDFS默认每个块备份3份,这样如果这个块上或这个节点坏掉,可以直接找其他节点上的备份块。还有就是,有的时候需要将备份数量提高,这样能够分散机群的读取负载,因为可以在多个节点中寻找到目标数据,减少单个节点读取。

HDFS里面,DataNode上的块大小默认是64MB或者128MB或256MB原因

HDFS里面,DataNode上的块大小默认是64MB或者128MB或256MB是最优的选择

为什么64MB或者128MB或256MB是最优的选择?

为什么不能远小于64MB或者128MB或256MB?

原因:(普通文件系统的数据块大小一般为4KB)减少硬盘寻道时间(disk seek time)

HDFS设计前提是支持大容量的流式数据操作,所以即使是一般的数据读写操作,涉及到的数据量都是比较大的。

假如数据块设置过少,那需要读取的数据块就比较多,

由于数据块在硬盘上非连续存储,

普通硬盘因为需要移动磁头,所以随机寻址较慢,读越多的数据块就增大了总的硬盘寻道时间。当硬盘寻道时间比io时间还要长的多时,那么硬盘寻道时间就成了系统的一个瓶颈。合适的块大小有助于减少硬盘,寻道时间,提高系统吞吐量。

减少NameNode内存消耗。

对于HDFS,他只有一个Namenode节点,他的内存相对于Datanode来说,是极其有限的。

然而,namenode需要在其内存FSImage文件中中记录在Datanode中的数据块信息,假如数据块大小设置过少,而需要维护的数据块信息就会过多,那Namenode的内存可能就会伤不起了。

为什么不能远大于64MB或者128MB或256MB?

这里主要从上层的MapReduce框架来讨论

Map崩溃问题:

系统需要重新启动,启动过程需要重新加载数据,数据块越大,数据加载时间越长,系统恢复过程越长。

监管时间问题:

主节点监管其他节点的情况,每个节点会周期性的把完成的工作和状态的更新报告回来。如果一个

节点保持沉默超过一个预设的时间间隔,主节点记录下这个节点状态为死亡,并把分配给这个节点的数据

发到别的节点。对于这个“预设的时间间隔”,这是从数据块的角度大概估算的。假如是对于64MB的数据块,我可以假设你10分钟之内无论如何也能解决了吧,超过10

分钟也没反应,那就是死了。可对于640MB或是1G

以上的数据,我应该要估算个多长的时间内?估算的时间短了,那就误判死亡了,分分钟

更坏的情况是所有节点都会被判死亡。

估算的时间长了,那等待的时间就过长了。

所以对于过大的数据块,这个“预设的时间间隔”不好估算。问题分解问题:

数据量大小是问题解决的复杂度是成线性关系的。对于同个算法,处理的数据量越大,它的时间复杂度也就越大。

约束Map输出:

在Map Reduce框架里,Map之后的数据是要经过排序才执行Reduce操作的。想想归并排序算法的思想,对小文件进行排序,然后将小文件归并成大文件的思想,然后就会懂这点了

为什么分片大小需要与HDFS数据块(分块)大小一致

hadoop将mapReduce的输入数据划分为等长的小数据块,称为输入分片或者分片,hadoop为每个分片构建一个map任务。

hadoop在存储有输入数据(HDFS中的数据)的节点上运行map任务,可以获得高性能,这就是所谓的数据本地化。所以最佳分片的大小应该与HDFS上的块大小一样,因为如果分片跨越2个数据块,对于任何一个HDFS节点(基本不肯能同时存储这2个数据块),分片中的另外一块数据就需要通过网络传输到map任务节点,与使用本地数据运行map任务相比,效率则更低!

 

已标记关键词 清除标记
相关推荐
©️2020 CSDN 皮肤主题: 书香水墨 设计师:CSDN官方博客 返回首页