HDFS默认快大小128M
HDFS小于一个块大小的文件不会占据整个块空间
对文件系统块检查:hdfs fsck / -files -blocks
namenode管理文件系统的命名空间,维护者文件系统及整颗树内所有文件和目录,这些信息以两个文件形式永久保存在本地磁盘上:命名空间镜像文件和编辑日志文件,也记录着每个文件各个块所在的数据节点信息
namenode容错提供两种机制:
hadoop可通过配置使namenode在多个文件系统上保存元数据的持久装填,实时同步,原子性
2.运行一个辅助namenode
定期合并编辑与命名空间镜像,通常部署到另一台单独物理机,内存需要与namenode一致
datanode 文件系统的工作节点,存储并检索数据块(受namenode调度),定期向namenode发送他们所存储的块列表
通常datanode从磁盘中读取块,对于频繁访问的文件,其对应的块可能被现实的缓存在datanode的内存中,以堆外快缓存的形式存在
用户可通过缓存吃(cache pool)中增加一个 cache directive 告诉 namenode需要缓存哪些文件及缓存多久
对于超大集群来首,内存将成为限制系统荷香扩展的瓶颈,从2.x版本开始,引入联邦HDFS,允许系统通过增加namenode实现扩展,其中每个namenode管理文件系统命名空间的一部分,如/usr目录下所有文件
在hadoop2.X版本以后,当活动namenode失效,备用namenode就会接管它,实现这一目标需要架构上做如下修改:
1.namenode之间需要通过高可用共享存储实现编辑日志的共享
2.datanode需要同时向两个namenode发送数据块处理报告,因为数据块的映射信息存储在namenode内存中,而非磁盘
3.客户端需要使用特定的机制来处理namenode失效问题
4.辅助namenode的角色被备用namenode所包含,设置周期性检查点
两种高可用性共享存储做出选择:
NFS过滤器或群体日志管理器
QJM是一个专用的HDFS实现,被推荐大多数HDFS部署,QJM以一组日志节点的形式运行,每次编辑必须写入多数日志界定啊,类似zookeeper
1.FileStyle open() 打开希望读取的文件,对象是DistributedFileSystem
2.DistributedFileSystem 通过远程RPC调用namenode,获取文件起始位置,对于每一个块,反回datanode地址
3.DistributedFileSystem 返回一个FSDataInputStream对象给客户端以便读取数据,FSDataInputStream转而封装DSFInputStream对象,该对象管理着datanode和namenode的 I/O
4.客户端对这个输入流调用read()方法,连接最近的文件第一个块所在的datanode,通过反复调用read方法,将数据传输到客户端
5.达到末端时,关闭datanode连接
写入文件:
1.客户端对DistributedFileSystem 对象调用create()来新建文件
2.DistributedFileSystem 对namenode创建一个RPC调用,在文件系统的命名空间中新建一个文件,此时该文件中还没有相应的数据块
3.在客户端写入数据时,DFDataOutPutStream 将他分成一个个的数据包,并写入内部队列,称为“数据队列”
4.DataStreamer处理数据队列,他的责任是挑选出适合存储数据副本的一组datanode
5.DFSOutPutStream也维护着一个内部数据包队列来等待datanode的收到确认回执,称为“确认队列”
一致模型
描述了文件读写的数据可见性
FS.create(Path(p))新建一个文件后,它能在文件系统的命名空间中立即可见:
fs.exists(P) = true
但是写入文件的内容并不能保证立即可见,即使数据流已经刷新并存储,但是文件长度显示为0,当写入数据超过一个块后,第一个数据块对新的reader就是可见的
FSDataOutputStream 调用hflush()方法,刷新目前为止写入的数据均达到所有datanode的写入管道,并且对所有新reader均可见
hflush()不保证datanode已将数据写到磁盘上,仅确保数据在datanode的内存中(如果断电,数据会丢失)
为确保数据写入磁盘上可调用hsync()代替
hadoop distcp file1 file2
hadoop distcp dir1 dir2
distcp 是作为一个MapReduce作业来实现的