Hadoop-分布式文件系统概述
来源:互联网 发布:mac怎么重新分区 编辑:程序博客网 时间:2024/06/08 01:17
HDFS(Hadoop Distributed File System)提供了分布式的存储服务,下面描述一下HDFS中的概念和关键原理。
数据块(Block)
数据块是HDFS存储文件的基本单位,块的默认大小为64MB(可以通过dfs.blocksize参数进行修改),MapReduce对输入数据进行分片时多数也是基于单个数据块大小来进行。
那么,数据块为什么会这么大呢?一个最主要的原因是减小磁盘寻址在一个读取中所占资源的比例,例如一次磁盘寻址需要1s,一个10MB的文件的读取时间为500sm,那么磁盘寻址的消耗就占整个任务的2/3,对于一个50M的文件呢,目前磁盘的IO速度大概位30-100M/s,假设一个100M的文件读取时间为2s,那么,磁盘寻址在整个读取任务中的消耗占比为1/3,(以上数据均为本人假设),根据当前磁盘的读取速度和实际测试结果,实际项目组通常会将数据块大小设置在60-150MB之间。
这时就会有人问,那为什么不把数据块大小设置的很大?比如1000MB?这是一个值得思考的问题,这个问题的关键在于谁读取数据,很多情况下是MapReduce(也可能是别的),以MapReduce为例,在输入分片阶段,Map任务数=数据文件大小/数据块大小,也就是说数据块约大,Map任务数据越小,这就会造成MapReduce任务负载过于集中,不能充分利用集群上的计算资源,拖慢任务,其次,集群负载倾斜很容易造成部分节点宕机或假死。
引入数据块的好处可以概括一下三点:
第一、单个文件大小不在局限于一个节点的存储能力,对于一个大文件,会按数据块大小进行分割,并存储在集群中,理论上,整个HDFS文件系统可以存储一个大小为集群最大存储容量的文件。
第二、提供了一种更高层次的抽象。HDFS只处理数据块,而不关心底层的实际存储系统,这样就可以把实际存储系统从HDFS中分离,在实际应用中,除了本地磁盘存储,还可以利用NFS或Amazon的S3作为存储介质。
第三、在数据块的基础上很容易引入复制,来提高系统的容错性和可用性。HDFS对于每个数据块都进行复制备份,默认副本数为3(可以利用dfs.replication参数修改副本数)。
查看hdfs块配置信息>hadoop fsck / -files -blockStatus: HEALTHY Total size: 47579 B Total dirs: 80 Total files: 56 Total symlinks: 0 Total blocks (validated): 41 (avg. block size 1160 B) Minimally replicated blocks: 41 (100.0 %) Over-replicated blocks: 0 (0.0 %) Under-replicated blocks: 18 (43.90244 %) Mis-replicated blocks: 0 (0.0 %) Default replication factor: 1 Average block replication: 1.0 Corrupt blocks: 0 Missing replicas: 36 (46.753246 %) Number of data-nodes: 1 Number of racks: 1FSCK ended at Wed Nov 02 03:42:54 PDT 2016 in 33 milliseconds
NameNode和DataNode
HDFS中有两种类型的节点:NameNode和DataNode。以主从的方式组织,NameNode为Master节点,DataNode为Fellower节点。
NameNode存储HDFS的命名空间、系统树结构及文件的元信息,NameNode并不参与实践的文件读写工作。
DataNode负责实际的文件读写任务,并心跳上报状态信息到NameNode,对于一个客户端请求,客户端首先RPC到NameNode获取元数据,在根据原数据RPC到DataNode做实际工作。
NameNode对于一个HDFS集群至关重要,没有NameNode整个集群将无法工作,为了保证NameNode的可用性,NameNode会将集群信息和数据信息写入本地磁盘的fsimage镜像日志和editlog编辑日志,这样当NameNode重启时,可以通过回放日志文件来恢复集群状态。为了防止NameNode节点的物理故障,还可以在另外一台物理集群上部署SecondaryNameNode,它会从NameNode节点复制数据,进行备份,单由于备份是固定频率,所以在故障恢复时,可能会造成部分数据丢失。
HDFS联邦
在传统的HDFS架构中,NameNode存在严重的单点失效问题(当NameNode出现故障,整个HDFS集群不可以),虽然fsimage和eidtlog能在一定程度上包装数据的可用性,但NameNode需要手工重启,这会造成整个集群的不可用,同时对于大型集群,NameNode的冷启动时间会很长。
第二个问题是,由于NameNode的单点运行,数据保存在内存中,当集群规模很大时,NameNode必定会成为整个集群扩展和性能瓶颈。
传统HDFS简易架构如下:
为了进一步解决NameNode的单点故障问题,在Hadoop2.x中引入了NameNode联邦机制,整体架构如下:
将NameNode进行横向拆分成多个NameNode,每一个NameNode相互独立。
NameNode联邦的优势在于:
第一、提高集群可用性。当一个NameNode挂掉,不会对其他NameNode造成影响,将故障影响最小化。
第二、提高集群扩展性。可以通过增加NameNode的方式来扩大集群可以存储的文件的数量。
第三、提高集群服务性能。一个NameNode的负载分摊到多个NameNode上,能有效提高单个NameNode的服务性能。
HDFS数据流
HDFS作为一个文件系统,对外提供两种服务:读 和 写。
下面描述一下HDFS对于读写请求的处理流程。
读(Read)
首先看一下《Hadoop权威指南》中给出的流程图
整个流程描述如下:
1.客户端根据配置信息创建代表HDFS的DistributedFileSystem对象
2.DFS对象RPC到NameNode,获取目标数据的元信息(包括块分布、DataNode地址等)
3.客户端获取指向目标DataNode的流对象FSDataInputStream
4.客户端在FSDIS对象上调用read方法,集群透明的组织分布在不同节点上的数据,并返回给客户端
5.客户端读取数据完成。
写(Write)
首先看一下《Hadoop权威指南》中给出的流程图
整个流程描述如下:
1.客户端创建代码集群的对象DistributedFileSystem
2.客户端在DFS对象上RPC到NameNode,创建一个新的文件标识
3.客户端得到一个FSDataOutputStream对象,客户端在该对象上调用write方法写入数据
4.HDFS利用机架感知功能及配置的副本数据创建一个数据流管道
5.被写入的数据在数据流管道中的节点上逐一写入而后返回
6.客户端得到写入成功确认后,关闭写入流,同时RPC到NameNode报告写入成功,NameNode记录本地操作到编辑日志editlog,写入完成
Hadoop-HDFS的整体轮廓就是这样,当然还有很多细节,后面再逐个加以讨论。
HDFS的读写一致模型
HDFS中的一致模型类似于关系数据库中的事务,可以把一个数据块Block理解为一个事务区间,单写入的数据量小于这个事务区间-即块大小时,写入的数据对外是不可见的,当然,也可以在写入的过程中调用FSDataOutputStream对象的sync()或close()方法来强制数据同步刷新到磁盘,下面看一个例子:
/** * 读写一致性. * @author zhangdong * @createtime 2016-11-03 09:28 * @location peking national library * * HDFS的一致模型可以这样理解: * 一个数据库是一个事务范围, 当写入数据的大小在一个数据块范围内时,写入数据对外界不可见。 * 可以调用FSDataOutputStream 的 sync方法或close反复来强制将数据刷新到磁盘。 * * */public class ConsistentModel { @Test public void hdfsConsistentModelTest() throws Exception{ //将本地文件写入hffs String localSrc = "E:\\New_WorkSpace\\eclipse\\bigdata_framework_hadoop\\resources\\log4j.properties"; String hdfsSrc = "hdfs://master:9000/consistentmodel1/1/a.txt"; InputStream in = new BufferedInputStream(new FileInputStream(localSrc)); Configuration conf = new Configuration(); FileSystem fs = FileSystem.get(new URI(hdfsSrc), conf); Path path = new Path(hdfsSrc); FSDataOutputStream out = fs.create(path); //IOUtils.copy(in, out, 1024); IOUtils.copyBytes(in, out, 1024); System.out.println(fs.exists(path) + "已存在"); System.out.println((fs.getFileStatus(path).getLen() == 0) + "长度为0"); out.sync(); System.out.println((fs.getFileStatus(path).getLen() != 0) + "sync-> 不为0"); IOUtils.closeStream(out); }}true已存在true长度为0truesync-> 不为0
从输出结果来看,一目了然。
HDFS的这种设计实际上是在性能和一致性上做的取舍,通常不同的应用系统对数据一致性的要求是不同的,在实际场景中可以根据具体的业务类型来把握。单值得注意的是,HDFS虽然对sync()进行了优化,但它仍然会带来很大的开销。
- Hadoop-分布式文件系统概述
- 分布式文件系统概述(ZZ)
- 分布式文件系统概述
- 分布式文件系统概述
- fastdfs分布式文件系统概述
- (一)分布式文件系统概述
- 分布式文件系统概述
- HDFS-hadoop分布式文件系统
- Hadoop分布式文件系统使用指南
- Hadoop分布式文件系统使用指南
- Hadoop分布式文件系统
- Hadoop分布式文件系统
- Hadoop HDFS分布式文件系统
- Hadoop分布式文件系统
- 分布式文件系统hadoop
- hadoop 分布式文件系统安装
- hadoop分布式文件系统
- Hadoop分布式文件系统
- 众说spring cloud和dubbo、、、
- java.util.Properties类,保存时保留注释及格式不变
- 网易视频云技术分享:移动端播放器框架搭建
- pi image shrink
- iOS VFL为scrollview添加约束
- Hadoop-分布式文件系统概述
- 在云服务器上部署项目
- java使用js引擎例子
- onMeasure学习整理
- Unity使用Random每次生成与上次不一致的随机数
- Mac开发
- android 系统UI模式的判断
- ThinkPHP框架模板文件中导入css,js文件相关问题
- 选择器