Hadoop之HDFS原理及文件上传下载源码分析(上)

发表于:2017-4-24 09:50

字体: | 上一篇 | 下一篇 | 我要投稿

 作者:君君wan岁    来源:博客园

  HDFS原理
  首先说明下,hadoop的各种搭建方式不再介绍,相信各位玩hadoop的同学随便都能搭出来。
  楼主的环境:
  · 操作系统:Ubuntu 15.10
  · hadoop版本:2.7.3
  · HA:否(随便搭了个伪分布式)
  文件上传
  下图描述了Client向HDFS上传一个200M大小的日志文件的大致过程:
  首先,Client发起文件上传请求,即通过RPC与NameNode建立通讯。
  NameNode与各DataNode使用心跳机制来获取DataNode信息。NameNode收到Client请求后,获取DataNode信息,并将可存储文件的节点信息返回给Client。
  Client收到NameNode返回的信息,与对应的DataNode节点取得联系,并向该节点写文件。
  文件写入到DataNode后,以流水线的方式复制到其他DataNode(当然,这里面也有DataNode向NameNode申请block,这里不详细介绍),至于复制多少份,与所配置的hdfs-default.xml中的dfs.replication相关。
  元数据存储
  先明确几个概念:
  fsimage:元数据镜像文件。存储某一时段NameNode内存元数据信息。
  edits:操作日志文件。
  fstime:保存最近一次checkpoint的时间
  checkpoint可在hdfs-default.xml中具体配置,默认为3600秒:
  1 <property>
  2   <name>dfs.namenode.checkpoint.period</name>
  3   <value>3600</value>
  4   <description>The number of seconds between two periodic checkpoints.
  5   </description>
  6 </property>
  fsimage和edits文件在namenode目录可以看到:
  NameNode中的元数据信息:
  test.log文件上传后,Namenode始终在内存中保存metedata,用于处理“读请求”。metedata主要存储了文件名称(FileName),副本数量(replicas),分多少block存储(block-ids),分别存储在哪个节点上(id2host)等。
  到有“写请求”到来时,namenode会首先写editlog到磁盘,即向edits文件中写日志,成功返回后,才会修改内存,并且向客户端返回
  hadoop会维护一个fsimage文件,也就是namenode中metedata的镜像,但是fsimage不会随时与namenode内存中的metedata保持一致,而是每隔一段时间通过合并edits文件来更新内容。此时Secondary namenode就派上用场了,合并fsimage和edits文件并更新NameNode的metedata。
  Secondary namenode工作流程:
  · secondary通知namenode切换edits文件
  · secondary通过http请求从namenode获得fsimage和edits文件
  · secondary将fsimage载入内存,然后开始合并edits
  · secondary将新的fsimage发回给namenode
  · namenode用新的fsimage替换旧的fsimage
  通过一张图可以表示为:
  文件下载
  文件下载相对来说就简单一些了,如图所示,Client要从DataNode上,读取test.log文件。而test.log由block1和block2组成。
  文件下载的主要流程为:
  · client向namenode发送请求。
  · namenode查看Metadata信息,返回test.log的block的位置。
  Block1: h0,h1,h3
  Block2: h0,h2,h4
  · 开始从h0节点下载block1,block2。
  源码分析
  我们先简单使用hadoop提供的API来实现文件的上传下载(文件删除、改名等操作比较简单,这里不演示):
1 package cn.jon.hadoop.hdfs;
2
3 import java.io.FileInputStream;
4 import java.io.FileOutputStream;
5 import java.io.IOException;
6 import java.io.InputStream;
7 import java.io.OutputStream;
8 import java.net.URI;
9 import java.net.URISyntaxException;
10
11 import org.apache.hadoop.conf.Configuration;
12 import org.apache.hadoop.fs.FileSystem;
13 import org.apache.hadoop.fs.Path;
14 import org.apache.hadoop.io.IOUtils;
15 import org.junit.Before;
16 import org.junit.Test;
17
18 public class HDFSDemo {
19     FileSystem fs = null;
20     @Before
21     public void init(){
22         try {
23             //初始化文件系统
24             fs = FileSystem.get(new URI("hdfs://hadoopmaster:9000"), new Configuration(), "root");
25         } catch (IOException e) {
26             e.printStackTrace();
27         } catch (InterruptedException e) {
28             e.printStackTrace();
29         } catch (URISyntaxException e) {
30             e.printStackTrace();
31         }
32     }
33     public static void main(String[] args) {
34
35     }
36     @Test
37     /**
38      * 文件上传
39      */
40     public void testFileUpload(){
41         try {
42             OutputStream os = fs.create(new Path("/test.log"));
43             FileInputStream fis = new FileInputStream("I://test.log");
44             IOUtils.copyBytes(fis, os, 2048,true);
45             //可以使用hadoop提供的简单方式
46             fs.copyFromLocalFile(new Path("I://test.log"), new Path("/test.log"));
47         } catch (IllegalArgumentException | IOException e) {
48             e.printStackTrace();
49         }
50     }
51     @Test
52     /**
53      * 文件下载
54      */
55     public void testFileDownload(){
56         try {
57             InputStream is = fs.open(new Path("/test.log"));
58             FileOutputStream fos = new FileOutputStream("E://test.log");
59             IOUtils.copyBytes(is, fos, 2048);
60             //可以使用hadoop提供的简单方式
61             fs.copyToLocalFile(new Path("/test.log"), new Path("E://test.log"));
62         } catch (IllegalArgumentException | IOException e) {
63             e.printStackTrace();
64         }
65     }
66
67 }
21/212>
《2023软件测试行业现状调查报告》独家发布~

关注51Testing

联系我们

快捷面板 站点地图 联系我们 广告服务 关于我们 站长统计 发展历程

法律顾问:上海兰迪律师事务所 项棋律师
版权所有 上海博为峰软件技术股份有限公司 Copyright©51testing.com 2003-2024
投诉及意见反馈:webmaster@51testing.com; 业务联系:service@51testing.com 021-64471599-8017

沪ICP备05003035号

沪公网安备 31010102002173号