背景
先给大家介绍一下什么叫HDFS,我们生活在信息爆炸的时代,随着数据量越来越大,在一个操作系统存不下所有的数据,那么就分配到更多的操作系统管理的磁盘中,但是不方便管理和维护,迫切需要一种系统来管理多台机器上的文件,这就是分布式文件管理系统。HDFS只是分布式文件管理系统中的一种。
定义
HDFS(Hadoop Distributed File System),它是一个文件系统,用于存储文件,通过目录树来定位文件;其次,它是分布式的,由很多服务器联合起来实现其功能,集群中的服务器有各自的角色。
HDFS的使用场景:适合一次写入,多次读出的场景。一个文件经过创建、写入和关闭之后就不需要改变。
优点
缺点
1、 NameNode(nn):就是Master,它是一个主管、管理者。
管理HDFS的名称空间;
配置副本策略;
管理数据块(Block)映射信息;
处理客户端读写请求。
2、 DataNode: 就是slave。NameNode下达命令,DataNode执行实际的操作。
储存实际的数据块;
执行数据块的读写操作。
3、 Client: 就是客户端
文件切分:文件上传HDFS的时候,Client将文件切分为一个一个的Block,然后进行上传;
与NameNode进行交互,获取文件的位置信息;
与DataNode进行交互,读取或者写入数据;
Client提供一些命令来管理HDFS,比如NameNode的格式化;
Client可以通过一些命令来访问HDFS,比如对HDFS增删改查操作。
4、 Secondary NameNode: 并非NameNode的热备。当NameNode挂掉的时候,它并不能马上替换NameNode并提供服务。
辅助NameNode,分担其工作量,比如定期合并Fsimage和Edits,并推送给NameNode;
在紧急情况下,可辅助恢复NameNode。
注:NameNode的HA模式下没有2NN,其功能由Standby的NameNode实现。
Hadoop集群中的文件存储都是以块(block)的形式存储在HDFS中的。其中从Hadoop2.7.3版本开始,文件块(block size)的默认值是128MB,之前版本默认值是64MB
在HDFS中存储是以块(block)的形式存储在DataNode中的。那么在真实存储中实际文件大小和block块大小是怎么一个关系呢?
下面举例来讲述(默认HDFS块大小为128MB,文件副本为3份)。
问题1:若从客户端上传一个大小为128MB的文件,会产生多少个block块,占用多少实际物理存储
问题2:若从客户端上传一个大小为130MB的文件,会产生多少个block块,占用多少实际物理存储
根据块大小,此时应该有2个block块,其中1个块大小是128MB,1个块大小是2MB,后者占用的真实存储空间也是2MB,并不是128MB,同样由于副本的存在,总共有6个block块,其中3个块大小是128MB,3个块大小是2MB;
实际占用物理存储为130MB,其中1个文件大小是128MB,1个文件大小是2MB,同样由于副本的存在,总共占用物理存储为128MB * 3 + 2MB * 3;
块信息位置等元数据信息是存储在NameNode中的,会存2条记录。
问题3:若从客户端再上传一个大小为 24MB 的文件,那么这个block块会与问题 2 中的那个 2MB 的block块进行合并吗?
如何修改默认块(block)大小
从Hadoop2.7.3版本开始,文件块(block size)的默认值是128MB,之前版本默认值是64MB
block大小可以通过修改hdfs-site.xml文件中的dfs.blocksize对应的值来实现,若设置block大小为256MB如下:
<property>
<name>dfs.block.size</name>
<value>268435456</value>
</property>
原则:最小化寻址开销,减少网络传输
寻址时间:HDFS中找到目标文件块(block)所需要的时间。
原理:
文件块越大,寻址时间越短,但磁盘传输时间越长;
文件块越小,寻址时间越长,但磁盘传输时间越短
减少磁盘寻道时间(disk seek time):HDFS的设计是为了支持大数据操作,合适的block大小有助于减少硬盘寻道时间(平衡了硬盘寻道时间、IO时间),提高系统吞吐量。
减少NameNode内存消耗:NameNode需要在内存FSImage文件中记录DataNode中数据块信息,若block size太小,那么需要维护的数据块信息会更多。而HDFS只有一个NameNode节点,内存是极其有限的。
影响map端失败时重启时间:若map端任务出现崩溃,那么在重新启动拉起任务时会重新加载数据,而数据块的大小直接影响了加載数据的时间,例如数据块(block)越大,数据加载时间就会越长,进而该map任务的恢复时间越长。
考虑网络传输问题:在数据读写过程中,需要进行网络传输。如果block块过大,会导致网络传输的时间边长,也会因网络不稳定等因素造成程序卡顿、超时、无响应等。如果block块过小,会频繁的进行文件传输,初始化的map端对象会变多,资源占用变高、jvm增高、网络占用变多。
考虑监管时间问题:主节点监管其他节点的情况,每个节点会周期性的把完成的工作和状态的更新报告回来。若某个节点保存沉默超过预设的时间间隔,主节点“宣告”该节点状态为死亡,并把分配给这个节点的数据发到别的节点。预设的时间间隔是根据数据块 size角度估算的,若size设置不合理,容易误判节点死亡。
HDFS中块(block)为什么不能设置太大,也不能设置太小
主要取决于磁盘/网络的传输速率。[其实就是CPU、磁盘、网卡之间的协同效率,即跨物理机/机架之间文件传输速率]
如果块设置过大,
从磁盘传输数据的时间会明显大于寻址时间,导致程序在处理这块数据时,变得非常慢;
mapreduce中的map任务通常一次只处理一个块中的数据,如果块过大运行速度也会很慢;
在数据读写计算的时候,需要进行网络传输。如果block过大会导致网络传输时间增长,程序卡顿/超时/无响应。任务执行的过程中拉取其他节点的block或者失败重试的成本会过高;
namenode监管容易判断数据节点死亡。导致集群频繁产生/移除副本,占用cpu、网络、内存资源。
如果块设置过小,
存放大量小文件会占用NameNode中大量内存来存储元数据,而NameNode的物理内存是有限的;
文件块过小,寻址时间增大,导致程序一直在找block的开始位置;
操作系统对目录中的小文件处理存在性能问题,比如同一个目录下文件数量操作100万,执行"fs -l "之类的命令会卡死;
会频繁的进行文件传输,严重占用网络/CPU资源。
为什么block块大小设置为128MB
实际中,磁盘传输速率为200MB/s时,一般设定block大小为256MB
首先HDFS中平均寻址时间大概为10ms;
经过前任的大量测试发现,寻址时间为传输时间的1%时,为最佳状态,所以最佳传输时间为:
10ms/0.01=1000s=1s
目前磁盘的传输速度普遍为100MB/s,最佳block大小计算:
100MB/s*1s=100MB
所以我们设置block大小为128MB
而在实际中,
磁盘传输速率为200MB/s时,一般设定block大小为256MB;
磁盘传输速率为400MB/s时,一般设定block大小为512MB。
前磁盘的传输速度普遍为100MB/s,最佳block大小计算:
100MB/s*1s=100MB
所以我们设置block大小为128MB
而在实际中,
磁盘传输速率为200MB/s时,一般设定block大小为256MB;
磁盘传输速率为400MB/s时,一般设定block大小为512MB。