本文基于Hadoop1.X

概述

分布式文件系统主要用来解决如下几个问题:

  • 读写大文件
  • 加速运算

对于某些体积巨大的文件,比如其大小超过了计算机文件系统所能存放的最大限制或者是其大小甚至超过了计算机整个硬盘的容量的文件,这时需要将文件分割为若干较小的块,然后将这些块按照一定的规则分放在集群中若干台节点计算机里。

分布式文件系统的另一个作用是加速运算,在多台计算机上对每个子文件进行计算最后再汇总结果通常比在一台计算机上处理大量文件的运算要块。这种分而治之的思想倡导:与其追求造价昂贵的高性能计算机,不如多找几个性能普通的廉价机器来搞。

廉价的机器集群还有一个比单个高性能计算机更有优势的地方是灵活性,可以非常方便的增加或减少集群中节点的数量,比起单个高性能机器,这种设计在计规模小时也不会造成资源(CPU,内存)的浪费,在规模膨胀时又能通过简单的增加节点的动作轻松应对。

然而,任何事情都有两面性,集群的弱点在于出现故障的几率变大了,假设单台机器故障率是p,那么具有n台机器节点的集群故障率就是pn,为了能够在某些节点出现故障的情况下不影响整个集群的健康,集群中不得不将每个节点中的数据备份多份放在别的节点,这样当某个节点的数据不可用时还可以读取备份节点的数据。集群以冗余为代价换取高可用性

HDFS(Hadoop Distrbuted File System)是当今世界上最流行的分布式大数据处理系统Hadoop所依赖的文件系统,它的思想源头是伟大的Google公司发表的论文:The Google File System,受此启发,雅虎的若干大神包括Doug Cutting等把它搞出来的。

HDFS的特点

  • 适合处理超大文件:超大文件是指大小超过几百M,几百G甚至几百T的文件。HDFS不适合处理小文件,首先,HDFS的文件块(block)默认为64M,太小的文件会造成磁盘的浪费;其次,HDFS的元数据信息(记录文件、路径和分块情况等信息)保存在某个节点(NameNode)的内存中,大量的小文件需要大量的元素据来记录,大量的元素据需要大量的内存;
  • 流式数据访问:一次写入数据,然后多次读取数据的大部分甚至全部进行分析,不支持随机读取操作
  • 对节点计算机的要求较低:无需昂贵的高性能机器,集群可由廉价机器组成
  • 不适合对数据读写延时有严格要求的场景:HDFS重在高吞吐量,付出的代价之一就是提高了延迟时间
  • 不支持多用户写入,不支持随机写操作:只能顺序将数据添加到文件结尾

想要实现随机读写以及延时较低的数据读写,请考虑使用基于HDFS的HBase数据库。

HDFS的结构

HDFS是一个基于操作系统本身的文件系统之上的虚拟文件系统,和常见的文件系统一样,HDFS文件存储的最小单元是块(block),默认的块的大小是64M,一个文件的若干块可分布在不同的机器上(DataNode),所以才“分布式”了。

集群节点由三部分组成,分别是

  • NameNode (只有一个)
  • DataNode
  • Secondary NameNode(只有一个)

NameNode节点负责保存和维护整个集群的元数据(Hadoop2并不是这样,希望后续文章会涉及),包括文件名、文件分块(block)、文件的块分布在哪些节点、整个文件系统的运行状态等信息,一个集群中只有一个节点是NameNode节点。

DataNode节点负责实际存放数据。

由于整个集群只有一个NameNode节点,该节点如果挂了整个集群也就完蛋了,所有又搞了一个Secondary NameNode出来,它会定时获取NameNode的快照,当NameNode挂掉后可以通过Secondary NameNode快速恢复(Hadoop2并不是这样,希望后续文章会涉及)。

下图来自《Hadoop 实战》:

文件data1和data2的元数据信息保存在NameNode节点中,元数据中记录了data1文件由3个文件块1,2和3组成,文件data2由2个文件块4和5组成,并且记录了每个块所在的DataNode节点。文件块分布在4个DataNode节点上,每个文件块有都保存3份(3份是默认的设置)。DataNode还定时给NameNode发送心跳数据,如果NameNode长时间没有收到心跳数据,则认为DataNode挂掉了。

HDFS的命令行接口

下载并安装Hadoop后,即可使用HDFS了,Hadoop的安装和配置请参考Hadoop学习之旅一:Hello Hadoop。HDFS类似于Unix的文件系统,权限的设定也是分w、r和x(可执行ls命令查看,该命令类似Unix的ls -l 命令),常用命令和Unix的文件操作命令相同或类似,下面介绍几个常用的命令:

  • ls: bin/hadoop fs -ls /user #列出路径/user下的所有文件和路径
  • lsr: `bin/hadoop fs -lsr /user #列出路径/user下的所有文件并递归列出子路径及子路经下的文件
  • mkdir: bin/hadoop fs -mkdir /user/hdfs_test #创建路径 /user/hdfs_test
  • rmr: bin/hadoop fs -rmr /user/hdfs_test #删除路径 /user/hdfs_test
  • put: bin/hadoop fs -put hello.txt /user/hdfs_test #拷贝本地文件到HDFS路径/user/hdfs_test
  • get: bin/hadoop fs -get /user/hdfs_test/hello.txt /home/joey #将hello.txt文件从HDFS拷贝到本地文件系统
  • cat: bin/hadoop fs -cat /user/hdfs_test/hello.txt #查看文件内容

更多命令请查看官方文档

HDFS的Java编程接口

实际上,上面的命令行接口就是一个Java应用,下面利用编程接口写一个示例程序,该程序使用FileSysgem类读取本地参数指定的路径下以“hadoop”开头的文件并将其复制到参数指定的HDFS路径:

package test.joye.com;

import java.io.IOException;

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; public class Copy { public static void main(String[] args) { Path localPath = new Path(args[0]); // /home/joey/test"
String hdfsPath = args[1]; // /user/hdfs
Configuration conf = new Configuration();
conf.set("fs.default.name", "hdfs://localhost:9000"); try {
FileSystem hdfs = FileSystem.get(conf);
FileSystem local = FileSystem.getLocal(conf); FileStatus[] inputFiles = local.listStatus(localPath);
for(int i = 0; i < inputFiles.length; i++){
String fileName = inputFiles[i].getPath().getName();
if(fileName.startsWith("hadoop")){
FSDataOutputStream out = hdfs.create(new Path(hdfsPath + "/" + fileName));
FSDataInputStream in = local.open(inputFiles[i].getPath());
byte[] buffer = new byte[256];
int bytesRead = 0;
while((bytesRead = in.read(buffer)) > 0){
out.write(buffer, 0, bytesRead);
}
in.close();
out.close();
}
} } catch (IOException e) {
e.printStackTrace();
}
} }

该程序引用了如下包:



关于更多的API可以参考官方文档

参考资料

Hadoop学习之旅二:HDFS的更多相关文章

  1. Hadoop学习之旅三:MapReduce

    MapReduce编程模型 在Google的一篇重要的论文MapReduce: Simplified Data Processing on Large Clusters中提到,Google公司有大量的 ...

  2. hadoop学习第二天-了解HDFS的基本概念&&分布式集群的搭建&&HDFS基本命令的使用

    一.HDFS的相关基本概念 1.数据块 1.在HDFS中,文件诶切分成固定大小的数据块,默认大小为64MB(hadoop2.x以后是128M),也可以自己配置. 2.为何数据块如此大,因为数据传输时间 ...

  3. hadoop学习之旅1

    大数据介绍 大数据本质也是数据,但是又有了新的特征,包括数据来源广.数据格式多样化(结构化数据.非结构化数据.Excel文件.文本文件等).数据量大(最少也是TB级别的.甚至可能是PB级别).数据增长 ...

  4. hadoop学习笔记(二):简单启动

    一.hadoop组件依赖关系 二.hadoop日志格式: 两种日志,分别以out和log结尾: 1 以log结尾的日志:通过log4j日志记录格式进行记录的日志,采用日常滚动文件后缀策略来命名日志文件 ...

  5. 滴滴Booster移动APP质量优化框架 学习之旅 二

    推荐阅读: 滴滴Booster移动App质量优化框架-学习之旅 一 Android 模块Api化演练 不一样视角的Glide剖析(一) 续写滴滴Booster移动APP质量优化框架学习之旅,上篇文章分 ...

  6. Hadoop学习(2)-- HDFS

    随着信息技术的高度发展,数据量越来越多,当一个操作系统管辖范围存储不下时,只能将数据分配到更多的磁盘中存储,但是数据分散在多台磁盘上非常不方便管理和维护,迫切需要一种系统来管理多台机器上的文件,因此诞 ...

  7. Hadoop学习总结之二:HDFS读写过程解析

    一.文件的打开 1.1.客户端 HDFS打开一个文件,需要在客户端调用DistributedFileSystem.open(Path f, int bufferSize),其实现为: public F ...

  8. Hadoop 学习笔记(二) HDFS API

    4.删除HDFS上的文件 package proj; import java.io.IOException; import org.apache.hadoop.conf.Configuration; ...

  9. hadoop学习笔记(二):hdfs优点和缺点

    优点 其中的10k+,指的是每一个块必须>=1M 缺点 低延迟:是指hadoop处理数据都是以分钟为单位的,而不像storm那样的是以毫秒级为单位的. 高吞吐率:是指你分布式存储的文件块的大小必 ...

随机推荐

  1. Angular杂谈系列1-如何在Angular2中使用jQuery及其插件

    jQuery,让我们对dom的操作更加便捷.由于其易用性和可扩展性,jQuer也迅速风靡全球,各种插件也是目不暇接. 我相信很多人并不能直接远离jQuery去做前端,因为它太好用了,我们以前做的东西大 ...

  2. Linux虚拟机的安装(使用Centos6.3)

    1.什么是虚拟机? 虚拟机指通过软件模拟的具有完整硬件系统功能的.运行在一个完全隔离环境中的完整计算机系统 2.安装Linux虚拟机前要做的准备 2.1:一台windows环境的pc 2.2:下载VM ...

  3. html5标签canvas函数drawImage使用方法

    html5中标签canvas,函数drawImage(): 使用drawImage()方法绘制图像.绘图环境提供了该方法的三个不同版本.参数传递三种形式: drawImage(image,x,y):在 ...

  4. android http 抓包

    有时候想开发的时候想看APP发出的http请求和响应是什么,这就需要抓包了,这可以得到一些不为人知的api,比如还可以干些“坏事”... 需要工具: Fiddler2 抓包(点击下载) Android ...

  5. MVC5 网站开发之九 网站设置

    网站配置一般用来保存网站的一些设置,写在配置文件中比写在数据库中要合适一下,因为配置文件本身带有缓存,随网站启动读入缓存中,速度更快,而保存在数据库中要单独为一条记录创建一个表,结构不够清晰,而且读写 ...

  6. Android数据存储之Android 6.0运行时权限下文件存储的思考

    前言: 在我们做App开发的过程中基本上都会用到文件存储,所以文件存储对于我们来说是相当熟悉了,不过自从Android 6.0发布之后,基于运行时权限机制访问外置sdcard是需要动态申请权限,所以以 ...

  7. C#创建dll类库

    类库让我们的代码可复用,我们只需要在类库中声明变量一次,就能在接下来的过程中无数次地使用,而无需在每次使用前都要声明它.这样一来,就节省了我们的内存空间.而想要在类库添加什么类,还需取决于类库要实现哪 ...

  8. 如何为你的微信小程序体积瘦身?

    众所周知,微信小程序在发布的时候,对提交的代码有1M大小的限制!所以,如果你正在写一个功能稍微复杂一点的小程序,就必须得时刻小心注意你的代码是不是快触及这个底线了. 在设计一个小程序之初,我们就需要重 ...

  9. 【开源】专业K线绘制[K线主副图、趋势图、成交量、滚动、放大缩小、MACD、KDJ等)

    这是一个iOS项目雅黑深邃的K线的绘制. 实现功能包括K线主副图.趋势图.成交量.滚动.放大缩小.MACD.KDJ,长按显示辅助线等功能 预览图 最后的最后,这是项目的开源地址:https://git ...

  10. atitit.细节决定成败的适合情形与缺点

    atitit.细节决定成败的适合情形与缺点 1. 在理论界有两种观点:一种是"细节决定成败",另一种是"战略决定成败".1 1.1. 格局决定成败,方向决定成败 ...