Hadoop-组件-HDFS-源码学习-数据读写-读数据设计
一、概述
在 HDFS 客户端实现中,最重要也最复杂的一部分就是文件的读写操作😯~
二、理论笔记
三、实现
3.1. 打开文件
当用户读取一个 HDFS 文件时,首先会调用 DistributedFileSystem.open() 方法打开这个文件,并获取文件对应的 FSDataInputStream 输入流,然后在这个 FSDataInputStream 对象上调用 read() 方法读取数据。
3.2. 读文件
HDFS 目前实现的读操作有三个层次,分别是网络读、短路读(short circuit read)以及零拷贝读(zero copy read),它们的读取效率依次递增。
- 网络读: 网络读是最基本的一种HDFS读,DFSClient 和 Datanode 通过建立 Socket连接传输数据。
- 短路读: 当 DFSClient 和保存目标数据块的 Datanode 在同一个物理节点上时,DFSClient 可以直接打开数据块副本文件读取数据,而不需要 Datanode 进程的转发。
- 零拷贝读: 当 DFSClient 和缓存目标数据块的 Datanode 在同一个物理节点上时,DFSClient 可以通过零拷贝的方式读取该数据块,大大提高了效率。而且即使在读取过程中该数据块被Datanode 从缓存中移出了,读取操作也可以退化成本地短路读
HdfsDataInputStream.read()方法就实现了层次读取。HdfsDataInputStream.read() 方法首先会调用HasEnhancedByteBufferAccess.read() 方法方法尝试进行零拷贝读取,如果当前配置不支持零拷贝读取模式,则抛出异常,然后调用 ByteBufferUtil.fallbackRead() 静态方法退化成短路读或者网络读。HasEnhancedByteBufferAccess.read() 方法定义了零拷贝读取的实现,而 InputStream.read() 方法则定义了短路读和网络读的实现。
3.2.1. 零拷贝读
DFSInputStream 实现了 HasEnhancedByteBufferAccess 接口的 read()方法,提供了以零拷贝模式读取数据块的功能。
3.2.2. 普通读
当 read() 方法执行零拷贝读操作失败后,会调用 ByteBufferUtil.fallbackRead() 退化为一个普通的读操作。
1 | buffer = ByteBufferUtil.fallbackRead(this, bufferPool, maxLength); |
ByteBufferUtil.fallbackRead() 判断传入参数的 InputStream (DFSInputStream)是否支持 ByteBuffer Read(实现了ByteBufferReadable 接口)。如果支持则直接将数据读取至 ByteBuffer 中,否则读取到 ByteBuffer:array() 字节数组中。
短路读
BlockReaderLocal 类实现了本地短路读取功能,也就是当客户端与 Datanode 在同一台机器上时,客户端可以绕过Datanode 进程直接从本地磁盘读取数据。
引用本站文章Hadoop-组件-HDFS-理论笔记-数据读写-读文件-短路读Joker网络读
网络读是最基本的一种 HDFS 读,DFSClient 和 Datanode 通过建立 Socket 连接传输数据。
引用本站文章Hadoop-组件-HDFS-理论笔记-数据读写-读文件-网络读Joker