溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Hadoop2.6.0學習筆記(二)HDFS訪問

發布時間:2020-06-28 20:39:02 來源:網絡 閱讀:8209 作者:luchunli1985 欄目:大數據

魯春利的工作筆記,誰說程序員不能有文藝范?



通過hadoop shell與java api訪問hdfs

工作筆記之Hadoop2.6集群搭建已經將集群環境搭建好了,下面來進行一些HDFS的操作

1、HDFS的shell訪問

    HDFS設計主要用來對海量數據進行處理,即HDFS上存儲大量文件。HDFS將這些文件進行分割后存儲在不同的DataNode上。HDFS提供了一個shell接口,屏蔽了block存儲的內部細節,所有的Hadoop操作均由bin/hadoop腳本引發。

    不指定任何參數的hadoop命令將打印所有命令的描述,與hdfs文件相關的操作為hadoop fs(hadoop腳本其他的命令此處不涉及)。

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

Generic options supported are
-conf <configuration file>     specify an application configuration file
-D <property=value>            use value for given property
-fs <local|namenode:port>      specify a namenode
-jt <local|resourcemanager:port>    specify a ResourceManager
-files <comma separated list of files>    specify comma separated files to be copied to the map reduce cluster
-libjars <comma separated list of jars>    specify comma separated jar files to include in the classpath.
-archives <comma separated list of archives>    specify comma separated archives to be unarchived on the compute machines.

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

    hadoop2.6版本中提示hadoop fs為“Deprecated, use hdfs dfs instead.”(2.6之前的版本未接觸過,這里就沒有深究從哪一個版本開始的,但是hadoop fs仍然可以使用)。

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

Generic options supported are
-conf <configuration file>     specify an application configuration file
-D <property=value>            use value for given property
-fs <local|namenode:port>      specify a namenode
-jt <local|resourcemanager:port>    specify a ResourceManager
-files <comma separated list of files>    specify comma separated files to be copied to the map reduce cluster
-libjars <comma separated list of jars>    specify comma separated jar files to include in the classpath.
-archives <comma separated list of archives>    specify comma separated archives to be unarchived on the compute machines.

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

如:

[hadoop@nnode ~]$ hdfs dfs -ls -R /user/hadoop
-rw-r--r--   2 hadoop hadoop       2297 2015-06-29 14:44 /user/hadoop/20130913152700.txt.gz
-rw-r--r--   2 hadoop hadoop        211 2015-06-29 14:45 /user/hadoop/20130913160307.txt.gz
-rw-r--r--   2 hadoop hadoop   93046447 2015-07-18 18:01 /user/hadoop/apache-hive-1.2.0-bin.tar.gz
-rw-r--r--   2 hadoop hadoop    4139112 2015-06-28 22:54 /user/hadoop/httpInterceptor_192.168.1.101_1_20130913160307.txt
-rw-r--r--   2 hadoop hadoop        240 2015-05-30 20:54 /user/hadoop/lucl.gz
-rw-r--r--   2 hadoop hadoop         63 2015-05-27 23:55 /user/hadoop/lucl.txt
-rw-r--r--   2 hadoop hadoop    9994248 2015-06-29 14:12 /user/hadoop/scalog.txt
-rw-r--r--   2 hadoop hadoop    2664495 2015-06-28 20:54 /user/hadoop/scalog.txt.gz
-rw-r--r--   3 hadoop hadoop   28026803 2015-06-24 21:16 /user/hadoop/test.txt.gz
-rw-r--r--   2 hadoop hadoop      28551 2015-05-27 23:54 /user/hadoop/zookeeper.out
[hadoop@nnode ~]$ 
# 這里的點為當前目錄,我是通過hadoop用戶操作的因此類似于/user/hadoop
# hdfs默認具有/user/{hadoop-user},但是在/下也可以自己通過mkdir命令來創建自己的目錄
[hadoop@nnode ~]$ hdfs dfs -ls -R .
-rw-r--r--   2 hadoop hadoop       2297 2015-06-29 14:44 20130913152700.txt.gz
-rw-r--r--   2 hadoop hadoop        211 2015-06-29 14:45 20130913160307.txt.gz
-rw-r--r--   2 hadoop hadoop   93046447 2015-07-18 18:01 apache-hive-1.2.0-bin.tar.gz
-rw-r--r--   2 hadoop hadoop    4139112 2015-06-28 22:54 httpInterceptor_192.168.1.101_1_20130913160307.txt
-rw-r--r--   2 hadoop hadoop        240 2015-05-30 20:54 lucl.gz
-rw-r--r--   2 hadoop hadoop         63 2015-05-27 23:55 lucl.txt
-rw-r--r--   2 hadoop hadoop    9994248 2015-06-29 14:12 scalog.txt
-rw-r--r--   2 hadoop hadoop    2664495 2015-06-28 20:54 scalog.txt.gz
-rw-r--r--   3 hadoop hadoop   28026803 2015-06-24 21:16 test.txt.gz
-rw-r--r--   2 hadoop hadoop      28551 2015-05-27 23:54 zookeeper.out
[hadoop@nnode ~]$

    如果不清楚hdfs命令的詳細操作,可以查看幫助信息:

[hadoop@nnode ~]$ hdfs dfs -help ls
-ls [-d] [-h] [-R] [<path> ...] :
  List the contents that match the specified file pattern. If path is not
  specified, the contents of /user/<currentUser> will be listed. Directory entries are of the form:
        permissions - userId groupId sizeOfDirectory(in bytes)
  modificationDate(yyyy-MM-dd HH:mm) directoryName
  
  and file entries are of the form:
        permissions numberOfReplicas userId groupId sizeOfFile(in bytes)
  modificationDate(yyyy-MM-dd HH:mm) fileName
                   
  -d  Directories are listed as plain files.
   
  -h  Formats the sizes of files in a human-readable fashion rather than a number of bytes.
  
  -R  Recursively list the contents of directories.
  
[hadoop@nnode ~]$

2、HDFS的Java API訪問

    Hadoop中通過DataNode節點存儲數據,而NameNode節點則記錄數據的存儲位置。Hadoop中各部分的通信基于RPC來實現,NameNode也是hadoop中RPC的server端(dfs.namenode.rpc-address說明了rpc端的主機名和端口號),而Hadoop提供的FileSystem類為hadoop中RPC Client的抽象實現。

    a.) 通過java.util.URL來讀取hdfs的數據

    為了讓java程序能夠識別Hadoop的hdfs URL需要通過URL的setURLStreamHandlerFactory(...);

    每個Java虛擬機只能調用依次這個方法,因此通常在靜態方法中調用。

package com.invic.hdfs;

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

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

/**
 * 
 * @author lucl
 * @ 通過java api來訪問hdfs上特定的數據
 *
 */
public class MyHdfsOfJavaApi {
    
    static {
        /**
         * 為了讓java程序能夠識別hadoop的hdfs url需要配置額外的URLStreamHandlerFactory
         * 如下方法java虛擬機只能調用一次,若原有的其他程序已經聲明過該factory,則我的java程序將無法從hadoop中讀取數據
         */
        URL.setURLStreamHandlerFactory(new FsUrlStreamHandlerFactory());
    }

    public static void main(String[] args) throws IOException {
        String path = "hdfs://nnode:8020/user/hadoop/lucl.txt";
        InputStream in = new URL(path).openStream();
        OutputStream ou = System.out;
        int buffer = 4096;
        boolean close = false;
        IOUtils.copyBytes(in, ou, buffer, close);
        
        IOUtils.closeStream(in);
    }
}

    b.) 通過Hadoop的FileSystem來訪問HDFS

    Hadoop有一個抽象的文件系統概念,HDFS只是其中的一個實現。java抽象類org.apache.hadoop.fs.FileSystem定義了Hadoop中的一個文件系統接口。

java.lang.Object
  org.apache.hadoop.conf.Configured
      org.apache.hadoop.fs.FileSystem
          |--org.apache.hadoop.fs.FilterFileSystem
             |----org.apache.hadoop.fs.ChecksumFileSystem
                  |----org.apache.hadoop.fs.LocalFileSystem
            |--org.apache.hadoop.fs.ftp.FTPFileSystem
          |--org.apache.hadoop.fs.s3native.NativeS3FileSystem
          |--org.apache.hadoop.fs.RawLocalFileSystem
          |--org.apache.hadoop.fs.viewfs.ViewFileSystem
package com.invic.hdfs;

import java.io.IOException;
import java.io.OutputStream;
import java.net.URI;
import java.util.Scanner;

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.FileUtil;
import org.apache.hadoop.fs.LocatedFileStatus;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.fs.PathFilter;
import org.apache.hadoop.fs.RemoteIterator;
import org.apache.hadoop.io.IOUtils;
import org.apache.hadoop.util.Progressable;

/**
 * 
 * @author lucl
 * @ 通過FileSystem API來實現    
 *  FileSystem get(Configuration)            通過設置配置文件core-site.xml讀取類路徑來實現,默認本地文件系統            
 *  FileSystem get(URI, Configuration)       通過URI來設定要使用的文件系統
 *  FileSystem get(URI, Configuration, user) 作為給定用戶來訪問文件系統,對安全來說至關重要
 */
public class MyHdfsOfFS {

    private static String HOST = "hdfs://nnode";
    private static String PORT = "8020";
    
    private static String NAMENODE = HOST + ":" + PORT;
    
    public static void main(String[] args) throws IOException {
        Configuration conf = new Configuration();
        
        String path = NAMENODE + "/user/";
        
        /**
         * 由于這里設計的為hadoop的user目錄,默認會查詢hdfs的用戶家目錄下的文件
         */
        String user = "hadoop";
        FileSystem fs = null;
        try {
            fs = FileSystem.get(URI.create(path), conf, user);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        
        if (null == fs) {
            return;
        }
        
        /**
         * 遞歸創建目錄
         */
        boolean mkdirs = fs.mkdirs(new Path("invic/test/mvtech"));
        if (mkdirs) {
            System.out.println("Dir ‘invic/test/mvtech’ create success.");
        }
        
        /**
         * 判斷目錄是否存在
         */
        boolean exists = fs.exists(new Path("invic/test/mvtech"));
        if (exists) {
            System.out.println("Dir ‘invic/test/mvtech’ exists.");
        }
        
        /**
         * FSDataInputStream支持隨意位置訪問
         * 這里的lucl.txt默認查找路徑為/user/Administrator/lucl.txt
             因為我是windows的eclipse
         * 如果我上面的get方法最后指定了user
             則查詢的路徑為/user/get方法指定的user/lucl.txt
         */
        FSDataInputStream in = fs.open(new Path("lucl.txt"));
        
        OutputStream os = System.out;
        
        int buffSize = 4098;
        
        boolean close = false;
        
        IOUtils.copyBytes(in, os, buffSize, close);
        
        System.out.println("\r\n跳到文件開始重新讀取文件。。。。。。");
        in.seek(0);
        IOUtils.copyBytes(in, os, buffSize, close);
        
        IOUtils.closeStream(in);
        
        /**
         * 創建文件
         */
        FSDataOutputStream create = fs.create(new Path("sample.txt"));
        create.write("This is my first sample file.".getBytes());
        create.flush();
        create.close();
        
        /**
         * 文件拷貝
         */
        fs.copyFromLocalFile(new Path("F:\\Mvtech\\ftpfile\\cg-10086.com.csv"), 
        new Path("cg-10086.com.csv"));
        
        /**
         * 文件追加
         */
        FSDataOutputStream append = fs.append(new Path("sample.txt"));
        append.writeChars("\r\n");
        append.writeChars("New day, new World.");
        append.writeChars("\r\n");
        
        IOUtils.closeStream(append);
        
        /**
         * progress的使用
         */
        FSDataOutputStream progress = fs.create(new Path("progress.txt"), 
        new Progressable() {
            
            @Override
            public void progress() {
                System.out.println("write is in progress......");
            }
        });
        
        // 接收鍵盤輸入到hdfs上
        Scanner sc = new Scanner(System.in);
        System.out.print("Please type your enter : ");
        String name = sc.nextLine();
        while (!"quit".equals(name)) {
            if (null == name || "".equals(name.trim())) {
                continue;
            }
            progress.writeChars(name);
            
            System.out.print("Please type your enter : ");
            name = sc.nextLine();
        }
        
        /**
         * 遞歸列出文件
         */
        RemoteIterator<LocatedFileStatus> it = fs.listFiles(new Path(path), true);
        while (it.hasNext()) {
            LocatedFileStatus loc = it.next();
            System.out.println(loc.getPath().getName() + "|" + loc.getLen() + "|" 
            + loc.getOwner()); 
        }
        
        /**
         * 文件或目錄元數據:文件長度、塊大小、復本、修改時間、所有者及權限信息
         */
        FileStatus status = fs.getFileStatus(new Path("lucl.txt"));
        System.out.println(status.getPath().getName() + "|" + 
        status.getPath().getParent().getName() + "|" + status.getBlockSize() + "|" 
        + status.getReplication() + "|" + status.getOwner());
        
        /**
         * 列出目錄中文件listStatus,若參數為文件則以數組方式返回長度為1的FileStatus對象
         */
        fs.listStatus(new Path(path));
        fs.listStatus(new Path(path), new PathFilter() {
            
            @Override
            public boolean accept(Path tmpPath) {
                String tmpName = tmpPath.getName();
                if (tmpName.endsWith(".txt")) {
                    return true;
                }
                return false;
            }
        });
        
        // 可以傳入一組路徑,會最終累計合并成一個數組返回
        // fs.listStatus(Path [] files);
        FileStatus [] mergeStatus = fs.listStatus(new Path[]{new Path("lucl.txt"),
         new Path("progress.txt"), new Path("sample.txt")});
        Path [] listPaths = FileUtil.stat2Paths(mergeStatus);
        for (Path p : listPaths) {
            System.out.println(p);
        }
        
        /**
         * 文件模式匹配
         */
        FileStatus [] patternStatus = fs.globStatus(new Path("*.txt"));
        for (FileStatus stat : patternStatus) {
            System.out.println(stat.getPath());
        }
        
        /**
         * 刪除數據
         */
        boolean recursive = true;
        fs.delete(new Path("demo.txt"), recursive);
        
        fs.close();
    }
}

    c.) 訪問HDFS集群

package com.invic.hdfs;

import java.io.IOException;

import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.LocatedFileStatus;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.fs.RemoteIterator;
import org.apache.log4j.Logger;

/**
 * 
 * @author lucl
 * @ 通過訪問hadoop集群來訪問hdfs
 *
 */
public class MyClusterHdfs {

    public static void main(String[] args) throws IOException {
        System.setProperty("hadoop.home.dir", "E:\\Hadoop\\hadoop-2.6.0\\hadoop-2.6.0\\");
        
        Logger logger = Logger.getLogger(MyClusterHdfs.class);
         
        Configuration conf = new Configuration();
        
        conf.set("fs.defaultFS", "hdfs://cluster");
        conf.set("dfs.nameservices", "cluster");
        conf.set("dfs.ha.namenodes.cluster", "nn1,nn2");
        conf.set("dfs.namenode.rpc-address.cluster.nn1", "nnode:8020");
        conf.set("dfs.namenode.rpc-address.cluster.nn2", "dnode1:8020");
        conf.set("dfs.client.failover.proxy.provider.cluster", 
                "org.apache.hadoop.hdfs.server.namenode.ha.ConfiguredFailoverProxyProvider");
        
        FileSystem fs = FileSystem.get(conf);
        
        
        RemoteIterator<LocatedFileStatus> it = fs.listFiles(new Path("/"), true);
        while (it.hasNext()) {
            LocatedFileStatus loc = it.next();
            logger.info(loc.getPath().getName() + "|" + loc.getLen() + loc.getOwner()); 
        }
        
        /*for (int i = 0; i < 500; i++) {
            String str = "the sequence is " + i;
            logger.info(str);
        }*/
        
        try {
            Thread.sleep(10);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.exit(0);
    }
}

說明:

System.setProperty("hadoop.home.dir", "E:\\Hadoop\\hadoop-2.6.0\\hadoop-2.6.0\\");
# 在main方法的第一行配置hadoop的home路徑,否則在Windows下可能報錯如下:
15/07/19 22:05:54 DEBUG util.Shell: Failed to detect a valid hadoop home directory
java.io.IOException: HADOOP_HOME or hadoop.home.dir are not set.
    at org.apache.hadoop.util.Shell.checkHadoopHome(Shell.java:302)
    at org.apache.hadoop.util.Shell.<clinit>(Shell.java:327)
    at org.apache.hadoop.util.GenericOptionsParser.preProcessForWindows(GenericOptionsParser.java:438)
    at org.apache.hadoop.util.GenericOptionsParser.parseGeneralOptions(GenericOptionsParser.java:484)
    at org.apache.hadoop.util.GenericOptionsParser.<init>(GenericOptionsParser.java:170)
    at org.apache.hadoop.util.GenericOptionsParser.<init>(GenericOptionsParser.java:153)
    at org.apache.hadoop.util.ToolRunner.run(ToolRunner.java:64)
    at org.apache.hadoop.util.ToolRunner.run(ToolRunner.java:84)
    at com.invic.mapreduce.wordcount.WordCounterTool.main(WordCounterTool.java:29)
15/07/19 22:05:54 ERROR util.Shell: Failed to locate the winutils binary in the hadoop binary path
java.io.IOException: Could not locate executable null\bin\winutils.exe in the Hadoop binaries.
    at org.apache.hadoop.util.Shell.getQualifiedBinPath(Shell.java:355)
    at org.apache.hadoop.util.Shell.getWinUtilsPath(Shell.java:370)
    at org.apache.hadoop.util.Shell.<clinit>(Shell.java:363)
    at org.apache.hadoop.util.GenericOptionsParser.preProcessForWindows(GenericOptionsParser.java:438)
    at org.apache.hadoop.util.GenericOptionsParser.parseGeneralOptions(GenericOptionsParser.java:484)
    at org.apache.hadoop.util.GenericOptionsParser.<init>(GenericOptionsParser.java:170)
    at org.apache.hadoop.util.GenericOptionsParser.<init>(GenericOptionsParser.java:153)
    at org.apache.hadoop.util.ToolRunner.run(ToolRunner.java:64)
    at org.apache.hadoop.util.ToolRunner.run(ToolRunner.java:84)
    at com.invic.mapreduce.wordcount.WordCounterTool.main(WordCounterTool.java:29)
向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

亚洲午夜精品一区二区_中文无码日韩欧免_久久香蕉精品视频_欧美主播一区二区三区美女