- 2.1、hdfs副本放置策略
- 2.2、hdfs的文件写流程
- 2.3、hdfs的文件读流程
- 2.4、hdfs上的datanode
- 2.5、hdfs上关于数据修复
- 2.6、hdfs上的SecondaryNameNode
- 2.7、fsimage+editlog详解
- 2.8、校验文件是否损坏
一、上次课程回顾
- https://blog.csdn.net/SparkOnYarn/article/details/105098427
1、block块和副本数的关系,面试题须知
2、HDFS的设计是为了小文件,数据上传hdfs前就需要合并,上传hdfs后也可以使用服务合并
3、namenode维护了哪些数据信息、datanode发送心跳和块报告、secondarynamenode上checkpoint要知道它的详细流程
4、修改hdfs的存储目录
二、Hadoop四
- hdfs课程上涉及更多的是原理性的东西,真正对于我们生产上用到的其实一些hdfs的命令,涉及到hdfs上小文件的处理,以及后续API的开发。
- 数据能够存储进hdfs及数据能够从hdfs取出就是涉及生产
2.1、hdfs副本放置策略
eg:有两个机架:rack1和rack2,在机架1上client进行提交:
- 第一个副本:假如上传节点为DN节点,优先放置本节点,否则就随机挑选一台磁盘不太慢,CPU不太繁忙的节点,未来我们在提交文件到hdfs节点上的时候;
- 第二个副本:放置在与第一个副本不同的机架的节点(机架与机架是独立的,避免因机架断电出现问题)
- 第三个副本:放置在与第二个副本相同机架的不同节点上
J总公司会选择一台机器做DataNode节点,直接get和put很方便;正常的公司会单独选择一个Client node:单独一台机器,没有datanode、datanode的角色,仅仅只有hdfs-site.xml文件,有xml文件就能进行通信;
正常公司中都使用CDH,CDH中有一个默认机架,这是一个虚拟的概念,它把机架1和机架2会看作一个整体的机架,在CDH中一般不调整默认的机架(较为麻烦)
2.2、hdfs的文件写流程
对应的hadoop命令:hdfs dfs -put xxx.log /wordcount,这是一个无感知的命令;
1、当我们执行hdfs dfs -put命令的时候,首先调用hdfs client客户端,它调用了分布式文件系统的一个方法,通过rpc协议去跟namenode进行通信,namenode接到请求后客户端去查看是否已经有这个文件,文件已经存在就返回已存在,还要查看是否有权限;一切检查okay就会在namenode创建一个新文件,这个新文件不会关联任何block块,仅仅是返回一个DFSData OutputSTream对象;
面试题目:FSDataOutputStream和FSDataInputStream到底谁是谁?
- FSDataOutputStream是往外出,文件读流程FSDatainputStream
简述流程:
1、Client调用FileSystem.create(filepath)方法,与NameNode进行rpc通信,check是否存在及是否有权限创建,假如不ok,就返回错误信息;假如ok,就创建一个新文件,不关联任何的block块,返回一个FSDataOutputStream对象;
2、Client调用FSDataOutputStream对象的write()方法,
先将第一块的第一个副本写到第一个DN,
第一个副本写完;就传输给第二个DN,
第二个副本写完;就传输给第三个DN,第三个副本写完。
就返回一个ack packet(确认包)给第二个DN,第二个DN接收到第三个的ack packet(确认包)+自身ok,就返回一个ack packet
给第一个DN,第一个DN接收到
第二个DN的ack packet确认包 + 自身ok,就返回ack packet(确认包)给FSDataOutputStream对象,这标志第一个块的3个副本写完。
然后余下的块这样写:
2.3、当向文件写入数据完成后,Client调用FSDataOutputStream.close() 方法,关闭输出流。
2.4、再调用分布式的文件系统FileSystem.complete()方法,告诉NN该文件写入成功。
2.3、hdfs的文件读流程
- hdfs文件读流程调用的是FSDataInputStream对象
简述hdfs文件的读流程:
1、Client调用FileSystem.open(filePath)方法,与NN进行【RPC】协议通信,返回该文件的部分或者全部的block块的列表,也就是返回FSDataInputStream对象。
2、Client调用FSDataInputStream对象的read()方法
a. 与第一个块最近的DN进行read,判断这个块与哪个dn最近,读取完成后,会进行check;
假如ok,就关闭与当前DN的通信;假如失败,会记录失败块+DN信息(会记录节点上块是否损坏,下次再进行请求读取,就会跳过这个块了);下次不会再进行读取;会去该块的第二个DN地址读取
block1 dn5
block1 dn15
block1 dn25
b.然后去第二个块的最近的DN上通信读取,check后,关闭通信;
c.假如block列表读取完成后,文件还未结束,就再次调用FileSystem方法从NN获取该文件的下一批次的block列表。(感觉就是连续的数据流,对于客户端操作是透明的无感知的)
3、Client调用FSDataInputStream.close()方法,关闭输入流。
2.4、迁移pid文件存储路径&&迁移hdfs的存储目录
1、迁移pid的存储路径:
- 修改/tmp下hdfs的pid存储路径,因为之前它是存放在/tmp目录下的,而它有定期清理机制,所以需要移到新的文件目录下:
1、我们首先需要知道启动hdfs进程的pid文件存储目录,如下:
[hadoop@hadoop001 hsperfdata_hadoop]$ pwd
/tmp/hsperfdata_hadoop
[hadoop@hadoop001 hsperfdata_hadoop]$ ll
total 160
-rw------- 1 hadoop hadoop 32768 Mar 26 13:45 11501
-rw------- 1 hadoop hadoop 32768 Mar 26 13:45 14940
-rw------- 1 hadoop hadoop 32768 Mar 26 13:44 15046
-rw------- 1 hadoop hadoop 32768 Mar 26 13:45 15247
-rw------- 1 hadoop hadoop 32768 Mar 26 13:45 1881
2、因为pid文件是存储在/tmp目录的,进入到hadoop的config目录,编辑hadoop-env.sh文件,修改HADOOP_PID_DIR的目录:
[hadoop@hadoop001 hadoop]$ pwd
/home/hadoop/app/hadoop/etc/hadoop
[hadoop@hadoop001 hadoop]$