1.HDFS体系结构 java
1.1介绍 node
1.2假设和目标 web
1.4 文件系统命名空间 shell
1.5 数据复制 数据库
1.5.1 Replica Placement: The First Baby Seteps apache
1.5.2 副本选择 api
1.5.3 安全模式 浏览器
1.8.1 Data Disk Failure, Heartbeats and Re-Replication
HDFS是分布式文件系统,运行在商用的硬件环境上。和其余的分布式文件系统类似。可是也有不一样,HDFS是高度容错的而且设计用来部署在低成本的硬件上。HDFS提供高吞吐量,比较适合大数据的应用。HDFS释放POSIX来启动流方式的访问文件系统数据。HDFS原来是Apache Nutch网页搜索引擎的底层服务。HDFS是Apache Hadoop Core项目的一部分。
略
HDFS有Master Slave体系结构。HDFS集群包含一个NameNode,master服务管理文件系统命名空间和控制client访问。另外有一些Datanodes,一般Cluster中一个node有一个datanode。用来管理node的空间。HDFS暴露文件系统命名空间容许用户数据保存在文件中。在内部,文件会被分为多个块而且这些块被保存在一些datanode上。Namenode执行文件系统命名空间操做,好比打开,关闭,重命名文件和目录。也决定了datanode 的块映射。Datanode为client读写请求服务。Datanode也执行block的建立,删除,根据namenode的指令复制。
Namenode和datanode是软件的一部分。HDFS使用java开发,任何支持java的设备均可以运行namenode和datanode。部署一般有一个专用的机器用来执行namenode。其余的设备运行datanode。固然也能够在一个设备上运行多个datanode,可是通常不多出现。
HDFS支持传统的分层的文件组织,一个用户或者应用程序建立目录,文件存在这些目录中。文件系统命名空间分层和其余现有的文件系统相似。能够建立,删除文件,移动文件,重命名文件。HDFS支持用户配额和访问权限。HDFS不支持硬连接或者软链接。可是HDFS不排除这些功能的实现。
Namenode维护文件系统的命名空间。任何修改文件系统命名空间或者属性都被记录在Namenode里面。一个引用程序能够指定一个文件多个副本维护在HDFS里面。这些信息也放在namenode里面。
HDFS设计用来保存大文件到一个大集群上。每一个文件都以顺序的块存储。块被复制用来容错。块的大小和复制参数能够为每一个文件配置。文件中的全部的块大小都是同样的,while users can start a new block without filling out the last block to the configured block size after the support for variable length block was added to append and hsync.
应用能够指定文件的副本个数。复制参数能够在文件建立的时候建立,以后能够修改。HDFS的文件是write-once(除了append和truncate),而且在任什么时候间都是严格的1个writer。
Namenode决定全部的关于复制的块。按期会接收一个心跳和一个block report。接受一个心跳表示datanode还活着,block report表示datanode的全部block。
副本的安置对HDFS的可靠性和性能来讲是很重要的。优化副本的安置是HDFS和其余分布式文件系统的区别。这个特性须要有不少的经验和调整。目的是机架级别的安置策略,用来提升数据可靠性,可用性和网络带宽利用。
对于很大的HDFS集群来讲,一般会传播到不少机架。不通机架间的node交互须要路过交换机。在不少状况下同一个机架下的网络带宽比不通机架下的设备带宽搞。
Namenode为每一个datanode决定rackid,经过Hadoop Rack Awareness来识别。一个最简单的策略是把副本放到不通的机架下面。这样若是整个机架错误了容许使用其余的机架下的数据。这个策略均匀的把副本分布到集群,能够很简单的让它在出现错误的时候来均衡。可是这个策略增长了写入的开销,由于要写入到多个机架下。
对于最一般的例子,复制参数是3,HDFS放置策略是若是writer在本地,那么放在本地也就是写入的那个datanode,不然随机随机选择一个datanode,第二个放在一个不通的机架下的datanode上。第三个放在相同的机架的不通datanode下。这个策略减少了机架间的传输,提升了写入性能。机架出现故障的几率远小于一个node出现错误的几率,这个策略不影响可靠性和可用性的保证。可是减小了网络带宽的使用,由于一个block只在2个机架中,而不是3个机架。可是这个策略不能让数据均匀的分布。1/3的副本在一个node中,2/3的副本在一个机架下,其余剩下的均匀的分布在剩下的机架下。这个策略提升了写入性能并无和可靠性和读性能冲突。
若是副本参数大于3,那么第4个副本或者以后的副本是随机存放的,可是每一个机架存放副本的个数有个上限,(replicas - 1) / racks + 2。
由于namenode不容许datanode拥有同一个block的多个副本,副本的最大个数,就是datanode 的个数。
Storage Types and Storage Policies支持了以后,namenode除了Rack awareness以外,还考虑了这个策略。Namenode选择node先基于rack awareness,而后检查候选node的存储需求。若是候选node没有storage type,namenode会查看其它node。若是在第一个path的node不够,那么namenode在第二个path查找storage path。
为了最小化带宽和读延迟,HDFS会尝试从最近的一个副本上读取。若是在同一个机架上面有一个可读副本,这个副本是被读取的首选。若是HDFS集群跨了多个数据中心,那么本地的数据中心会被首选。
在startup的时候,namenode会进入特别的状态叫作safemode。在safemode下,数据块的复制是不会发生的。Namenode从datanode上接受到心跳和blockreport。Blockreport包含了datanode拥有的全部block。每一个block有个副本的最小值。一个block若是在namenode中被检查完后,那么就认为是安全的。若是安全率到达某个值,那么namenode就退出安全模式。若是发现有一些数据块的副本不够,那么就会建立这些数据库的副本。
HDFS的命名空间保存在namenode上。Namenode使用事务日志叫editlog来保存记录的修改。好比建立一个新的文件,namenode就会插入一条记录到editlog。一样的修改复制参数也会在editlog上建立一条机滤。Namenode在系统的文件系统上保存editlog。整个文件系统的命名空间,包括block和文件的映射,文件系统的属性。都被保存在fsimage中。Fsimage也被保存在本地文件系统上。
Namenode在内存中,保存了整个文件系统命名空间和文件block map的快照。当namenode启动,或者出发checkpoint,就会从磁盘中把fsimage和editlog读出来,应用全部editlog上的事务,到内存中的fsimage,而后从新刷新到磁盘中的fsimage。而后能够截断,由于已经被应用到磁盘fsimage。这个过程叫checkpoint。目的是保证HDFS有一致性的文件系统元数据。尽管读取fsimage速度很快,可是增量的直接修改fsimage并不快。咱们不直接修改fsimage,而是保存在editlog中。在checkpoint的时候而后应用的fsimage上。Checkpoint的周期能够经过参数dfs.namenode.checkpoint.period 指定时间间隔来触发,也可使用dfs.namenode.checkpoint.txns指定多少个事务以后触发。若是都设置了,那么第一个触发就会checkpoint。
HDFS数据在datanode中以文件的方式被保存在本地文件系统上。Datanode不会在乎HDFS文件。HDFS数据每一个block一个文件保存在本地文件系统上。Datanode不会把全部的文件都放在一个目录下面。而是使用一个启发式结构来肯定,每一个目录的最优文件个数,而且适当的建立子目录。当datanode启动,会扫描本地文件系统,生成一个HDFS的列表,而且发送给namenode。这个report叫blockreport。
全部HDFS交互协议都是基于tcp/ip的client建立一个链接到namenode机器。使用clientprotocol和namenode交互,datanode使用datanode protocol和namenode交互。Namenode并不开启任何RPC。只是对datanode 和client的反应。
尽管存在错误,HDFS保存数据仍是可靠的。一下是一些namenode错误,datanode错误和网络分区。
每一个datanode会发送心跳信息到namenode。网络分区会致使子网的datanode和namenode 的链接中断。Namenode经过心跳信息来发现。Namenode把没有收到心跳信息的node标记为死亡,而且发送新的IO请求到这个node。任何数据在死亡的datanode不在对HDFS可用。Datanode 的死亡会致使一些block的复制参数少于指定的值。Namenode会不间断的跟踪这些须要复制的block,而且在有须要的时候启动复制。须要从新复制的理由可能不少:datanode变的不可用,副本损坏,datanode所在的硬件损坏,或者复制参数增长。
HDFS结构兼容数据再平衡框架。若是一个datanode的空闲超过了阀值,一个框架可能把数据从一个datanode移动到另一个。若是一个特定的文件请求特别高,框架会动态的建立副本而且再平衡数据。数据再平衡目前没有实现。
一个block的数据出现损坏是颇有可能的。出现损坏,多是磁盘问题,网络问题或者有bug。HDFS客户端软件实现了checksum检查HDFS文件的内容。当一个客户端建立了HDFS文件。会为每一个block计算checksum而且保存在在同一个命名空间下,独立的隐藏文件下。当client获取文件内容,须要验证每一个datanode的checksum和checksum文件中的一致。若是不一致,从副本上获取。
Fsiamge和editlog是HDFS结构的核心。若是出现损坏,会致使HDFS实例没法运行。由于这个能够配置fsimage和editlog多个副本。任何更新fsimage和editlog会同步的更新副本。同步的更新fsiamge和editlog可能会致使性能问题。然而仍是能够接受的,由于HDFS是数据敏感而不是元数据敏感的。当namenode重启会选择最新的fsimage和editlog使用。
另一个选项是使用多namenode启动HA,或者使用NFS共享存储,分布式的editlog。
快照是被支持的。快照的一个用处是修复HDFS。
HDFS被设计用来支持很是大的文件。应用使用HDFS来处理这些文件。这些应用只写一次可是要读不少次。HDFS支持write-once-read-many。一般HDFS block大小是128MB。所以HDFS会被切成128MB的块。
当client写数据到HDFS,而且复制参数是3,namenode会获取datanode的一个列表使用复制选择算法。这些列表包含了datanode 的副本block。Client而后写入第一个datanode。第一个datanode一部分一部分的接受数据,把每一个部分写到本地的存储库中而且把这部分传输到list中的第二个datanode。第二个datanode,同样接受数据,而后存储到本地存储库,而后传输到第三个datanode。第三个datanode,接受数据保存到本地存储库。所以数据是以pipeline的方式从一个到另一个。
HDFS能够以不一样的方式被访问。最原始的使用java 的API。也可使用http浏览器。HDFS能够被mount到client本地文件系统。
HDFS容许用户数据以目录和文件的方式组织。提供了命令行借口FSShell可让用户和HDFS交互。语法和bash相似。
Action |
Command |
Create a directory named /foodir |
bin/hadoop dfs -mkdir /foodir |
Remove a directory named /foodir |
bin/hadoop fs -rm -R /foodir |
View the contents of a file named /foodir/myfile.txt |
bin/hadoop dfs -cat /foodir/myfile.txt |
DFSAdmin命令主要用来管理HDFS集群。
Action |
Command |
Put the cluster in Safemode |
bin/hdfs dfsadmin -safemode enter |
Generate a list of DataNodes |
bin/hdfs dfsadmin -report |
Recommission or decommission DataNode(s) |
bin/hdfs dfsadmin -refreshNodes |
HDFS安装配置了web服务来暴露HDFS的命名空间。容许经过浏览器查看和定位文件。
若是trash配置启用了,FSShell删除的文件并不会立刻从HDFS上面删除。HDFS会把这些移动到trash目录中(/user/<username>/.Trash)。这样文件能够快速的恢复。
最近被删除的文件会被移动到当前的trash目录(/user/<username>/.Trash/Current),根据checkpoint的配置,HDFS为当前的删除建立checkpoint(/user/<username>/.Trash/<date>),到期后会删除老的checkpoint。查看 expunge command of FS shell
到期以后,namenode会删除文件的元数据。删除后会致使相关的block被回收。例子以下:
建立2个文件
$ hadoop fs -mkdir -p delete/test1
$ hadoop fs -mkdir -p delete/test2
$ hadoop fs -ls delete/
Found 2 items
drwxr-xr-x - hadoop hadoop 0 2015-05-08 12:39 delete/test1
drwxr-xr-x - hadoop hadoop 0 2015-05-08 12:40 delete/test2
删除一个文件根据提示被移动到了trash目录
$ hadoop fs -rm -r delete/test1
Moved: hdfs://localhost:9820/user/hadoop/delete/test1 to trash at: hdfs://localhost:9820/user/hadoop/.Trash/Current
删除test2,可是跳过trash
$ hadoop fs -rm -r -skipTrash delete/test2
Deleted delete/test2
最后只会看到trash中的一个文件
$ hadoop fs -ls .Trash/Current/user/hadoop/delete/
Found 1 items\
drwxr-xr-x - hadoop hadoop 0 2015-05-08 12:39 .Trash/Current/user/hadoop/delete/test1
当复制数量减小,namenode会选择多余的副本进行删除。在下一次心跳传输给datanode,datanode而后删除响应的块,释放空间。经过setReplication API设置到真正释放空间有延迟。
Hadoop JavaDoc API.
HDFS source code: http://hadoop.apache.org/version_control.html