一、HDFS写数据流程:
- 客户端(Client)通过Distributed FileSystem向NameNode申请上传 …/xxx.txt 文件300 M;
- NameNod向Client响应是否可以上传文件:如果有就告诉客户端这个文件已存在;如果没有,告诉客户端可以上传;
- 客户端收到NameNod可以上传的消息后,将300M文件切分,将第一个block(128M)和副本数n(3),客户端请求第一个 Block向NameNode申请去哪几个DataNode服务器上;
- NameNode选择3个DataNode(DN1、DN2、DN3)给客户端;
- Client向DN1、DN2、DN3申请建立文件传输通道:客户端通过FSDataOutputStream模块请求dn1上传数据,dn1收到请求会继续调用dn2,然后dn2调用dn3,将通信管道建立完成;
- DN3、DN2、DN1依次应答给客户端;
- 客户端开始传输数据,以Packet(数据包、信息包)为单位,DN1收到一个Packet就会传给DN2,DN2传给DN3;
- 当一个Block传输完成之后,客户端再次请求NameNode上传第二个Block的服务器。
二、HDFS读取文件步骤:
- Client通过Distributed FileSystem向NN请求下载 …/xxx.txt文件
- NameNode通过查询元数据,找到文件块所在的DN地址,发给客户端
- Client就近原则选择一台服务器(DataNode1),请求访问读数据block_1
- Client通过socket流读取DN1中数据
- Client向DN2请求访问读数据block_2
- DN2向Client传输数据
- 客户端以Packet为单位接收,先在本地缓存,然后写入目标文件。
三、block 副本放置策略:
- 第一个副本选择最近的DataNode给客户端;
- 第二个副本放置在于第一个副本不同的机架的节点上,提高可靠性;
- 第三个副本与第一个副本相同机架的节点;
- 更多副本:随机节点。
四、HDFS HA 高可用原理:
在Hadoop 2.0.0之前,NameNode是HDFS集群中的单点故障,HDFS高可用性中,可以在同一群集中运行两个(自3.0.0起,超过两个)冗余NameNode。这样可以在机器崩溃的情况下快速故障转移到新的NameNode,或者出于计划性维护的目的由管理员发起的正常故障转移。
- HDFS HA(High Available)同时配置两个Namenode,状态分别是Active和Standby。利用ZK来做HDFS HA状态进程的自动切换。Standby Namenode作为热备份,在机器发生故障时能够快速进行故障转移,同时在日常维护的时候进行Namenode切换。Namenode只能配置一主一备,不能多于两个Namenode。
- 主Namenode处理所有的操作请求(读写),而Standby只是作为slave,用来同步主Namenode的状态,保证发生故障时能够快速切换。为了使Standby Namenode与Active Namenode数据保持同步,两个Namenode都与一组Journal Node进行通信。当主Namenode进行任务的namespace(命名空间)操作时,都会同步修改日志到Journal Node节点中。Standby Namenode持续监控这些edit,当监测到变化时,将这些修改 同步到自己的namespace。当进行故障转移时,Standby在成为Active Namenode之前,会确保自己已经读取了Journal Node中的所有edit日志,从而保持数据状态与故障发生前一致。
- 为了确保故障转移能够快速完成,Standby Namenode需要维护最新的Block位置信息,即每个Block副本存放在集群中的哪些节点上。为了达到这一点,Datanode同时配置主备两个Namenode,并同时发送Block报告和心跳到两台Namenode。
- 任何时刻集群中只有一个Namenode处于Active状态,否则可能出现数据丢失或者数据损坏。当两台Namenode都认为自己的Active Namenode时,会同时尝试写入数据(不会再去检测和同步数据)。为了防止这种脑裂现象,Journal Nodes只允许一个Namenode写入数据,内部通过维护epoch数(QJM的全称是Quorum Journal Manager,管理的节点为JournalNode)来控制,从而安全地进行故障转移。
五、小文件问题
HDFS并不是为了有效的处理大量小文件而存在的,它主要是为了流式的访问大文件而设计的。
小文件问题的解决方案:(从小文件产生的途经就可以从源头上控制小文件数量)
1.使用Sequence File作为表存储格式,不要用textfile,在一定程度上可以减少小文件。
2.减少reduce的数量(可以使用参数进行控制)。
3.少用动态分区,用时记得按distribute by分区。