Hadoop学习笔记—2.不怕故障的海量存储:HDFS基础入门

一.HDFS出现的背景

  随着社会的进步,需要处理数据量越来越多,在一个操作系统管辖的范围存不下了,那么就分配到更多的操作系统管理的磁盘中,但是却不方便管理和维护—>因此,迫切需要一种系统来管理多台机器上的文件,于是就产生了分布式文件管理系统,英文名成为DFSDistributed File System)。

  那么,什么是分布式文件系统?简而言之,就是一种允许文件通过网络在多台主机上分享的文件系统,可以让多个机器上的多个用户分享文件和存储空间。它最大的特点是“通透性”,DFS让实际上是通过网络来访问文件的动作,由用户和程序看来,就像是访问本地的磁盘一般(In other words,使用DFS访问数据,你感觉不到是访问远程不同机器上的数据)。

图1.一个典型的DFS示例

二.深入了解HDFS原理

  作为Hadoop的核心技术之一,HDFS(Hadoop Distributed File System,Hadoop分布式文件系统)是分布式计算中数据存储管理的基础。它所具有的高容错、高可靠、高可扩展性、高吞吐率等特性为海量数据提供了不怕故障的存储,也为超大规模数据集(Large Data Set)的应用处理带来了很多便利。

  图2.Hadoop HDFS的LOGO

  提到HDFS,不得不说Google的GFS。正是Google发表了关于GFS的论文,才有了HDFS这个关于GFS的开源实现。

2.1 设计前提与目标

  (1)硬件错误是常态而不是异常;(最核心的设计目标—>HDFS被设计为运行在众多的普通硬件上,所以硬件故障是很正常的。因此,错误检测并快速恢复是HDFS最核心的设计目标)

  (2)流式数据访问;(HDFS更关注数据访问的高吞吐量)

  (3)大规模数据集;(HDFS的典型文件大小大多都在GB甚至TB级别)

  (4)简单一致性模型;(一次写入,多次读取的访问模式)

  (5)移动计算比移动数据更为划算;(对于大文件来说,移动计算比移动数据的代价要低)

2.2 HDFS的体系结构

  HDFS是一个主/从(Master/Slave)式的结构,如下图所示。

  

  图3.HDFS的基本架构

  从最终用户的角度来看,它就像传统的文件系统一样,可以通过目录路径对文件执行CRUD(增删查改)操作。但由于分布式存储的性质,HDFS拥有一个NameNode和一些DataNodes。NameNode管理文件系统的元数据,DataNode存储实际的数据。客户端通过同NameNode和DataNode的交互访问文件系统→客户端联系NameNode以获取文件的元数据,而真正的I/O操作是直接和DataNode进行交互的。

  下面我们再来看看HDFS的读操作和写操作的流程:

  ①读操作

  图4.HDFS的读操作

  客户端要访问一个文件,首先,客户端从NameNode中获得组成该文件数据块位置列表,即知道数据块被存储在哪几个DataNode上;然后,客户端直接从DataNode上读取文件数据。在此过程中,NameNode不参与文件的传输。

  ②写操作

write

图5.HDFS的写操作

  客户端首先需要向NameNode发起写请求,NameNode会根据文件大小和文件块配置情况,返回给Client它所管理部分DataNode的信息。最后,Client(开发库)将文件划分为多个文件块,根据DataNode的地址信息,按顺序写入到每一个DataNode块中。

  下面我们看看NameNode和DataNode扮演什么角色,有什么具体的作用:

  (1)NameNode

  NameNode的作用是管理文件目录结构,是管理数据节点的。NameNode维护两套数据:一套是文件目录与数据块之间的关系,另一套是数据块与节点间的关系。前一套是静态的,是存放在磁盘上的,通过fsimage和edits文件来维护;后一套数据时动态的,不持久化到磁盘,每当集群启动的时候,会自动建立这些信息。

  (2)DataNode

  毫无疑问,DataNode是HDFS中真正存储数据的。这里要提到一点,就是Block(数据块)。假设文件大小是100GB,从字节位置0开始,每64MB字节划分为一个Block,以此类推,可以划分出很多的Block。每个Block就是64MB(也可以自定义设置Block大小)。

  (3)典型部署

  HDFS的一个典型部署是在一个专门的机器上运行NameNode,集群中的其他机器各运行一个DataNode。(当然,也可以在运行NameNode的机器上同时运行DataNode,或者一个机器上运行多个DataNode)一个集群中只有一个NameNode(但是单NameNode存在单点问题,在Hadoop 2.x版本之后解决了这个问题)的设计大大简化了系统架构。

2.3 保障HDFS的可靠性措施

  HDFS具备了较为完善的冗余备份和故障恢复机制,可以实现在集群中可靠地存储海量文件。

  (1)冗余备份:HDFS将每个文件存储成一系列的数据块Block),默认块大小为64MB(可以自定义配置)。为了容错,文件的所有数据块都可以有副本(默认为3个,可以自定义配置)。当DataNode启动的时候,它会遍历本地文件系统,产生一份HDFS数据块和本地文件对应关系的列表,并把这个报告发送给NameNode,这就是报告块(BlockReport),报告块上包含了DataNode上所有块的列表。

  (2)副本存放:HDFS集群一般运行在多个机架上,不同机架上机器的通信需要通过交换机。通常情况下,副本的存放策略很关键,机架内节点之间的带宽比跨机架节点之间的带宽要大,它能影响HDFS的可靠性和性能。HDFS采用一种称为机架感知(Rack-aware)的策略来改进数据的可靠性、可用性和网络带宽的利用率。在大多数情况下,HDFS副本系数是默认为3,HDFS的存放策略是将一个副本存放在本地机架节点上,一个副本存放在同一个机架的另一个节点上,最后一个副本放在不同机架的节点上。这种策略减少了机架间的数据传输,提高了写操作的效率。机架的错误远远比节点的错误少所以这种策略不会影响到数据的可靠性和可用性。

  图6.副本存放的策略

  (3)心跳检测:NameNode周期性地从集群中的每个DataNode接受心跳包和块报告,NameNode可以根据这个报告验证映射和其他文件系统元数据。收到心跳包,说明该DataNode工作正常。如果DataNode不能发送心跳信息,NameNode会标记最近没有心跳的DataNode为宕机,并且不会给他们发送任何I/O请求。

  (4)安全模式

  (5)数据完整性检测

  (6)空间回收

  (7)元数据磁盘失效

  (8)快照(HDFS目前还不支持)

三.HDFS常用Shell操作

  (1)列出文件目录:hadoop fs -ls 目录路径

     查看HDFS根目录下的目录:hadoop fs -ls /

     递归查看HDFS根目录下的目录:hadoop fs -lsr /

  (2)在HDFS中创建文件夹:hadoop fs -mkdir 文件夹名称

    在根目录下创建一个名称为di的文件夹:

  (3)上传文件到HDFS中:hadoop fs -put 本地源路径 目标存放路径

    将本地系统中的一个log文件上传到di文件夹中:hadoop fs -put test.log /di

*PS:我们通过Hadoop Shell上传的文件是存放在DataNode的Block(数据块)中的,通过Linux Shell是看不到文件的,只能看到Block。因此,可以用一句话来描述HDFS:把客户端的大文件存放在很多节点的数据块中。

  (4)从HDFS中下载文件:hadoop fs -get HDFS文件路径 本地存放路径

    将刚刚上传的test.log下载到本地的Desktop文件夹中:hadoop fs -get /di/test.log /home/hadoop/Desktop

  (5)直接在HDFS中查看某个文件:hadoop fs -text(-cat) 文件存放路径

    在HDFS查看刚刚上传的test.log文件:hadoop fs -text /di/test.log

  (6)删除在HDFS中的某个文件(夹):hadoop fs -rm(r) 文件存放路径

    删除刚刚上传的test.log文件:hadoop fs -rm /di/test.log

    删除HDFS中的di文件夹:hadoop fs -rmr /di

  (7)善用help命令求帮助:hadoop fs -help 命令

    查看ls命令的帮助:hadoop fs -help ls

四.使用Java操作HDFS

  我们在工作中写完的各种代码是在服务器中运行的,HDFS的操作代码也不例外。在开发阶段,我们使用Windows下的Eclipse作为开发环境,访问运行在虚拟机中的HDFS,也就是通过在本地的Eclipse中的Java代码访问远程Linux中的HDFS。

在本地的开发调试过程中,要使用宿主机中的Java代码访问客户机中的HDFS,需要确保以下几点:
宿主机和虚拟机的网络能否互通?确保宿主机和虚拟机中的防火墙都关闭!确保宿主机与虚拟机中的jdk版本一致!                                 

  4.1 准备工作:

  (1)导入依赖jar包,如下图所示

  

  (2)关联hadoop源码项目,如下图所示

  

  4.2 第一个Java-HDFS程序

  (1)定义HDFS_PATH:public static final String HDFS_PATH = "hdfs://hadoop-master:9000/testdir/testfile.log";

  (2)让URL类型识别hdfs://(URL类型默认只识别http://):URL.setURLStreamHandlerFactory(new FsUrlStreamHandlerFactory());

  (3)具体详细代码如下:

 1 package hdfs;
 2 
 3 import java.io.InputStream;
 4 import java.net.MalformedURLException;
 5 import java.net.URL;
 6 
 7 import org.apache.hadoop.fs.FsUrlStreamHandlerFactory;
 8 import org.apache.hadoop.io.IOUtils;
 9 
10 public class firstApp {
11     
12     public static final String HDFS_PATH = "hdfs://hadoop-master:9000/testdir/testfile.log";
13     
14     /**
15      * @param args
16      * @throws MalformedURLException 
17      */
18     public static void main(String[] args) throws Exception {
19         // TODO Auto-generated method stub
20         URL.setURLStreamHandlerFactory(new FsUrlStreamHandlerFactory());
21         final URL url = new URL(HDFS_PATH);
22         final InputStream in = url.openStream();
23         /**
24          * @params in 输入流
25          * @params out 输出流
26          * @params buffersize 缓冲区大小
27          * @params close 是否自动关闭流
28          */
29         IOUtils.copyBytes(in, System.out, 1024, true);
30     }
31 
32 }
View Code

    (4)运行结果(后面不再贴运行结果图):

  

  4.3 对HDFS进行CRUD编程

  (1)获得万能的大神对象:final FileSystem fileSystem = FileSystem.get(new URI(HDFS_PATH),new Configuration());

  (2)调用HDFS API进行CRUD操作,详情见下代码

public class FileSystemApp {private static final String HDFS_PATH = "hdfs://hadoop-master:9000/testdir/";private static final String HDFS_DIR = "/testdir/dir1";public static void main(String[] args) throws Exception {FileSystem fs = getFileSystem();// 01.创建文件夹  对应shell:mkdir
        createDirectory(fs);// 02.删除文件  对应shell:hadoop fs -rm(r) xxx
        deleteFile(fs);// 03.上传文件  对应shell:hadoop fs -input xxx
        uploadFile(fs);// 04.下载文件  对应shell:hadoop fs -get xxx xxx
        downloadFile(fs);// 05.浏览文件夹  对应shell:hadoop fs -lsr /listFiles(fs,"/");}private static void listFiles(FileSystem fs,String para) throws IOException {final FileStatus[] listStatus = fs.listStatus(new Path(para));for (FileStatus fileStatus : listStatus) {String isDir = fileStatus.isDir() ? "Directory" : "File";String permission = fileStatus.getPermission().toString();short replication = fileStatus.getReplication();long length = fileStatus.getLen();String path = fileStatus.getPath().toString();System.out.println(isDir + "\t" + permission + "\t" + replication+ "\t" + length + "\t" + path);if(isDir.equals("Directory")){listFiles(fs, path);}}}private static void downloadFile(FileSystem fs) throws IOException {final FSDataInputStream in = fs.open(new Path(HDFS_PATH + "check.log"));final FileOutputStream out = new FileOutputStream("E:\\check.log");IOUtils.copyBytes(in, out, 1024, true);System.out.println("Download File Success!");}private static void uploadFile(FileSystem fs) throws IOException {final FSDataOutputStream out = fs.create(new Path(HDFS_PATH+ "check.log"));final FileInputStream in = new FileInputStream("C:\\CheckMemory.log");IOUtils.copyBytes(in, out, 1024, true);System.out.println("Upload File Success!");}private static void deleteFile(FileSystem fs) throws IOException {fs.delete(new Path(HDFS_DIR), true);System.out.println("Delete File:" + HDFS_DIR + " Success!");}private static void createDirectory(FileSystem fs) throws IOException {fs.mkdirs(new Path(HDFS_DIR));System.out.println("Create Directory:" + HDFS_DIR + " Success!");}private static FileSystem getFileSystem() throws IOException,URISyntaxException {return FileSystem.get(new URI(HDFS_PATH), new Configuration());}}
View Code

参考文献与资料

  (1)传智播客Hadoop从入门到工作视频教程第二季:http://bbs.itcast.cn/thread-21310-1-1.html

  (2)刘鹏教授,《实战Hadoop:开启通向云计算的捷径》:http://item.jd.com/10830089.html

  (3)吴超,《Hadoop的底层架构——RPC机制》:http://www.superwu.cn/2013/08/05/360

  (4)zy19982004,《Hadoop学习十一:Hadoop-HDFS RPC总结》:http://zy19982004.iteye.com/blog/1875969

 

转载于:https://www.cnblogs.com/edisonchou/p/3538524.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/263230.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

ASP.NET的错误处理机制之一(概念)

对Web应用程序来说,发生不可预知的错误和异常在所难免,我们必须为Web程序提供错误处理机制。当错误发生时,我们必须做好两件事情:一是将错误信息记录日志,发邮件通知网站维护人员,方便技术人员对错误进行跟…

改善用户体验之Alert提示效果

功能&#xff1a;替换传统弹出窗口提示 window.alert("");好处&#xff1a;界面美观&#xff0c;友善(最起码没有系统报警的声音&#xff09;。引用方便&#xff0c;纯js脚本文件实现所有效果。使用方法&#xff1a;<!DOCTYPE html PUBLIC "-//W3C//DTD XHTM…

LeetCode—<动态规划专项>剑指 Offer 42、46、47、48

剑指 Offer 42. 连续子数组的最大和、剑指 Offer 46. 把数字翻译成字符串、剑指 Offer 47. 礼物的最大价值、剑指 Offer 48. 最长不含重复字符的子字符串 题目描述&#xff1a; [42] [46] [47] [48] 考察重点&#xff1a;第42题要计算最大子数组和&#xff0c;考虑第i位…

常用JQuery插件整理

虽然自己也写过插件&#xff0c;但JQuery插件种类的繁多&#xff0c;大多时候&#xff0c;我还是使用别人写好的插件&#xff0c;这些都是我用了同类插件里较为不错的一些&#xff0c;今天就整理一下公开放出来。 UI&#xff1a; jquery.HooRay&#xff08;哈哈&#xff0c;自己…

操作系统核心原理-5.内存管理(下):段式内存管理

一、分页系统的缺点 分页系统存在的一个无法容忍&#xff0c;同时也是分页系统无法解决的一个缺点就是&#xff1a;一个进程只能占有一个虚拟地址空间。在此种限制下&#xff0c;一个程序的大小至多只能和虚拟空间一样大&#xff0c;其所有内容都必须从这个共同的虚拟空间内分配…

局域网连接SQL Server数据库配置

首先要保证两台机器位于同一局域网内&#xff0c;然后打开配置工具→SQL Server配置管理器进行配置。将MSSQLSERVER的协议的TCP/IP的&#xff08;IP1。IP2&#xff09;TCPport改为1433&#xff0c;已启用改为是。 server名称:输入IP 登录名:输入数据库帐号 password:输入数据库…

驳AXAJ的七宗罪 (转)

我不带任何主观色彩来评一下这个所谓的 “AJAX 的七宗罪”。 1、连带着 Flash 和 Ajax 一块骂了。 引用:没有链接的web就像森林中迷路的羔羊&#xff0c;这句看似广告语&#xff0c;其实是web设计的根本原则。 这句“原则”至少我并不知道&#xff0c;因此看起来不过就是一句…

LeetCode—<双指针专项>剑指 Offer 18、21、22、25、52、57、58 - I

剑指 Offer 18. 删除链表的节点、21. 调整数组顺序使奇数位于偶数前面、22. 链表中倒数第k个节点、25. 合并两个排序的链表、52. 两个链表的第一个公共节点、57. 和为s的两个数字、58 - I. 翻转单词顺序 题目描述&#xff1a; [18] 给定单向链表的头指针和一个要删除的节点的值…

Android应用程序绑定服务(bindService)的过程源代码分析

Android应用程序组件Service与Activity一样&#xff0c;既可以在新的进程中启动&#xff0c;也可以在应用程序进程内部启动&#xff1b;前面我们已经分析了在新的进程中启动Service的过程&#xff0c;本文将要介绍在应用程序内部绑定Service的过程&#xff0c;这是一种在应用程…

递归-汉诺塔

#A&#xff1a;起始&#xff0c;B&#xff1a;中间&#xff0c;C&#xff1a;最后count0def hanoi(n,A,B,C): global count if n1: print("{}:{}->{}".format(1,A,C)) count1 else: hanoi(n-1,A,C,B) #将前n…

Bootstrap系列 -- 8. 代码显示

一. Bootstrap中的代码块 代码块一般在博客中使用的较多&#xff0c;比较博客园中提供的贴代码. 在Bootstrap中提供了三种形式的代码显示 1. 使用<code></code>来显示单行内联代码 2. 使用<pre></pre>来显示多行块代码 3. 使用<kbd></kbd>…

PowerDesigner12对SQL2005反向工程问题.

用PowerDesigner12利用ODBC连接SQL2005进行反向工程&#xff0c;总分报错[Microsoft][ODBC SQL Server Driver][SQL Server]未能准备评语句SQLSTATE37000解决办法&#xff1a;把&#xff02;更改默认的数据库为&#xff02;这个选项去掉在中选择要进行操做的数据库.转载于:http…

LeetCode—<搜索与回溯专项>剑指 Offer 12、13、34、36、54

剑指 Offer 12. 矩阵中的路径、13. 机器人的运动范围、34. 二叉树中和为某一值的路径、36. 二叉搜索树与双向链表、54. 二叉搜索树的第k大节点 题目描述&#xff1a; [12] 给定一个 m x n 二维字符网格 board 和一个字符串单词 word 。如果 word 存在于网格中&#xff0c;返回…

导数--基本概念

转载于:https://www.cnblogs.com/liuys635/p/11242741.html

解决IE6、IE7、Firefox兼容最简单的CSS Hack

写三句代码来控制一个属性&#xff0c;区别Firefox&#xff0c;IE7&#xff0c;IE6&#xff1a; background:orange; *background:green !important; *background:blue; 说明&#xff1a;这段代码会使在Firefox中&#xff0c;背景呈橙色&#xff1b;IE7中为绿色&#xf…

[导入]创建、查询、修改带名称空间的 XML 文件的例子

XML的应用越来越广泛了&#xff0c;如Vista、Flex编程都将使用 XML&#xff0c;正确掌握XML的各种操作&#xff0c;对提高编程效率至关重要。下面就是一个综合处理带名称空间的XML的例子。 文章来源:http://blog.csdn.net/net_lover/archive/2006/12/18/1447434.aspx 转载于:ht…

Kernel那些事儿之内存管理(2) --- 百闻不如一见

上次介绍了物理内存管理中三位主要人物中的node 和zone。这两位是当官的&#xff0c;一个是县长&#xff0c;一个是里长&#xff0c;不敢不先介绍啊。接下来出场的就是我们的老百姓了 --- page frame。Page frame是物理内存的基本组成单位&#xff0c;在Kernel中由结构体 struc…

LeetCode—<排序专项>剑指 Offer 40、41、45、61

剑指 Offer 40. 最小的k个数、41. 数据流中的中位数、45. 把数组排成最小的数、61. 扑克牌中的顺子 题目描述&#xff1a; [40] 输入整数数组 arr &#xff0c;找出其中最小的 k 个数。例如&#xff0c;输入4、5、1、6、2、7、3、8这8个数字&#xff0c;则最小的4个数字是1、2…

归并 快排 快速幂

/* 归并排序&#xff1a;不断将数组切分为两部分递归切分直到数组长度为1&#xff0c;之后逐渐有序合并 */ #include <cstdio> #include <iostream> #include <cmath> using namespace std;//归并 小-->大 void Merge(int a[], int s, int m, int e, int …

dev GridControl双击行事件

今天用到了gridcontrol这个控件,要求写一个gridview的双击事件,因为想要的效果是只双击行才出Message,用gridview的Double_Click我没实现,后来想到MouseDown,一试,很简单,首先,仍旧需要将gridview1.OptionsBehavior.Editable设为false,下面是代码: Skelta BPM.NET&#xff08…