zl程序教程

您现在的位置是:首页 >  其他

当前栏目

Hadoop HDFS 读写流程

2023-09-14 09:14:49 时间

HDFS 写流程

HDFS 的写数据流程 :

  1. 客户端通过 Distributed FileSystem 模块向 NameNode 请求上传文件, NameNode 检查目录 , 文件是否已存在
  2. NameNode 返回是否可以上传
  3. 客户端请求 Block 上传到哪几个 DataNode 服务器上
  4. NameNode 返回 3 个 DataNode 节点, 分别为 dn1、 dn2、 dn3
  5. 客户端通过 FSDataOutputStream 模块请求 dn1 上传数据, dn1 收到请求会再调 dn2,然后 dn2 调用 dn3,将这个通信管道建立完成
  6. dn1、 dn2、 dn3 逐级应答客户端
  7. 客户端开始往 dn1 上传 Block (单位 : Packet)(从磁盘读取到内存缓存),dn1 每收到个 Packet 就会传给 dn2, dn2 传给 dn3; dn1 每传个 packet 会放入一个应答队列等待应答
  8. 当 Block 传输完成后,客户端会再请求 NameNode 上传另外 Block 的服务器。(重复执行 3-7 步)

代码分析 :

image.png

网络拓扑

HDFS 写数据时, NameNode 会选择距离 Clinet 最近 DataNode 接收数据

  • 节点距离:两个节点到达最近的共同祖先的距离总和

节点距离计算 : 如 : 数据中心 d1 机架 r1 中的节点 n1 , 该节点表示为 /d1/r1/n1

情况集群机架节点距离情况
设备1d1r1n00同一节点上的进程
设备2d1r1n0
设备1d1r1n02同一机架上的不同节点
设备2d1r1n2
设备1d1r1n04同一数据中心不同机架上的节点
设备2d1r2n0
设备1d1r1n06不同数据中心的节点
设备2d2r1n0

机架感知

http://hadoop.apache.org/docs/r3.1.3/hadoop-project-dist/hadoop-hdfs/HdfsDesign.html#Data_Replication

副本放置策略 (副本 : 3) :

  • 副本1 : Client 的节点上。当客户端在集群外, 随机选 ( 快速写入 )
  • 副本2 : 另个机架的随机一个节点 ( 应对交换机故障 )
  • 副本3 : 副本2 的机架的随机节点 ( 减少跨 rack 的网络流量 )

image.png

此策略好处 :

  • 减少了机架间写入流量,提高写入性能
  • 不影响数据可靠性和可用性 , 因为机架故障的几率远小于节点故障
  • 减少了读取数据时 , 使用的总网络带宽,因为一个块只放置在两个独特的机架中,而不是三个
  • 文件的副本并非均匀分布在机架上。1 / 3 的副本在一个节点上,1 / 3 的副本在一个机架上,1/ 3 均匀分布在剩余的机架上

源码说明

Idea 中

org.apache.hadoop.hdfs.server.blockmanagement;

<dependency>
    <groupId>org.apache.hadoop</groupId>
    <artifactId>hadoop-hdfs</artifactId>
    <version>3.1.3</version>
</dependency>

Crtl + n 查找 BlockPlacementPolicyDefault ,在该类中查找 chooseTargetInOrder 方法

protected Node chooseTargetInOrder() {
	int numOfResults = results.size();
	if (numOfResults == 0) {
		// 本地
		DatanodeStorageInfo storageInfo = this.chooseLocalStorage();
	}
	if (numOfResults <= 1) {
		// 远程
		this.chooseRemoteRack();
	}
	if (numOfResults <= 2) {
		if (this.clusterMap.isOnSameRack(dn0, dn1)) {
			// 上一个本地, 这就远程
		   this.chooseRemoteRack();
		} else if (newBlock) {
			// 本地
		   this.chooseLocalRack();
		} else {
			// 本地
		   this.chooseLocalRack();
		}
	}
}

HDFS 读流程

读流程 :

  1. 客户端通过 DistributedFileSystem 向 NameNode 请求下载文件, NameNode 通过查询元数据,找到文件块所在的 DataNode 地址
  2. 选一台 DataNode (就近原则,数据量大就会随机),请求读取数据
  3. DataNode 开始传输数据给客户端(从磁盘读到输入流,以 Packet 为单位来做校验)
  4. 客户端接收数据 ( 单位: Packet),先在本地缓存,然后写入目标文件