hadoop写流程

1.调用客户端对象Distributed FileSystem的create方法

2.Distributed FileSystem会向NameNode发起一个RPC连接,请求创建一个文件,NameNode会通过一系列的检查,判断要创建的文件是否存在以及客户端是否有创建该文件的权限。
若要创建的文件不存在,以及客户端存在创建该文件的权限。NameNode会创建该文件,实质上是向edits log文件中写入,若创建失败,客户端会抛出IOException。若文件存在或用户无权限,抛出异常结束

3.创建成功后,Distributed FileSystem会向客户端返回FSDataOutputStream,用于写数据,FSDataOutputStream中封装了DFSOutputStream,用于客户端与NameNode和DataNode进行通信

4.FSDataOutputStream会将数据切分一个个小的数据包(64kb),并写入到一个内部序列DataStreamer会读取其中的内容,并向NameNode请求获取存放当前block副本的DataNode列表。列表中的DataNode会根据与客户端的距离,形成一个管线。DataStreamer会将读取到的数据包发送给第一个DataNode,当第一个数据包发送完成后,DataStreamer会接着向第一个DataNode发送第二个数据包,此时第一个DataNode会将接受到的第一个数据包通过管线发送给第二个DataNode,在第一个DataNode将数据包发送完后之后,第二个会将这个数据包发送给第三个数据包。这样就可以利用时间差加快数据的传输。在第一个接收完数据包后,会将该数据包写入到客户端的确认队列中,当管线中所有的datanode写入完成后,从确认队列中删除该数据包。

如果在写入数据期间,DataNode发送故障,则执行以下操作

    a)关闭管线,把确认队列中的所有包添加回数据队列的最前端,以保证故障节点下游的节点不会漏掉任意一个包

    b)在存储在另一个节点处的当前数据块指定一个标志,并将这个标志告知NameNode,以便故障节点恢复后,可以将已经存储的数据包删除

    c)删除管线中的故障节点,并将剩余数据包写入其它正常的DataNode,NameNode检测到副本数不足时,会在另一个DataNode上创建新的副本       

    d)后续的数据库正常处理

5.DFSOutputStream中有一个数据包队列,该队列中的数据包是需要写入DataNode的,该队列被称为确认队列ack(客户端存放,这是第二个队列),当一个数据包写入管线中所有DataNode,会将该数据包从队列中移除

6.如果还有要写入的block,则重复4,5操作

7.当客户端完成数据的传输(是否是将最后一个的block写入到确认队列),调用数据流的close()方法。该方法将数据队列中的所有数据包写入到管线中,等待管线的确认

8.客户端收到管线中所有DataNode的确认消息后,通知NameNode写入完成

9.namenode已经知道文件由哪些块组成,所以它在返回成功前只需要等待数据块进行最小量的复制(复制的是什么??? 复制的是副本,达到最小副本数)

package com.bjsxt.hadoop.test;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;

import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.FSDataInputStream;
import org.apache.hadoop.fs.FSDataOutputStream;
import org.apache.hadoop.fs.FileStatus;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.io.IOUtils;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;

public class HadoopDemo1 {

	private Configuration conf;
	private FileSystem fs;
	
	@Before
	public void init() throws IOException, InterruptedException, URISyntaxException {
		conf = new Configuration(true);
		fs = FileSystem.get(new URI("hdfs://mycluster"), conf, "root");
	}
	
	/**
	 * 文件上传
	 * @throws IOException
	 * @throws InterruptedException
	 * @throws URISyntaxException
	 */
	@Test
	public void testWrite() throws IOException, InterruptedException, URISyntaxException {
		//上传的文件
		FileInputStream fis = new FileInputStream("/Users/zzw/Desktop/hello1.txt");
		//上传到的位置
		Path path = new Path("/hello.txt");
		FSDataOutputStream dos = fs.create(path);
		//通过hadoop工具类直接将文件输出流写入到输出流上
		IOUtils.copyBytes(fis, dos, conf);
		//关闭输入输出流
		fis.close();
		dos.flush();
		dos.close();
	}

	@After
	public void close() throws IOException {
		if(fs != null) {
			fs.close();
		}
	}
	
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值