HDFS

HDFS中fsck指令可以显示块信息

hdfs fsck / -files -blocks

namenode和datanode

HDFS集群有两类节点以管理节点-工作节点模式运行,即一个namenode(管理节点)和多个datanode(工作节点)。namenode管理文件系统的命令空间。它维护着文件系统树及整棵树内所有的文件和目录。这些信息以两个文件形式永久保存在本地磁盘上:命名空间镜像文件和编辑日志文件。namenode也记录着每个文件中每个块所在的数据节点信息。客户端(client)代表用户通过与namenode和datanode交互来访问整个文件系统。datanode是文件系统的工作节点。它们根据需要存储并检索数据块,并且定期向namenode发送它们所存储的块的列表。

namenode容错机制:
1.备份那些组成文件系统元数据持久状态的文件
2.运行一个辅助namenode,但它不能作为namenode。这个辅助namenode的重要作用是定期合并编辑日志与命名空间镜像,以防止编辑日志过大。这个辅助namenode保存合并后的命名空间镜像的副本,并在namenode发生故障时候启用,但是,辅助namenode保存的状态总是滞后于主节点,所以在主节点全部失效时,将存储在NFS上namenode元数据复制到辅助namenode作为新的namenode运行。

块缓存
通常datanode从磁盘中读取块,但对于访问频繁的文件,其对应的块可能被显式地缓存在datanode的内存,以堆外块缓存的形式存在。默认情况下,一个块仅缓存在一个datanode的内存中,当然也可以针对每个文件配置datanode的数量。作业调度器通过在缓存块的datanode上运行任务,可以利用缓存块的优势提高读操作的性能。缓存池是一个用于管理缓存权限和资源使用的管理性分组

联邦HDFS
联邦HDFS允许系统通过添加namenode实现扩展,其中每个namenode管理文件系统命名空间的一部分。每个namenode维护一个命名空间卷,命名空间卷是相互独立的,两两之间并不相互通信,一个namenode的失效不会影响另外一个。数据块池不再进行切分,因此集群中的datanode需要注册到每个namenode,并且存储着来自多个数据块池的数据块。

HDFS的高可用性(HA)
为了解决namenode失效问题,Hadoop2增加了HA的支持。HA配置了一对活动-备用namenode。当活动namenode失效,备用namenode就会接管它的任务并开始服务于来自客户端的请求,不会有任何明显中断。实现这一目标需要在架构上做如下修改:
1.namenode之间需要通过高可用共享存储(NFS过滤器或QJM)实现编辑日志的共享。当备用namenode接管工作之后,它将通读共享编辑日志直至末尾,以实现与活动namenode的状态同步,并继续读取由活动namenode写入的新条目。
2.datanode需要同时向两个namenode发送数据块处理报告,因为数据块的映射信息存储在namenode的内存中,而非磁盘
3.客户端需要使用特定的机制来处理namenode的失效问题,这一机制对用户是透明的。
4.辅助namenode的角色被备用namenode所包含,备用namenode为活动的namenode命名空间设置周期性检查点

故障切换与规避
系统中有一个称为故障转移控制器的新实体,管理着将活动namenode转移为备用namenode的转换过程。有多种故障转移控制器,但默认的一种是使用了ZooKeeper来确保有且仅有一个活动namenode。每一个namenode运行着一个轻量级的故障转移控制器,其工作是监视宿主namenode是否失效并在namenode失效时进行故障切换。

数据流

1.数据流之文件读取
客户端通过调用FileSystem对象的open()方法打开希望读取的文件,对于HDFS来说,这个对象是DistributedFileSystem的一个实例。DistributedFileSystem通过远程调用过程调用(RPC)来调用namenode。以确定文件起始块的位置。对于每一个块,namenode返回存有该块副本的datanode地址。此外,这些datanode根据它们与客户端的距离来排序。如果该客户端本身就是一个datanode,那么该客户端将会从保存有相应数据块副本的本地datanode读取数据。
DistributedFileSystem类返回一个FSDataInputStream对象给客户端以便读取数据。FSDataInputStream类转而封装DFSInputStream对象,该对象管理着datanode和namenode的IO。接着,客户端对这个输入流调用read()方法。存储着文件起始块的datanode地址的DFSInputStream随即连接距离最近的文件中第一个块所在的datanode。通过对数据流反复调用read()方法,可以将数据从datanode传输到客户端。到达块的末端时,DFSInputStream关闭与该datanode的连接,然后寻找到下一个块的最佳datanode。

2.数据流之剖析文件写入
客户端通过对DistributedFileSystem对象调用creat()来新建文件。DistributedFileSystem对namenode创建一个RPC调用,在文件系统的命名空间中新建一个文件,此时该文件中还没有相应的数据块。namenode执行各种不同的检查以确保这个文件不存在以及客户端有新建该文件的权限。如果这些检查均通过,namenode就会为创建新文件记录一条记录;否则文件创建失败并向客户端抛出一条IOException异常。DistributedFileSystem向客户端返回一个FSDataOutputStream对象,由此客户端开始写入数据。就像读取事件一样,FSDataOutputStream封装一个DFSoutputstream对象,该对象负责处理datanode和namenode之间的通信。

在客户端写入数据时,DFSOutputStream将它分成一个个的数据包,并写入内部队列,称为“数据队列”。客户端完成数据的写入后,对数据流调用close()方法,该操作将剩余的所有数据包写入datanode管线,并在联系到namenode告知其文件写入完成之前,等待确认。namenode已经知道文件由那些块组成,所以它在返回成功前只需要等待数据块进行最小量的复制。

副本存放的方式:Hadoop的默认布局策略是在运行客户端的节点上方第1个副本(如果客户端运行在集群之外,就随机选择一个节点,不过系统会避免挑选那些存储太满或太忙的节点。)第2个复本放在第一个不同且随机另外选择的机架中节点上。第3个复本与第2个复本放在同一个机架上,且随机选择另一个节点。

3.一致模型
文件系统的一致模型描述了文件读/写的数据可见性。新建一个文件后,它能在文件系统的命名空间中立即可见。但是,写入文件的内容并不保证能立即可见,即使数据流已经刷新并存储。所以文件长度显示为0。

HDFS提供了一种强行将所有缓存刷新到datanode中的手段,即对FSDataOutputStream调用hflush()方法,当hflush()方法返回成功后,对所有新的reader而言,HDFS能保证文件中到目前为止写入的数据均到达所有datanode的写入管道并且对所有新的reader均可见。

注意,hflush()不保证datanode已经将数据写到磁盘上,仅确保数据在datanode的内存中。为确保数据写入到磁盘上,可以用hsync()替代。

通过distcp并行复制

hadoop distcp file1 file2
//将文件复制到另一个文件中
hadoop distcp dir1 dir2
//如果dir2不存在,将新建dir2,目录dir1的内容全部复制到dir2下
//可以指定多个源路径,所有源路径下的内容都将被复制到目标路径下
//如果dir2已经存在,那么dir1复制到dir2的目录下,形成dir2/dir1
//-overwrite可覆盖覆写
//-update仅更新发生变化的文件

distcp是作为一个Mapreduce作业来实现的,该复制作业是通过集群中并行运行的map来完成。这里没有reducer,每个文件通过一个map进行复制,并且distcp试图为每一个map分配大致相等的数据来执行,即把文件执行为大致相等的块。默认情况下,将近20个map将被使用。

hadoop distcp -update -delete -p hdfs://namenode1/foo hdfs://namenode2/foo
//-delete选项使得distcp可以删除目标路径中任意没在源路径中出现的文件或目录,-P选项意味着文件状态属性如权限
//块大小和复本数被保留。当你运行不带参数的distcp时,能够看到准确的用法。

你可能感兴趣的:(大数据)