hdfs 中chunk_HDFS写文件过程分析

引自:http://shiyanjun.cn/archives/942.html

HDFS是一个分布式文件系统,在HDFS上写文件的过程与我们平时使用的单机文件系统非常不同,从宏观上来看,在HDFS文件系统上创建并写一个文件,流程如下图(来自《Hadoop:The Definitive Guide》一书)所示:

b37c9f8d3371ff58a33187acae1aedc7.png

具体过程描述如下:

Client调用DistributedFileSystem对象的create方法,创建一个文件输出流(FSDataOutputStream)对象

通过DistributedFileSystem对象与Hadoop集群的NameNode进行一次RPC远程调用,在HDFS的Namespace中创建一个文件条目(Entry),该条目没有任何的Block

通过FSDataOutputStream对象,向DataNode写入数据,数据首先被写入FSDataOutputStream对象内部的Buffer中,然后数据被分割成一个个Packet数据包

以Packet最小单位,基于Socket连接发送到按特定算法选择的HDFS集群中一组DataNode(正常是3个,可能大于等于1)中的一个节点上,在这组DataNode组成的Pipeline上依次传输Packet

这组DataNode组成的Pipeline反方向上,发送ack,最终由Pipeline中第一个DataNode节点将Pipeline ack发送给Client

完成向文件写入数据,Client在文件输出流(FSDataOutputStream)对象上调用close方法,关闭流

调用DistributedFileSystem对象的complete方法,通知NameNode文件写入成功

下面代码使用Hadoop的API来实现向HDFS的文件写入数据,同样也包括创建一个文件和写数据两个主要过程,代码如下所示:

01

static String[] contents = new String[] {

02

"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",

03

"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb",

04

"cccccccccccccccccccccccccccccccccccccccccccccccccccccccccc",

05

"dddddddddddddddddddddddddddddddd",

06

"eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee",

07

};

08

09

public static void main(String[] args) {

11

Path path = new Path(file);

12

Configuration conf = new Configuration();

13

FileSystem fs = null;

14

FSDataOutputStream output = null;

15

try {

16

fs = path.getFileSystem(conf);

17

output = fs.create(path); // 创建文件

18

for(String line : contents) { // 写入数据

19

output.write(line.getBytes("UTF-8"));

20

output.flush();

21

}

22

} catch (IOException e) {

23

e.printStackTrace();

24

} finally {

25

try {

26

output.close();

27

} catch (IOException e) {

28

e.printStackTrace();

29

}

30

}

31

}

结合上面的示例代码,我们先从fs.create(path);开始,可以看到FileSystem的实现DistributedFileSystem中给出了最终返回FSDataOutputStream对象的抽象逻辑,代码如下所示:

1

public FSDataOutputStream create(Path f, FsPermission permission,

2

boolean overwrite,

3

int bufferSize, short replication, long blockSize,

4

Progressable progress) throws IOException {

5

6

statistics.incrementWriteOps(1);

7

return new FSDataOutputStream

8

(dfs.create(getPathName(f), permission, overwrite, true, replication, blockSize, progress, bufferSize), statistics);

9

}

上面,DFSClient dfs的create方法中创建了一个OutputStream对象,在DFSClient的create方法:

01

public OutputStream create(String src,

02

FsPermission permission,

03

boolean overwrite,

04

boolean createParent,

05

short replication,

06

long blockSize,

07

Progressable progress,

08

int buffersize

09

) throws IOException {

10

... ...

11

}

创建了一个DFSOutputStream对象,如下所示:

1

final DFSOutp

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值