hadoop2.x之HDFS

1.HDFS简介

HDFS(有时也成为DFS)是Hadoop的分布式文件系统。他可以将一个文件分布在多个主机上

例如:现在有一个200GB的文件,我们有5台电脑,每台存储为100GB,所以我们在一台电脑上是无法存放该文件的。这时我们就需要将其分区(就是切割成好几块)然后将它分别存储在各个主机上(每个电脑存储40GB的)。这就是HDFS的原理。

1. HDFS的特性

HDFS的优势:

  • 超大文件存储
    HDFS能够存储超大文件,几百MB,几百GB,几百TB,甚至几百PB

  • 流式数据访问
    流式数据,像流水一样,不是一次过来而是一点一点“流”过来。而处理流式数据也是一点一点处理。如果是全部收到数据以后再处理,那么延迟会很大,而且在很多场合会消耗大量内存。

  • 商用硬件
    就是普通的硬件,不需要昂贵可靠性高的硬件,只需要普通的PC机的硬件就可以。

HDFS的弊端:

  • 延迟高
    HDFS是为了高数据吞吐量应用优化的,相应的牺牲了时间,因此延迟较高。如果对延迟有要求可以用HBase

  • 对小文件支持不好
    文件的存储信息大约为150字节,如果大量小文件,例如一亿个,就需要namenode有30GB的内存,显然是不可以的。

  • 文件只能添加/删除/追加,不能修改
    HDFS文件只能添加/删除/追加,不能修改和多用户同时追加

2.HDFS数据块
HDFS的数据块很大,默认为64MB,很多情况下为128MB,这是为了最小化寻址开销。假设寻址时间为10ms,传输速率为100m/s,那么对于大数据块,寻址时间则大约为1%。

3. namenode和datanode
HDFS是以管理者-工作者的模式运行的。即有一个namenode和多个datanode,namenode管理文件系统的命名空间,以及文件信息。namenode也管理者各个文件中各个块所在的数据节点信息。

4.联邦HDFS

5.HDFS高可用

6.HDFS在Hadoop的配置
Hadoop中对HDFS有两个关键的配置

  • 第一个是fs.default.name设置默认的文件系统,设置为:hdfs://localhost:9000/这样我们后面用到的绝对路径都是相对于这个路径。配置在core-site.xml文件中

  • 第二个是dfs.replication设置副本数,HDFS通过设置多个副本冗余的方式来实现容错,默认设置为3,通过设置这个我们可以改变副本数目,例如在伪分布式下需要设置为1.

02.HDFS命令行接口

我们所常使用的文件操作,例如:读取文件,新建目录,移动文件,删除数据,列出目录等,HDFS都可以做到,我们使用hadoop fs -help命令可以查询详细的帮助文档

[grid@tiny01 ~]$ hadoop fs -help
Usage: hadoop fs [generic options]
        [-appendToFile  ... ]
        [-cat [-ignoreCrc]  ...]
        [-checksum  ...]
        [-chgrp [-R] GROUP PATH...]
        [-chmod [-R] ... | OCTALMODE> PATH...]
        [-chown [-R] [OWNER][:[GROUP]] PATH...]
        [-copyFromLocal [-f] [-p] [-l]  ... ]
        [-copyToLocal [-p] [-ignoreCrc] [-crc]  ... ]
        [-count [-q] [-h]  ...]
        [-cp [-f] [-p | -p[topax]]  ... ]
        [-createSnapshot  []]
        [-deleteSnapshot  ]
        [-df [-h] [ ...]]
        [-du [-s] [-h]  ...]
        [-expunge]
        [-find  ...  ...]
        [-get [-p] [-ignoreCrc] [-crc]  ... ]
        [-getfacl [-R] ]
        [-getfattr [-R] {-n name | -d} [-e en] ]
        [-getmerge [-nl]  ]
        [-help [cmd ...]]
        [-ls [-d] [-h] [-R] [ ...]]
        [-mkdir [-p]  ...]
        [-moveFromLocal  ... ]
        [-moveToLocal  ]
        [-mv  ... ]
        [-put [-f] [-p] [-l]  ... ]
        [-renameSnapshot   ]
        [-rm [-f] [-r|-R] [-skipTrash]  ...]
        [-rmdir [--ignore-fail-on-non-empty]  ...]
        [-setfacl [-R] [{-b|-k} {-m|-x } ]|[--set  ]]
        [-setfattr {-n name [-v value] | -x name} ]
        [-setrep [-R] [-w]   ...]
        [-stat [format]  ...]
        [-tail [-f] ]
        [-test -[defsz] ]
        [-text [-ignoreCrc]  ...]
        [-touchz  ...]
        [-truncate [-w]   ...]
        [-usage [cmd ...]]

Generic options supported are
-conf      specify an application configuration file
-D             use value for given property
-fs       specify a namenode
-jt     specify a ResourceManager
-files     specify comma separated files to be copied to the map reduce cluster
-libjars     specify comma separated jar files to include in the classpath.
-archives     specify comma separated archives to be unarchived on the compute machines.

The general command line syntax is
bin/hadoop command [genericOptions] [commandOptions]

例如,我们将一个本地文件复制到HDFS上,可以使用

[grid@tiny01 ~]$ hadoop fs -copyFromLocal easy.txt /easy.txt
[grid@tiny01 ~]$ hadoop fs -ls /
Found 2 items
-rw-r--r--   1 grid supergroup  438736103 2017-07-10 02:30 /data.txt
-rw-r--r--   1 grid supergroup    4783306 2017-07-21 23:39 /easy.txt

创建目录

[grid@tiny01 ~]$ hadoop fs -mkdir /tmp
[grid@tiny01 ~]$ hadoop fs -ls /
Found 3 items
-rw-r--r--   1 grid supergroup  438736103 2017-07-10 02:30 /data.txt
-rw-r--r--   1 grid supergroup    4783306 2017-07-21 23:39 /easy.txt
drwxr-xr-x   - grid supergroup          0 2017-07-21 23:40 /tmp

等等

03.Hadoop文件系统

Hadoop可以使用多种文件系统,HDFS只是其中的一个实现。其中org.apache.hadoop.fs.FileSystem是Hadoop文件系统的抽象类,其中有多种实现

文件系统 URL方案 Java实现(org.apache.hadoop包中) 描述
local file fs.LocalFileSystem 本地文件系统
HDFS hdfs hdfs/DistributedFileSystem Hadoop的分布式文件向系统
HFTP Hftp hdfs.hftpFileSystem 一个HTTP上提供对HDFS只读访问的文件系统(和FTP无关)
HSFTP hsftp hdfs.HsftpFileSystem 同上
WebHDFS Webhdfs Hdfs.web.WebHdfsFileSystem 基于HTTP,对HDFS提供安全读写访问的文件系统,替换了HSFTP,HFTP
HAR har fs.HarFileSystem 一个构建在其他文件系统之上用于文件存档的文件系统
FTP ftp fs.ftp.FTPFileSystem 由FTP服务器支持的文件系统

Hadoop对文件系统提供了许多接口,如果我们想使用这些文件系统可以使用如下方式:

hadoop fs -ls file:///

但是建议使用HDFS文件系统。

04.Hadoop文件管理类:FileSystem

我们介绍一下Hadoop的FileSystem类的使用。

1. 从URL中读取数据
读取hdfs URL需要使用FsUrlStreamHandlerFactory实例中的调用java.net.URL对象的setUrlStreamHandlerFactory方法,每个Java虚拟机中只能使用一次这个方法,因此通常在静态方法中使用。

import java.io.InputStream;
import java.net.URL;

import org.apache.hadoop.fs.FsUrlStreamHandlerFactory;
import org.apache.hadoop.io.IOUtils;

public class UrlCat {

    static{
        URL.setURLStreamHandlerFactory(new FsUrlStreamHandlerFactory());
    }

    public static void main(String[] args) throws Exception{
        if(args.length < 1) {
            throw new RuntimeException("请输入文件路径 !");
        }
        InputStream in = null;
        try {
            in = new URL(args[0]).openStream();
        } finally{
            IOUtils.closeStream(in);
        }
        IOUtils.copyBytes(in, System.out, 4096,false);
    }

}

在Hadoop中运行:

[grid@tiny01 input]$ hadoop UrlCat file:///home/grid/input/word.txt 

如果没有出结果可能没有设置HADOOP_CLASSPATH,需要在hadoop-env.sh中设置一下。

2.从FileSystemAPI中读取数据
前面说过,我们需要使用FsUrlStreamHandlerFactory实例中的调用java.net.URL对象的setUrlStreamHandlerFactory方法,但是每个Java虚拟机中只能使用一次这个方法。因此有时我们根本不可能在应用中设置他。这种情况下我们可以使用Hadoop的FileSystem API中打开文件。

import java.io.InputStream;
import java.net.URI;

import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.io.IOUtils;

public class FileSystemCat {

    public static void main(String[] args) throws Exception{
        String url = args[0];
        Configuration conf = new Configuration();
        FileSystem fs = FileSystem.get(URI.create(url), conf);
        InputStream in = null;
        try {
            in = fs.open(new Path(url));
            IOUtils.copyBytes(in, System.out, 4096,false);
        } catch (Exception e) {
            IOUtils.closeStream(in);
        }

    }

}

3.写入数据
FileSystem中包含了一些列创建新文件的方法,最简单的方法是在指定一个Path对象,然后返回一个用于写入数据的工作流:

import java.net.URI;

import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.FSDataOutputStream;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.io.IOUtils;

public class FileSystemCreate {

    public static void main(String[] args) throws Exception{
        String url = args[0];
        String content = args[1];

        Configuration conf = new Configuration();
        FileSystem fs = FileSystem.get(URI.create(url), conf);
        FSDataOutputStream outputStream = fs.create(new Path(url));
        try {
            outputStream.writeBytes(content);
            outputStream.flush();
        } catch (Exception e) {
            IOUtils.closeStream(outputStream);
        }
    }
}

运行:

[grid@tiny01 input]$ hadoop FileSystemCreate file:///home/grid/input/word2.txt aaaaaaaa 
[grid@tiny01 input]$ hadoop FileSystemCat file:///home/grid/input/word2.txt          
aaaaaaaa

4. FileSystem的其他方法
FileSystem还有许多实用的方法,例如:

  • 文件追加内容:append()
  • 创建目录:mkdirs()
  • 查询文件状态:getFileStatus()
  • 检查文件/目录是否存在:exist()
  • 列出目录中的文件状态:listStatus()
  • 删除文件/目录:delete(),第二个参数,是删除有内容的目录的。

等等。

05.参考资料

[1] Hadoop:The Definitive Guide,Third Edition, by Tom White. Copyright 2013 Tom White,978-1-449-31152-0

你可能感兴趣的:(hadoop)