Hadoop(五)搭建Hadoop客戶端與Java訪問HDFS集羣

前言java

  上一篇詳細介紹了HDFS集羣,還有操做HDFS集羣的一些命令,經常使用的命令:apache

    hdfs dfs -ls xxx
    hdfs dfs -mkdir -p /xxx/xxx
    hdfs dfs -cat xxx
    hdfs dfs -put local cluster
    hdfs dfs -get cluster local
    hdfs dfs -cp /xxx/xxx /xxx/xxx
    hdfs dfs -chmod -R 777 /xxx
    hdfs dfs -chown -R zyh:zyh /xxx

  注意:這裏要說明一下-cp,咱們能夠從本地文件拷貝到集羣,集羣拷貝到本地,集羣拷貝到集羣。編程

1、Hadoop客戶端配置

  其實在前面配置的每個集羣節點均可以作一個Hadoop客戶端。可是咱們通常都不會拿用來作集羣的服務器來作客戶端,須要單獨的配置一個客戶端。windows

1)安裝JDK服務器

2)安裝Hadoopmaven

3)客戶端配置子core-site.xml分佈式

  

4)客戶端配置之mapred-site.xmlide

  

5)客戶端配置之yarn-site.xml工具

  

以上就搭建了一個Hadoop的客戶端oop

2、Java訪問HDFS集羣

2.一、HDFS的Java訪問接口 

  1)org.apache.hadoop.fs.FileSystem
    是一個通用的文件系統API,提供了不一樣文件系統的統一訪問方式。
  2)org.apache.hadoop.fs.Path
    是Hadoop文件系統中統一的文件或目錄描述,相似於java.io.File對本地文件系統的文件或目錄描述。
  3)org.apache.hadoop.conf.Configuration
    讀取、解析配置文件(如core-site.xml/hdfs-default.xml/hdfs-site.xml等),或添加配置的工具類
  4)org.apache.hadoop.fs.FSDataOutputStream
    對Hadoop中數據輸出流的統一封裝
  5)org.apache.hadoop.fs.FSDataInputStream
    對Hadoop中數據輸入流的統一封裝

2.二、Java訪問HDFS主要編程步驟 

    1)構建Configuration對象,讀取並解析相關配置文件
    Configuration conf=new Configuration();
  2)設置相關屬性
    conf.set("fs.defaultFS","hdfs://1IP:9000");
  3)獲取特定文件系統實例fs(以HDFS文件系統實例)
    FileSystem fs=FileSystem.get(new URI("hdfs://IP:9000"),conf,「hdfs");
  4)經過文件系統實例fs進行文件操做(以刪除文件實例)
    fs.delete(new Path("/user/liuhl/someWords.txt"));

2.三、使用FileSystem API讀取數據文件

  有兩個靜態工廠方法來獲取FileSystem實例文件系統。

  

  經常使用的就第二個和第四個

3、實戰Java訪問HDFS集羣

3.一、環境介紹

  1)使用的是IDEA+Maven來進行測試

  2)Maven的pom.xml文件

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.jxlg.zyh.hadoop</groupId>
    <artifactId>Hadoop_0010</artifactId>
    <version>1.0-SNAPSHOT</version>

    <dependencies>
        <dependency>
            <groupId>org.apache.hadoop</groupId>
            <artifactId>hadoop-common</artifactId>
            <version>2.8.1</version>
        </dependency>
        <dependency>
            <groupId>org.apache.hadoop</groupId>
            <artifactId>hadoop-client</artifactId>
            <version>2.8.1</version>
        </dependency>
        <dependency>
            <groupId>org.apache.hadoop</groupId>
            <artifactId>hadoop-hdfs</artifactId>
            <version>2.8.1</version>
        </dependency>
        <dependency>
            <groupId>org.apache.hadoop</groupId>
            <artifactId>hadoop-mapreduce-client-core</artifactId>
            <version>2.8.1</version>
        </dependency>
        <dependency>
            <groupId>org.apache.hadoop</groupId>
            <artifactId>hadoop-auth</artifactId>
            <version>2.8.1</version>
        </dependency>
        <dependency>
            <groupId>log4j</groupId>
            <artifactId>log4j</artifactId>
            <version>1.2.17</version>
        </dependency>
        <dependency>
            <groupId>commons-logging</groupId>
            <artifactId>commons-logging</artifactId>
            <version>1.2</version>
        </dependency>
        <dependency>
            <groupId>com.google.guava</groupId>
            <artifactId>guava</artifactId>
            <version>19.0</version>
        </dependency>
        <dependency>
            <groupId>commons-collections</groupId>
            <artifactId>commons-collections</artifactId>
            <version>3.2.2</version>
        </dependency>
        <dependency>
            <groupId>commons-cli</groupId>
            <artifactId>commons-cli</artifactId>
            <version>1.2</version>
        </dependency>
        <dependency>
            <groupId>commons-lang</groupId>
            <artifactId>commons-lang</artifactId>
            <version>2.6</version>
        </dependency>
        <dependency>
            <groupId>commons-configuration</groupId>
            <artifactId>commons-configuration</artifactId>
            <version>1.9</version>
        </dependency>
        <dependency>
            <groupId>org.apache.avro</groupId>
            <artifactId>avro</artifactId>
            <version>1.7.7</version>
        </dependency>
        <dependency>
            <groupId>commons-io</groupId>
            <artifactId>commons-io</artifactId>
            <version>2.5</version>
        </dependency>
    </dependencies>
    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-assembly-plugin</artifactId>
                <version>3.0.0</version>
                <configuration>
                    <descriptorRefs>
                        <descriptorRef>jar-with-dependencies</descriptorRef>
                    </descriptorRefs>
                </configuration>
                <executions>
                    <execution>
                        <id>make-my-jar-with-dependencies</id>
                        <phase>package</phase>
                        <goals>
                            <goal>single</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.3</version>
                <configuration>
                    <source>1.8</source>
                    <target>1.8</target>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-dependency-plugin</artifactId>
                <version>3.0.0</version>
                <executions>
                    <execution>
                        <phase>package</phase>
                        <goals>
                            <goal>copy-dependencies</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>

</project>
pom.xml

  3)HDFS集羣一個NameNode和兩個DataNode

3.二、查詢HDFS集羣文件系統的一個文件將它文件內容打印出來

package com.jslg.zyh.hadoop.hdfs;

import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.FSDataInputStream;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.net.URI;

public class CatDemo_0010 {
    public static void main(String[] args) throws IOException {
        // 建立Configuration對象
        Configuration conf=new Configuration();
        // 建立FileSystem對象
        FileSystem fs=
                FileSystem.get(URI.create(args[0]),conf);
        // 需求:查看/user/kevin/passwd的內容
        // args[0] hdfs://1.0.0.5:9000/user/zyh/passwd
        // args[0] file:///etc/passwd
        FSDataInputStream is=
                fs.open(new Path(args[0]));
        byte[] buff=new byte[1024];
        int length=0;
        while((length=is.read(buff))!=-1){
            System.out.println(
                    new String(buff,0,length));
        }
        System.out.println(
                fs.getClass().getName());
    }
}

  1)須要在HDFS文件系統中有passwd.txt文件,若是沒有須要本身建立

    hdfs dfs -mkdir -p /user/zyh

    hdfs dfs -put /etc/passwd /user/zyh/passwd.txt

  2)將Maven打好的jar包發送到服務器中,這裏咱們就在NameNode主機中執行,每個節點都是一個客戶端。

    注意:

      這裏要發送第二個包,由於它把相關類也打進jar中

    查看服務器已經收到jar包

  3)執行jar包查看結果

    

  咱們能夠看到查詢出來了passwd.txt中的內容

  注意:在最後咱們還查看了一下FileSystem類,由於咱們知道FileSystem是抽象類,它是根據後面的URI來肯定到底調用的是哪個子類的。

    

3.三、咱們在IEDA中執行來獲取文件系統的內容並打印在控制檯和相應的本地文件中

  1)主要代碼

 public static void main(String[] args) throws IOException {
        //建立configuration對象
        Configuration conf = new Configuration();
        //建立FileSystem對象
        //需求:查看hdfs集羣服務器/user/zyh/passwd.txt的內容
        FileSystem fs = FileSystem.get(URI.create("hdfs://1.0.0.5:9000/user/zyh/passwd.txt"), conf);
        // args[0] hdfs://1.0.0.3:9000/user/zyh/passwd.txt
        // args[0] file:///etc/passwd.txt
        FSDataInputStream is = fs.open(new Path("hdfs://1.0.0.5:9000/user/zyh/passwd.txt"));
        OutputStream os=new FileOutputStream(new File("D:/a.txt"));
        byte[] buff= new byte[1024];
        int length = 0;
        while ((length=is.read(buff))!=-1){
            System.out.println(new String(buff,0,length));
            os.write(buff,0,length);
            os.flush();
        }
        System.out.println(fs.getClass().getName());
        //這個是根據你傳的變量來決定這個對象的實現類是哪一個
    }

  2)Maven從新編譯,並執行

    

  3)結果

    在控制檯中:

      

    在本地文件中:

      

3.四、獲取HDFS集羣文件系統中的文件到本地文件系統

  1)主要代碼

public class GetDemo_0010 {
    public static void main(String[] args) throws IOException {
        Configuration conf=
                new Configuration();
        // 獲取從集羣上讀取文件的文件系統對象
        // 和輸入流對象
        FileSystem inFs=
                FileSystem.get(
                        URI.create(args[0]),conf);
        FSDataInputStream is=
                inFs.open(new Path(args[0]));
        // 獲取本地文件系統對象
        //固然這個你也能夠用FileOutputStream
        LocalFileSystem outFs=
                FileSystem.getLocal(conf);
        FSDataOutputStream os=
                outFs.create(new Path(args[1]));
        byte[] buff=new byte[1024];
        int length=0;
        while((length=is.read(buff))!=-1){
            os.write(buff,0,length);
            os.flush();
        }
        System.out.println(
                inFs.getClass().getName());
        System.out.println(
                is.getClass().getName());
        System.out.println(
                outFs.getClass().getName());
        System.out.println(
                os.getClass().getName());
        os.close();
        is.close();
    }
}

  2)結果

    

    

   咱們能夠看到對於HDFS集羣中獲取的FileSystem對象是分佈式文件系統,而輸入流是HdfsDataInputStream主要用來作數據的傳輸。

  對於本地來講獲取到的FileSystem對象時本地文件系統,而輸出流就是FSDataOutputStream。

 

將HDFS中的文件拿到windows中: 

        //建立configuration對象
        Configuration conf = new Configuration();
// 獲取從集羣上讀取文件的文件系統對象
        // 和輸入流對象
        FileSystem inFs=
            FileSystem.get(
                URI.create("file://1.0.0.5:9000/user/kevin/passwd"),conf);
        FSDataInputStream is=
            inFs.open(new Path("hdfs://1.0.0.5:9000/user/kevin/passwd"));
        // 獲取本地文件系統對象
        LocalFileSystem outFs=
            FileSystem.getLocal(conf);
        FSDataOutputStream os=
            outFs.create(new Path("C:\\passwd"));
        byte[] buff=new byte[1024];
        int length=0;
        while((length=is.read(buff))!=-1){
            os.write(buff,0,length);
            os.flush();
        }
        System.out.println(
            inFs.getClass().getName());
        System.out.println(
            is.getClass().getName());
        System.out.println(
            outFs.getClass().getName());
        System.out.println(
            os.getClass().getName());
        os.close();
        is.close(); 

 3.五、經過設置命令行參數變量來編程

  這裏須要藉助Hadoop中的一個類Configured、一個接口Tool、ToolRunner(主要用來運行Tool的子類也就是run方法)

  分析:

    1)咱們查看API能夠看到ToolRunner中有一個run方法:

      

      裏面須要一個Tool的實現類和使用args用來傳遞參數的String類型的數據

    2)分析Configured

      這是Configurable接口中有一個getConf()方法

        

      而在Configured類中實現了Configurable接口

        

      因此Configured類中實現了Configurable接口的getConf()方法,使用它來得到一個Configuration對象

        

    3)細說Configuration對象

      能夠獲取Hadoop的全部配置文件中的數據

      還能夠經過使用命令行中使用-D(-D是一個標識)使用的變量以及值  

  1)主要代碼  

import java.net.URI;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.conf.Configured;
import org.apache.hadoop.fs.FSDataInputStream;
import org.apache.hadoop.fs.FSDataOutputStream;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.io.IOUtils;
import org.apache.hadoop.util.Tool;
import org.apache.hadoop.util.ToolRunner;

public class GetDemo_0011
    extends Configured
    implements Tool{
    @Override
    public int run(String[] strings) throws Exception{
        //咱們全部的代碼都寫在這個run方法中
        Configuration conf=
            getConf();
        String input=conf.get("input");
        String output=conf.get("output");
        FileSystem inFs=
            FileSystem.get(
                URI.create(input),conf);
        FSDataInputStream is=
            inFs.open(new Path(input));
        FileSystem outFs=
            FileSystem.getLocal(conf);
        FSDataOutputStream os=
            outFs.create(new Path(output));
        IOUtils.copyBytes(is,os,conf,true);
        return 0;
    }

    public static void main(String[] args) throws Exception{
        //ToolRunner中的run方法中須要一個Tool的實現類,和
        System.exit(
            ToolRunner.run(
                new GetDemo_0011(),args));
    }
}

  分析:

    1)介紹IOUtils

      它是Hadoop的一個IO流的工具類,查看API中可知!

      

  2)打包jar發送給服務器執行

    

  3)查看結果

    

3.六、從HDFS集羣中下載文件到本地

  1)普通版

import java.net.URI;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.conf.Configured;
import org.apache.hadoop.fs.FSDataInputStream;
import org.apache.hadoop.fs.FSDataOutputStream;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.LocalFileSystem;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.io.IOUtils;
import org.apache.hadoop.util.Tool;
import org.apache.hadoop.util.ToolRunner;

public class P00032_HdfsDemo_PutFile_0010 extends Configured implements Tool{
    @Override
    public int run(String[] strings) throws Exception{
        Configuration configuration
            =getConf();
        String input=
            configuration.get("input");
        String output=
            configuration.get("output");
        LocalFileSystem inFs=
            FileSystem.getLocal(
                configuration);
        FileSystem outFs=
            FileSystem.get(
                URI.create(output),
                configuration);
        FSDataInputStream is=
            inFs.open(new Path(input));
        FSDataOutputStream os=
            outFs.create(new Path(output));
        IOUtils.copyBytes(is,os,1024,true);
        System.out.println(os.getClass().getName());
        inFs.close();
        outFs.close();
        return 0;
    }

    public static void main(String[] args) throws Exception{
        System.exit(ToolRunner.run(new P00032_HdfsDemo_PutFile_0010(),args));
    }
}
P00032_HdfsDemo_PutFile_0010

  2)能夠觀察到寫入了多少

import java.io.IOException;
import java.net.URI;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.conf.Configured;
import org.apache.hadoop.fs.FSDataInputStream;
import org.apache.hadoop.fs.FSDataOutputStream;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.LocalFileSystem;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.io.IOUtils;
import org.apache.hadoop.util.Tool;
import org.apache.hadoop.util.ToolRunner;

public class P00031_HdfsDemo_PutFile_0010 extends Configured implements Tool{
    FSDataOutputStream os=null;
    @Override
    public int run(String[] strings) throws Exception{
        Configuration configuration=getConf();
        String input=configuration.get("input");
        String output=configuration.get("output");
        LocalFileSystem inFs=FileSystem.getLocal(configuration);
        FileSystem outFs=FileSystem.get(URI.create(output),configuration);
        FSDataInputStream is=inFs.open(new Path(input));
        os=outFs.create(new Path(output),()->{
            try{
                System.out.println("已經寫入了"+os.getPos()+"bytes");
            }catch(IOException e){
                e.printStackTrace();
            }
        });
        IOUtils.copyBytes(is,os,1024,true);
        System.out.println(os.getClass().getName());
        inFs.close();
        outFs.close();
        return 0;
    }

    public static void main(String[] args) throws Exception{
        System.exit(ToolRunner.run(new P00031_HdfsDemo_PutFile_0010(),args));
    }
}
P00031_HdfsDemo_PutFile_001

   

 喜歡就「推薦」哦!   

相關文章
相關標籤/搜索