DOIT20-HDP02

1 HDFS的shell客戶端

[root@linux01 ~]# 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] [-d] [-t <thread count>] <localsrc> ... <dst>]
        [-copyToLocal [-f] [-p] [-ignoreCrc] [-crc] <src> ... <localdst>]
        [-count [-q] [-h] [-v] [-t [<storage type>]] [-u] [-x] [-e] <path> ...]
        [-cp [-f] [-p | -p[topax]] [-d] <src> ... <dst>]
        [-createSnapshot <snapshotDir> [<snapshotName>]]
        [-deleteSnapshot <snapshotDir> <snapshotName>]
        [-df [-h] [<path> ...]]
        [-du [-s] [-h] [-v] [-x] <path> ...]

        [-expunge]
        [-find <path> ... <expression> ...]
        [-get [-f] [-p] [-ignoreCrc] [-crc] <src> ... <localdst>]
        [-getfacl [-R] <path>]
        [-getfattr [-R] {-n name | -d} [-e en] <path>]
        [-getmerge [-nl] [-skip-empty-file] <src> <localdst>]
        [-head <file>]
        [-help [cmd ...]]
        [-ls [-C] [-d] [-h] [-q] [-R] [-t] [-S] [-r] [-u] [-e] [<path> ...]]
        [-mkdir [-p] <path> ...]
        [-moveFromLocal <localsrc> ... <dst>]
        [-moveToLocal <src> <localdst>]
        [-mv <src> ... <dst>]
        [-put [-f] [-p] [-l] [-d] <localsrc> ... <dst>]
        [-renameSnapshot <snapshotDir> <oldName> <newName>]
        [-rm [-f] [-r|-R] [-skipTrash] [-safely] <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> ...]
        [-truncate [-w] <length> <path> ...]
        [-usage [cmd ...]]







































hdfs  dfs  -ls   /
hdfs  dfs  -put  /a.sh    /data/
hdfs  dfs  -get  /data/a.sh   /doit20/
hdfs  dfs  -cat  /a.sh
hdfs  dfs  -tail /a.sh
hdfs  dfs  -head /a.sh
hdfs  dfs  -chmod  -R  777   /data
hdfs  dfs  -mv   
hdfs  dfs  -cp
hdfs  dfs  -mkdir  -p 
hdfs  dfs  -rm  -r 
hdfs  dfs  -rmdir 
hdfs  dfs  -df -h
hdfs  dfs  -du  -h
hdfs  dfs  -find  /data/  -name  a.sh

2 HDFS的java客戶端

1 maven項目

 <properties>
        <maven.compiler.source>1.8</maven.compiler.source>
        <maven.compiler.target>1.8</maven.compiler.target>
    </properties>
 <!--項目需要的jar包   mysql   fastjson...-->
    <dependencies>
        <!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java -->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.47</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/com.alibaba/fastjson -->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
            <version>1.2.62</version>
        </dependency>
        <!--添加hdfs的客戶端依賴-->
        <dependency>
            <groupId>org.apache.hadoop</groupId>
            <artifactId>hadoop-common</artifactId>
            <version>3.1.1</version>
        </dependency>
        <dependency>
            <groupId>org.apache.hadoop</groupId>
            <artifactId>hadoop-hdfs</artifactId>
            <version>3.1.1</version>
        </dependency>
        <dependency>
            <groupId>org.apache.hadoop</groupId>
            <artifactId>hadoop-mapreduce-client-core</artifactId>
            <version>3.1.1</version>
        </dependency>

        <dependency>
            <groupId>org.apache.hadoop</groupId>
            <artifactId>hadoop-mapreduce-client-common</artifactId>
            <version>3.1.1</version>
        </dependency>

        <dependency>
            <groupId>org.apache.hadoop</groupId>
            <artifactId>hadoop-mapreduce-client-jobclient</artifactId>
            <version>3.1.1</version>
        </dependency>

    </dependencies>

</project>

2 編程

2.1 入門程序

package cn._51doit.day02.hdfs.client;

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

import java.net.URI;
import java.net.URISyntaxException;

/**
 * FileName: Demo1
 * Author:   多易教育-DOIT
 * Date:     2020/12/16 0016
 * Description:使用java操作HDFS分佈式文件系統
 */
public class Demo1 {
    public static void main(String[] args) throws Exception {
        // 1 配置信息對象    用於用戶自定義設置 比如副本個數   物理切塊
        Configuration conf = new Configuration();
        // 2 獲取HDFS 的客戶端對象
        /**
         * newInstance獲取文件系統
         * 參數一  URI   namenode的位置  HDFS的位置
         * URL http://linux01:8080/html/login.html
         * jdbc:mysql://localhost:3306/db_dmeo1
         * hdfs://linux01:8020
         * 參數二 配置對象
         * 參數三  用戶名
         */
        FileSystem fs = FileSystem.newInstance(new URI("hdfs://linux01:8020"), conf, "root");
         // 操作HDFS 系統  ls put get mv   rm   cat
        // 將windows中的文件上傳到HDFS 中
        /**
         * 參數一 本地路徑
         * 參數二  HDFS 的路徑
         */
        fs.copyFromLocalFile(new Path("d://word.txt"),new Path("/"));

        fs.close();

    }
}

2.2 上傳下載

    /**
     * 獲取HDFS客戶端
     * hdfs://linux01:8020
     * @return
     * @throws Exception
     */
    public  static FileSystem getHdfsFs() throws Exception {
        Configuration conf = new Configuration();
        return  FileSystem.newInstance(new URI("hdfs://linux01:8020"),conf , "root");

    }
 /**
     * 下載
     * @throws Exception
     */
    private static void get() throws Exception {
        FileSystem fs = HdfsUtils.getHdfsFs();
        /**
         * 注意:************ 下載API需要windows本地配置HDP環境變量  且生效
         * 參數一  是否刪除待下載的文件
         * 參數二  HDFS的路徑
         * 參數三 本地 路徑
         * 參數四  是否使用本地原生的文件系統 ***  默認是false
         *     是否使用原生的本地文件系統  true使用windows的文件系統來存儲存儲下載的數據  所以在本地沒有生成.word.txt.crc文件
         *     默認使用HDFS系統 ---> windows寫數據 生成校驗文件 .a.sh.crc
         */
        fs.copyToLocalFile(true , new Path("/a.sh") ,new Path("d://"),false);
        fs.close();
    }

    /**
     * 上傳
     * @throws Exception
     */
    private static void put() throws Exception {
        //1 上傳
        FileSystem fs = HdfsUtils.getHdfsFs();
        /**
         * 參數一  是否刪除待上傳的文件
         * 參數二  是否覆蓋HDFS中已經存在的文件
         * 參數三  待上傳文件路徑
         * 參數四  HDFS的目標路徑
         */
        fs.copyFromLocalFile(true, true, new Path("d://word.txt"), new Path("/"));
        fs.close();
    }

2.3 創建文件夾

 /**
     * 創建文件夾
     *
     * @throws Exception
     */
    private static void mkdirs() throws Exception {
        FileSystem fs = HdfsUtils.getHdfsFs();
        //創建多級文件夾
        boolean b = fs.mkdirs(new Path("/wbb/wb/b"));
        // 如果創建成功返回true
        if (b) {// 成功
            // 遍歷/下所有的內容[FileStatus 包括文件和文件夾]
            FileStatus[] statuses = fs.listStatus(new Path("/"));
            for (FileStatus status : statuses) {
                // 獲取文件文件夾 路徑
                Path path = status.getPath();
                // 獲取名稱
                String name = path.getName();
                System.out.println(name);
            }
        }
        fs.close();
    }

2.4 刪除內容

  /**
     * 刪除內容
     *
     * @throws Exception
     */
    private static void rmr() throws Exception {
        FileSystem fs = HdfsUtils.getHdfsFs();
        boolean b = fs.delete(new Path("/wbb"), true);
        if (b) {
            System.out.println("刪除成功");
        } else {
            System.out.println("刪除失敗");
        }
        fs.close();
    }

2.5 遍歷路徑下所有的文件

  /**
     * 遍歷路徑下所有的文件
     *
     * @throws Exception
     */
    private static void listFiles() throws Exception {
        FileSystem fs = HdfsUtils.getHdfsFs();
        // 遞歸遍歷一個路徑下所有的文件
        RemoteIterator<LocatedFileStatus> locatedFileStatusRemoteIterator = fs.listFiles(new Path("/"), true);
        // 遍歷文件
        while (locatedFileStatusRemoteIterator.hasNext()) {
            // 獲取每個文件
            LocatedFileStatus next = locatedFileStatusRemoteIterator.next();
            // 獲取每個文件的路徑
            Path path = next.getPath();
            System.out.println(path);
            String name = path.getName();  // 獲取每個文件的文件名
        }
        fs.close();
    }
hdfs://linux01:8020/a/b/c/zk.sh
hdfs://linux01:8020/a/b/zk.sh
hdfs://linux01:8020/wbb.mp4

2.6 API01

    /**
     * 讀取數據
     * @throws Exception
     */
    private static void readData() throws Exception {
        FileSystem fs = HdfsUtils.getHdfsFs();
        // 8 讀取數據
        FSDataInputStream  ipt = fs.open(new Path("/ab.mp4"));
        //wbbhefengjiede qimei aiqing gushi
      /*  int i = ipt.read();
        int j = ipt.read();
        System.out.println(j);*/
        BufferedReader br = new BufferedReader(new InputStreamReader(ipt));
        String  line = null ;
        while((line = br.readLine())!=null){
            System.out.println(line);
        }
        ipt.close();
        br.close();
        fs.close();
    }

    /**
     * 移動 重命名
     * @param fs
     * @throws IOException
     */
    private static void mv(FileSystem fs) throws IOException {
        fs.rename(new Path("/a.mp4") , new Path("/ab.mp4")) ;
    }

    /**
     * 獲取元數據信息
     * @throws Exception
     */
    private static void getFileBlockMeta() throws Exception {
        FileSystem fs = HdfsUtils.getHdfsFs();
        // 遞歸遍歷一個路徑下所有的文件
        RemoteIterator<LocatedFileStatus> locatedFileStatusRemoteIterator = fs.listFiles(new Path("/"), false);
        // 遍歷文件
        while (locatedFileStatusRemoteIterator.hasNext()) {
            // 獲取每個文件
            LocatedFileStatus next = locatedFileStatusRemoteIterator.next();
            // 獲取每個文件的路徑
            Path path = next.getPath();
            System.out.println(path);
            String name = path.getName();  // 獲取每個文件的文件名
            next.getBlockSize() ;//128M
            next.getReplication() ;//3
            //  獲取元數據信息..
            BlockLocation[] blockLocations = next.getBlockLocations();// 塊位置   a.txt  300M
            for (BlockLocation blockLocation : blockLocations) {//塊   3個副本
                long length = blockLocation.getLength(); // 數據塊的大小
                String[] names = blockLocation.getNames();
                System.out.println(Arrays.asList(names));// names
                // 獲取乜咯副本所在的機器
                String[] hosts = blockLocation.getHosts(); // 3
                List<String> strings = Arrays.asList(hosts); // hosts
                System.out.println(strings);
            }
        }
        fs.close();
    }

    /**
     * 遍歷路徑下所有的內容
     * @throws Exception
     */
    private static void listStatus() throws Exception {
        FileSystem fs = HdfsUtils.getHdfsFs();
        FileStatus[] fileStatuses = fs.listStatus(new Path("/"));
        for (FileStatus fileStatus : fileStatuses) {
            fileStatus.isDirectory();
            if(fileStatus.isFile()){  // 文件
              //  獲取文件信息
                fileStatus.getAccessTime() ;
                fileStatus.getBlockSize();
                fileStatus.getLen() ;
                fileStatus.getReplication() ;
            }
        }
        fs.close();
    }

2,7 追加寫

 /**
     * 追加寫操作
     * @throws Exception
     */
    private static void writeData() throws Exception {
        FileSystem fs = HdfsUtils.getHdfsFs();
        FSDataOutputStream append = fs.append(new Path("/ab.mp4"));
        BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(append));
        bw.write("wbb 真笨");
        bw.newLine();
        bw.flush();
        bw.close();
        fs.close();
    }

3 原理加強

3.1 數據存儲位置觀察

當datanode啓動以後會向namenode註冊 ,dfs.namenode.rpc-address ! namenode接收註冊 返回一個唯一的集羣ID!

返回一個blockpoolId, datanode將數據存儲在這個統一的目錄中!

-- 數據在集羣中是以128M物理切塊多副本存儲 (集羣),數據塊回存儲在

每臺datanode的這個BP-859207207-192.168.133.3-1608020883489目錄下

在linux01機器  linux02 linux03的目錄下有數據塊

3.2 寫數據流程(上傳)

....作業

 

 

3.3 讀數據流程 (下載)

 

3.4 namenode和datanode通信

1、namenode 如何判斷datanode節點是否宕機?
先決條件:
datanode每隔一段時間像namenode彙報,彙報的信息有兩點
(1)自身datanode的狀態信息;
(2)自身datanode所持有的所有的數據塊的信息。
如果namenode連續十次沒有收到datanode的彙報,那麼namenode就會認爲該datanode存在宕機的可能。
datanode啓動以後會專門啓動一個進程負責給namenode發送心跳數據包,如果datanode沒有問題,僅僅只是發送信息數據包的進程掛了,namenode會發送命令像這個datanode進行確認,
查看這個發送心跳包的進程是否還能正常運行,namenode會向datanode確認兩遍,每五分鐘確認一次。如果兩次都沒有返回結果,那麼namenode就會認爲datanode已經宕機了。
最終namenode判斷一個datanode死亡的時間計算公式:
timeout = 10 * 心跳間隔時間 + 2 * 檢查一次消耗的時間
心跳間隔時間
配置參數:dfs.heartbeat.interval
默認值:3s,單位s
檢查一次消耗的時間
配置參數:dfs.namenode.heartbeat.recheck-interval
默認值:    300000,單位ms

2、數據塊讀寫操作的一些配置項
(1)配置參數:dfs.blocksize 
參數說明:客戶端數據分塊的大小
默認值:134217728(128M);單位:字節
(2)dfs.client-write-packet-size
參數說明:客戶端寫入數據時packet數據包的大小
默認值:65536(64K),單位字節
(3)dfs.bytes-per-checksum
參數說明:chunk(寫入數據時最小的一個單位),數據校驗的粒度
默認值:512字節
注:事實上一個chunk還包含4B的校驗值,因而chunk寫入packet時是516B;數據與檢驗值的比值爲128:1,所以對於一個128M的block會有一個1M的校驗文件與之對應;

3、集羣數據損壞以後,自動刪除時長
配置項:dfs.blockreport.intervalMsec
默認值:21600000(36分鐘),單位:ms

4、元數據checkPount
在分佈式或者僞分佈集羣中,每隔一段時間,會由 secondary namenode 將 namenode 上積累的所有 edits 和一個最新的 fsimage 下載到本地,並加載到內存進行 merge(這個過程稱爲 checkpoint)
dfs.namenode.checkpoint.check.period=60 ##檢查觸發條件是否滿足的頻率,60 秒
dfs.namenode.checkpoint.dir=file://${hadoop.tmp.dir}/dfs/namesecondary
##以上兩個參數做 checkpoint 操作時,secondary namenode 的本地工作目錄
dfs.namenode.checkpoint.edits.dir=${dfs.namenode.checkpoint.dir}
dfs.namenode.checkpoint.max-retries=3 ##最大重試次數
dfs.namenode.checkpoint.period=3600 ##兩次 checkpoint 之間的時間間隔 3600 秒
dfs.namenode.checkpoint.txns=1000000 ##兩次 checkpoint 之間最大的操作記錄

5、jvm重用
配置參數:mapred.job.reuse.jvm.num.tasks
參數解釋:一個jvm內部跑多少個task,默認是1,可以設置爲多個。這個參數在2.9.2版本中未找到。

 

3.5  namenode和datanode角色總結 

3.6 元數據管理機制

 

 

 

 

 

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章