HDFS
HDFS是一个分布式的文件系统,可以在其中存储海量的数据,并且能够保证数据的可靠性。
hdfs屏蔽掉了背后的分布式文件系统,使我们用起来跟普通的文件系统没有差别。
(一)hdfs的shell命令
hadoop fs -ls /(路径),显示目录结构
hadoop fs -mkdir /park,创建文件夹
hadoop fs -put /home/software/hadoop.txt /park,上传(/home/software/hadoop.txt是要上传的文件在本地所在的位置,/park是hdfs上的路径)
hadoop fs -cat /park/hadoop.txt,查看
hadoop fs -get /park/hadoop.txt /home/software/hdfs.txt,下载(/park/hadoop.txt是文件在hdfs上的路径,/home/software/hdfs.txt是文件下载到本地的路径以及命名的文件名字)
hadoop fs -tail /park/hadoop.txt,查看文件后1000个字符
hadoop fs -rm /park/hadoop.txt,删除文件
hadoop fs -rmdir /park,删除文件夹(如果文件夹不是空的,直接删除会报错)
hadoop fs -help,帮助(会显示出所有命令及作用)
注意:hdfs只能一次写入,多次查询,不允许行级别的增删改。
问题:namenode is in safe mode(安全模式)
解决:退出安全模式:hadoop dfsadmin -safemode leave
(二)hdfs细节
-
Hdfs
Hdfs是一个分布式的文件存储系统,hdfs为了保证数据存储的可靠性和读取性能,会对数据进行切块,切块之后进行复制并存储在集群的多个节点中。Hdfs中存在一个名字节点namenode和多个数据节点datanode,其中namenode是用来存储元数据信息,并且将元数据保存在内存和磁盘当中,它其中的元数据,保存的是文件、block、datanode之间的映射关系,而datanode就是真正用来存储我们数据的节点,datanode将我们文件切成的block存储在磁盘,并且维护了block id到文件的映射关系。 -
Block(数据块)
一个文件上传到hdfs之后会被切成若干个块,就是block,分别存储到不同的磁盘上,所以block是hdfs当中数据存储的基本单位。
Block数据块有一个默认大小,默认是128M(在Hadoop1.0是64M),然后以block为单位,复制出副本,然后再分布式的存储。
切成block有什么好处:
①文件块可以保存到不同的磁盘上,切分之后,可以更加灵活的分布式存储。
②简化存储系统,屏蔽数据的区别
③有利于复制,为了保证数据的可靠性(数据不丢失),hdfs会将每一个block复制成三份(包括原来的内份),称之为三个副本。
256M文件,会切成几个block块?2块
258M文件,会切成几个block块?3块,如果剩余的最后一块,不足128M,是多大就是多大,并不占用整个数据块存储空间。 -
Namenode(名字节点)
Namenode维护着hdfs中的元数据信息,包括文件的信息,目录结构的信息,文件和块之间的信息,副本数量信息,block和datanode之间的关系信息
/test/a.log,3,{b1,b2},[{b1:[h0,h1,h3]},{b2:[h0,h2,h4]}]
Namenode中的元数据信息会存储在内存和文件中,内存中是实时的数据,文件中为数据镜像作为持久化存储使用。
磁盘当中的文件:fsimage元数据镜像文件,edits操作日志文件,fstime文件(记录最后一次合并时间的文件) -
Secondarynamenode
触发合并的条件:达到一定时间:默认值是3600秒;edits达到一定大小,默认是64M
主要功能就是帮namennode合并这个元数据
Secondarynamenode对namenode会进行一定的备份,但不是实时的备份(热备)
Namenode当中元数据合并的过程:
达到条件后 snn会将nn中的fsimage和edits文件拷贝过来,同时nn中会创建一个新的edits.new文件,新的读写请求会写入到这个edits.new中,在snn中将拷贝过来的fsimage和edits合并为一个新的fsimage,最后snn将合并完成的fsimage文件拷贝回nn中替换之前的fsimage,nn再将edtis.new改为edits
由于NameNode实时数据都在内存中,此处的合并指的是磁盘中的持久化的数据的处理。 -
Datanode
真正存储数据的节点,在Hadoop中,数据是以block的形式存放在datanode上
Datanode会不断的向namenode发送心跳报告,datanode通过向namenode发送心跳保持和它的联系,时间间隔是3秒钟,而后续datanode节点在工作的过程中会不断的更新namenode节点与之对应的元数据信息,并通过心跳机制,接受来namenode节点的指令。
而如果连续10分钟,我们namenode都没有收到datanode的心跳,namenode会认为这个datanode已经丢失,namenode就会命令其他的datanode,复制刚刚挂掉的datanode所存储的block,达到指定的数量。 -
机架感知策略(副本放置策略)
默认情况下,一个block块有三个副本(包括自己)
第一个副本:如果客户端本身就是一个datanode,就会将第一个副本存放到自己身上
如果客户端本身不是datanode,会就近选择一个datanode进行存储(延迟最低)
第二个副本:存放在和第一个副本不同机架的节点上
第三个副本:存放在和第二个副本相同机架的不同节点上
(三)hdfs执行流程
-
hdfs的读流程
使用HDFS提供的客户端开发库client,向远程的namenode发起RPC请求;
Namenode会检验当前文件是否存在,以及当前客户端是否有权限读取该文件;
如果都没有问题,namenode会视情况返回文件的部分或者全部block列表,对于每个block,namenode都有返回有该block副本的datanode地址;
客户端client会选取举例客户端最接近(不是物理上的接近,而是延迟最低负载最低)的datanode读取block;如果客户端本身就是一个datanode,那么直接从本地读取数据
读取完当前的block的数据后,关闭与当前datanode的连接,并未读取下一个block寻找最佳的datanode;
当读取完列表的block后,判断文件是否结束,如果文件没有结束,客户端会向namenode获取下一批block列表
没读取完一个block都会进行验证,如果读取datanode时出现错误,客户端会通知namenode,然后再从下一个拥有该block副本的datanode上继续读取
当文件结束之后,也就是文件最后一个block块也读取完毕,客户端会连接namenode告知关闭文件。
-
hdfs的写流程
使用hdfs的客户端client,向远程的namenode发起RPC请求;
Namenode会检查要创建的文件是否已经存在,创建者是否有对应的权限,成功则为文件创建一个记录,否则会抛出相应的异常
客户端会将文件切分成若干个packets,并在内部以数据队列的形式管理这些packets
向namenode申请用来存放这些数据的datanode的地址
客户端根据namenode返回的地址找到对应datanode上传第一个packet,datanode集群内部会以管道流的方式写入这个packet(第一个datanode写完之后,将其传递给下一个datanode,第二个写完传递给第三个),第三个datanode写入成功之后,会返还一个ack给第二个datanode,确定成功,第二个datanode收到这个ack之后,会发送一个ack给第一个datanode,第一个datanode收到这个ack之后,会发送一个ack给客户端,客户端收到datanode返回的ack之后,会从队列当中移除这个packet,按照列表的顺序上传下一个packet,重复上传的过程,直到整个队列当中的所有packet全部上传成功;
全部上传成功之后,客户端会通知namenode文件上传完成,namenode会将该文件置为可用状态,并关闭该文件。
-
hdfs删除流程
客户端连接namenode表示要删除文件,namenode会检查文件是否存在,是否有权限
Namenode会执行元数据的删除(将改元数据置为已删除状态)
向客户端表示文件删除成功
当保存着这些数据块的datanode节点向namenode发送心跳时,在心跳响应中,namenode节点会向datanode节点发出指令,要求删除这些block
Datanode收到指令后删除对应的block
所以在执行完删除之后的一段时间内,数据块才会真正的删除掉
当该文件对应的所有block及其副本都被删除后,namenode将之前标记为已删除状态的元数据删掉。 -
hdfs启动流程
Hdfs的主要的两个节点:namenode和datanode
内存当中的元数据:文件信息及目录结构、文件副本数量、block编号以及block编号对应的datanode地址
Fsimage文件当中的元数据:文件信息及目录结构、文件副本数量,block编号
备注:namenode启动第一件事就是要先合并元数据,并且把它恢复到内存中,这个namenode刚起来的第一次合并操作不是secondarynamenode做的,是namenode自己做。
Datanode一启动的时候,就会向namenode发送心跳包,每三秒报告一次,namenode会等待datanode报过过来的心跳,在心跳包当中,会携带着datanode身上有哪些编号的block这样的信息,namenode接受这个心跳信息,临时在内存中组织出我们block编号和datanode之间的对应关系。当满足最小启动条件的时候(所有的block,都至少找到一个副本),它就可以正常的对外提供服务了。但是,在真正提供对外服务之前,namenode还会把缺少的副本数量,复制到足够的数量。(对于多出的副本数量会删除)
在启动到真正对外提供服务的这段时间内,除了查看文件结构之外的任何操作都做不了,如果做其他操作,会报一个错,sateModeException:cannot …操作,namenode is in sate mode(safe mode:安全模式),遇到安全模式,最好的解决办法,就是等一会儿,如果长时间不自动退出安全模式,正规操作是去检查是什么原因进入了安全模式,也可以强制退出安全模式,hadoop dfsadmin -safemode leave