一、HDFS角色以及职责
1.NameNode
NameNode是Hadoop分布式文件系统的核心,架构中的主角色
NameNode维护和管理文件系统元数据,包括名称空间目录树结构、文件和块的位置信息、访问权限等信息
基于以上原因, NameNode成为了访问HDFS的唯一入口。
NameNode内部通过内存(如果服务器断电,内存数据全部消失)和磁盘文件两种方式管理元数据,其中磁盘上的元数据文件包括Fsimage内存元数据镜像文件和edits log(Journal)编辑日志
2.DataNode
DataNode是Hadoop HDFS中的从角色,负责具体的数据块存储
DataNode的数量决定了HDFS集群的整体数据存储能力。通过和NameNode配合维护着数据块
3.主角色辅助角色: secondarynamenode
Secondary NameNode充当NameNode的辅助节点,但不能替代NameNode(当NameNode挂了以后,无法使用secondarynamenode充当NameNode)
主要是帮助主角色进行元数据文件的合并动作,可以通俗的理解为主角色的“性感小秘书”
职责:
1.NameNode
- NameNode仅存储HDFS的元数据:文件系统中所有文件的目录树,并跟踪整个集群中的文件, 不存储实际数据
- NameNode知道HDFS中任何给定文件的块列表及其位置。使用此信息NameNode知道如何从块中构建文件
- NameNode不持久化存储每个文件中各个块所在的datanode的位置信息,这些信息会在系统启动时从DataNode重建
- NameNode是Hadoop集群中的单点故障(一旦NameNode挂掉之后,所有的读写请求都不存在了,不知道元元数据,访问不了,数据不会丢失(存在DataNode),但元数据以及目录树都没有了,无法定位到文件)
- NameNode所在机器通常会配置有大量内存(RAM)
2.DataNode
- DataNode负责最终数据块block的存储。是集群的从角色,也称为Slave
- DataNode启动时,会将自己注册到NameNode并汇报自己负责持有的块列表
- 当某个DataNode关闭时,不会影响数据的可用性。 NameNode将安排由其他DataNode管理的块进行副本复制
- DataNode所在机器通常配置有大量的硬盘空间, 因为实际数据存储在DataNode中
二、HDFS写数据流程
完整流程图
文件写入流程
在流程开始之前,要掌握一个词 - Pipeline(管道)
Pipeline(管道)- HDFS中上传文件写入数据过程中的一种数据传输方式
根据上图,可以得知: 客户端将数据块写入第一个数据节点,第一个数据节点保存数据之后再将块复制到第二个数据节点,后者保存后将其复制到第三个数据节点。
为什么HDFS采用一个个进行数据传输,不采用同时并行传输?
因为数据以管道的方式, 顺序的沿着一个方向传输,这样能够充分利用每个机器的带宽,避免网络瓶颈和高延迟时的连接,最小化推送所有数据的延时
在线性推送模式下,每台机器所有的出口宽带都用于以最快的速度传输数据,而不是在多个接受者之间分配宽带。
以上的方式可能会出现数据丢失的情况,而为了解决数据丢失的问题,HDFS是这么解决的
在每一个节点之间进行传输的时候,先返回ack,如果返回成功,再进行下一个节点的传输
ACK-确认字符,在数据通信中,接收方发给发送方的一种传输类控制字符。表示发来的数据已确认接收无误。
在HDFS pipeline管道传输数据的过程中,传输的反方向会进行ACK校验,确保数据传输安全。
默认的副本策略
默认副本存储策略是由BlockPlacementPolicyDefault指定(只要保证不再同一个机器上即可)
完整流程描述
以hadoop fs -put a.txt /这条命令为例,假设副本数为3:- 客户端执行了命令后,会向NameNode发起上传请求,走的是RPC协议
- NameNode收到请求,执行各种检查判断:目标文件是否存在、父目录是否存在、客户端是否具有创建该文件的权限。检查通过后 NameNode就会为本次请求记下一条记录并给客户端反馈是否可以上传的标记
- 客户端收到请求后,将文件进行切片(将a.txt切成了三片))。也可以理解成块(block)
- 客户端发起上传第一个block请求(块)
- 内部组件datastreamer请求NameNode挑选出适合存储数据副本的一组DataNode地址返回给客户端(3副本)
- 客户端和主机列表中第一个的主机建立pipeline,datastreamer将数据包流式传输到一个DataNode,第一个DataNode跟第二个DataNode建立pipeline,以此类推进行数据包的传输,形成一个客户端到三台主机的线性管道。
- 考虑到网络传输性能,客户端上传block的时候会再次切片,将block切成多个package(数据包,默认大小是64kb,一个个上传),所有的数据包到达DataNode的时候都会被缓存
- 每一次的传输DataNode都要及时的返回ack机制校验数据包是否成功,如果失败,重试。
- 直到第一个DataNode收到ack并给客户端进行写应答。
- 客户端收到写应答后,会传下一个package
- 重复这个过程,直到所有的package传输完成,三台主机会将缓存中的数据包合成block(块),再落盘。
- 之后上传第二个第三个block
- 当所有的block全部传输完成之后,客户端会向NameNode汇报上传完毕
- NameNode收到请求之后会更新元数据。