Hadoop組件介紹

Distributed File System

1.數據量越來越多,在一個操作系統管轄的範圍存不下了,那麼就分配到更多的操作系統管理的磁盤中,但是不方便管理和維護,因此迫切需要一種系統來管理多臺機器上的文件,這就是分佈式文件管理系統 。

2.是一種允許文件通過網絡在多臺主機上分享的文件系統,可讓多機器上的多用戶分享文件和存儲空間。

3.通透性。讓實際上是通過網絡來訪問文件的動作,由程序與用戶看來,就像是訪問本地的磁盤一般。

4.容錯。即使系統中有某些節點脫機,整體來說系統仍然可以持續運作而不會有數據損失。

5.分佈式文件管理系統很多,hdfs只是其中一種。適用於一次寫入多次查詢的情況,不支持併發寫情況,小文件不合適。

HDFS的Shell

1.調用文件系統(FS)Shell命令應使用 bin/hadoop fs 的形式。

2.所有的FS shell命令使用URI路徑作爲參數。
 URI格式是scheme://authority/path。HDFS的scheme是hdfs,對本地文件系統,scheme是file。其中scheme和authority參數都是可選的,如果未加指定,就會使用配置中指定的默認scheme。

例如:/parent/child可以表示成hdfs://namenode:namenodePort/parent/child,或者更簡單的/parent/child(假設配置文件是namenode:namenodePort)

3.大多數FS Shell命令的行爲和對應的Unix Shell命令類似。
HDFS fs命令

-help [cmd]  //顯示命令的幫助信息
-ls(r) <path>  //顯示當前目錄下所有文件
-du(s) <path>  //顯示目錄中所有文件大小
-count[-q] <path>  //顯示目錄中文件數量
-mv <src> <dst>  //移動多個文件到目標目錄
-cp <src> <dst>  //複製多個文件到目標目錄
-rm(r)  //刪除文件(夾)
-put <localsrc> <dst>  //本地文件複製到hdfs
-copyFromLocal  //同put
-moveFromLocal  //從本地文件移動到hdfs
-get [-ignoreCrc] <src> <localdst>  //複製文件到本地,可以忽略crc校驗
-getmerge <src> <localdst>  //將源目錄中的所有文件排序合併到一個文件中
-cat <src>  //在終端顯示文件內容
-text <src>  //在終端顯示文件內容
-copyToLocal [-ignoreCrc] <src> <localdst>  //複製到本地
-moveToLocal <src> <localdst>
-mkdir <path>  //創建文件夾
-touchz <path>  //創建一個空文件
HDFS的Shell命令練習
#hadoop fs -ls /  查看HDFS根目錄
#hadoop fs -mkdir /test 在根目錄創建一個目錄test
#hadoop fs -mkdir /test1 在根目錄創建一個目錄test1
#hadoop fs -put ./test.txt /test 
或#hadoop fs -copyFromLocal ./test.txt /test
#hadoop fs -get /test/test.txt .
或#hadoop fs -getToLocal /test/test.txt .
#hadoop fs -cp /test/test.txt /test1
#hadoop fs -rm /test1/test.txt
#hadoop fs -mv /test/test.txt /test1
#hadoop fs -rmr /test1   

HDFS架構

NameNode
DataNode
Secondary NameNode
HDFS Architecture
在這裏插入圖片描述

元數據存儲細節

在這裏插入圖片描述

NameNode

1.是整個文件系統的管理節點。它維護着整個文件系統的文件目錄樹,文件/目錄的元信息和每個文件對應的數據塊列表。接收用戶的操作請求。
2.文件包括:
①fsimage:元數據鏡像文件。存儲某一時段NameNode內存元數據信息。(hdfs-site.xml的dfs.name.dir屬性)
②edits:操作日誌文件。
③fstime:保存最近一次checkpoint的時間
3.以上這些文件是保存在linux的文件系統中。

NameNode的工作特點

1.Namenode始終在內存中保存metedata,用於處理“讀請求”

2.到有“寫請求”到來時,namenode會首先寫editlog到磁盤,即向edits文件中寫日誌,成功返回後,纔會修改內存,並且向客戶端返回

3.Hadoop會維護一個fsimage文件,也就是namenode中metedata的鏡像,但是fsimage不會隨時與namenode內存中的metedata保持一致,而是每隔一段時間通過合併edits文件來更新內容。Secondary namenode就是用來合併fsimage和edits文件來更新NameNode的metedata的。

SecondaryNameNode

1.HA的一個解決方案。但不支持熱備。配置即可。

2.執行過程:從NameNode上下載元數據信息(fsimage,edits),然後把二者合併,生成新的fsimage,在本地保存,並將其推送到NameNode,替換舊的fsimage.

3.默認在安裝在NameNode節點上,但這樣…不安全!

secondary namenode的工作流程

1.secondary通知namenode切換edits文件
2.secondary從namenode獲得fsimage和edits(通過http)
3.secondary將fsimage載入內存,然後開始合併edits
4.secondary將新的fsimage發回給namenode
5.namenode用新的fsimage替換舊的fsimage

什麼時候checkpiont

1.fs.checkpoint.period 指定兩次checkpoint的最大時間間隔,默認3600秒。
2.fs.checkpoint.size 規定edits文件的最大值,一旦超過這個值則強制checkpoint,不管是否到達最大時間間隔。默認大小是64M。
在這裏插入圖片描述

Datanode
1.提供真實文件數據的存儲服務。
2.文件塊(block):最基本的存儲單位。對於文件內容而言,一個文件的長度大小是size,那麼從文件的0偏移開始,按照固定的大小,順序對文件進行劃分並編號,劃分好的每一個塊稱一個Block。HDFS默認Block大小是128MB,以一個256MB文件,共有256/128=2個Block.
dfs.block.size

3.不同於普通文件系統的是,HDFS中,如果一個文件小於一個數據塊的大小,並不佔用整個數據塊存儲空間
4.Replication。多複本。默認是三個。
hdfs-site.xml的dfs.replication屬性

Shell命令練習:驗證塊大小
1.方法:上傳大於128MB的文件,觀察塊大小
2.驗證:使用 http://node:50070 觀察(node爲節點大小)
在這裏插入圖片描述

HDFS的java訪問接口——FileSystem

•寫文件 create
•讀取文件 open
•刪除文件delete
•創建目錄 mkdirs
•刪除文件或目錄 delete
•列出目錄的內容 listStatus
•顯示文件系統的目錄和文件的元數據信息 getFileStatus
HDFS的FileSystem讀取文件

  private static FileSystem getFileSystem() throws URISyntaxException,
            IOException {
        Configuration conf = new Configuration();
        URI uri = new URI("hdfs://hadoop240:9000");
        final FileSystem fileSystem = FileSystem.get(uri , conf);
        return fileSystem;
    }
    /**
     * 讀取文件,調用fileSystem的open(path)
     * @throws Exception
     */
    private static void readFile() throws Exception {
        FileSystem fileSystem = getFileSystem();
        FSDataInputStream openStream = fileSystem.open(new Path("hdfs://itcast0106:9000/aaa"));
        IOUtils.copyBytes(openStream, System.out, 1024, false);
        IOUtils.closeStream(openStream);
    }

HDFS的FileSystem目錄

    /**
     * 創建目錄,調用fileSystem的mkdirs(path)
     * @throws Exception
     */
    private static void mkdir() throws Exception {
        FileSystem fileSystem = getFileSystem();
        fileSystem.mkdirs(new Path("hdfs://itcast0106:9000/bbb"));
    }
    /**
     * 刪除目錄,調用fileSystem的deleteOnExit(path)
     * @throws Exception
     */
    private static void rmdir() throws Exception {
        FileSystem fileSystem = getFileSystem();
        fileSystem.delete(new Path("hdfs://itcast0106:9000/bbb"));
    }

HDFS的FileSystem遍歷目錄

/**
     * 遍歷目錄,使用FileSystem的listStatus(path)
     * 如果要查看file狀態,使用FileStatus對象
     * @throws Exception
     */
    private static void list() throws Exception{
        FileSystem fileSystem = getFileSystem();
        FileStatus[] listStatus = fileSystem.listStatus(new Path("hdfs://itcast0106:9000/"));
        for (FileStatus fileStatus : listStatus) {
            String isDir = fileStatus.isDir()?"目錄":"文件";
            String name = fileStatus.getPath().toString();
            System.out.println(isDir+"  "+name);
        }
    }

FileSystem

用戶代碼操作HDFS時,是直接調用FileSystem的子類完成的。

Remote Procedure Call

1.RPC——遠程過程調用協議,它是一種通過網絡從遠程計算機程序上請求服務,而不需要了解底層網絡技術的協議。RPC協議假定某些傳輸協議的存在,如TCP或UDP,爲通信程序之間攜帶信息數據。在OSI網絡通信模型中,RPC跨越了傳輸層和應用層。RPC使得開發包括網絡分佈式多程序在內的應用程序更加容易。

2.RPC採用客戶機/服務器模式。請求程序就是一個客戶機,而服務提供程序就是一個服務器。首先,客戶機調用進程發送一個有進程參數的調用信息到服務進程,然後等待應答信息。在服務器端,進程保持睡眠狀態直到調用信息的到達爲止。當一個調用信息到達,服務器獲得進程參數,計算結果,發送答覆信息,然後等待下一個調用信息,最後,客戶端調用進程接收答覆信息,獲得進程結果,然後調用執行繼續進行。
3.hadoop的整個體系結構就是構建在RPC之上的(見org.apache.hadoop.ipc)。

RPC示例

public interface Bizable extends  VersionedProtocol{
    public abstract String hello(String name);
}

class Biz implements Bizable{
    @Override
    public String hello(String name){
        System.out.println("被調用了");
        return "hello "+name;
    }

    @Override
    public long getProtocolVersion(String protocol, long clientVersion)
            throws IOException {
        System.out.println("Biz.getProtocalVersion()="+MyServer.VERSION);
        return MyServer.VERSION;
    }
}

public class MyServer {
    public static int PORT = 3242;
    public static long VERSION = 23234l;
    
    public static void main(String[] args) throws IOException {
        final Server server = RPC.getServer(new Biz(), "127.0.0.1", PORT, new Configuration());
        server.start();
    }
}

public class MyClient {
    public static void main(String[] args) throws IOException {
        final InetSocketAddress inetSocketAddress = new InetSocketAddress("127.0.0.1", MyServer.PORT);
        final Bizable proxy = (Bizable) RPC.getProxy(Bizable.class, MyServer.VERSION, inetSocketAddress, new Configuration());
        final String ret = proxy.hello("吳超");
        System.out.println(ret);
        
        RPC.stopProxy(proxy);
    }
}

RPC調用流程

在這裏插入圖片描述
ClientProtocol
l是客戶端(FileSystem)與NameNode通信的接口。
DatanodeProtocol
l是DataNode與NameNode通信的接口
NamenodeProtocol
l是SecondaryNameNode與NameNode通信的接口。

HDFS讀過程

1.初始化FileSystem,然後客戶端(client)用FileSystem的open()函數打開文件
2.FileSystem用RPC調用元數據節點,得到文件的數據塊信息,對於每一個數據塊,元數據節點返回保存數據塊的數據節點的地址。
3.FileSystem返回FSDataInputStream給客戶端,用來讀取數據,客戶端調用stream的read()函數開始讀取數據。
4.DFSInputStream連接保存此文件第一個數據塊的最近的數據節點,data從數據節點讀到客戶端(client)
5.當此數據塊讀取完畢時,DFSInputStream關閉和此數據節點的連接,然後連接此文件下一個數據塊的最近的數據節點。
6.當客戶端讀取完畢數據的時候,調用FSDataInputStream的close函數。
7.在讀取數據的過程中,如果客戶端在與數據節點通信出現錯誤,則嘗試連接包含此數據塊的下一個數據節點。
8.失敗的數據節點將被記錄,以後不再連接。
在這裏插入圖片描述

HDFS寫過程

1.初始化FileSystem,客戶端調用create()來創建文件
2.FileSystem用RPC調用元數據節點,在文件系統的命名空間中創建一個新的文件,元數據節點首先確定文件原來不存在,並且客戶端有創建文件的權限,然後創建新文件。
3.FileSystem返回DFSOutputStream,客戶端用於寫數據,客戶端開始寫入數據。
4.DFSOutputStream將數據分成塊,寫入data queue。data queue由Data Streamer讀取,並通知元數據節點分配數據節點,用來存儲數據塊(每塊默認複製3塊)。分配的數據節點放在一個pipeline裏。Data Streamer將數據塊寫入pipeline中的第一個數據節點。第一個數據節點將數據塊發送給第二個數據節點。第二個數據節點將數據發送給第三個數據節點。
5.DFSOutputStream爲發出去的數據塊保存了ack queue,等待pipeline中的數據節點告知數據已經寫入成功。
6.當客戶端結束寫入數據,則調用stream的close函數。此操作將所有的數據塊寫入pipeline中的數據節點,並等待ack queue返回成功。最後通知元數據節點寫入完畢。
7.如果數據節點在寫入的過程中失敗,關閉pipeline,將ack queue中的數據塊放入data queue的開始,當前的數據塊在已經寫入的數據節點中被元數據節點賦予新的標示,則錯誤節點重啓後能夠察覺其數據塊是過時的,會被刪除。失敗的數據節點從pipeline中移除,另外的數據塊則寫入pipeline中的另外兩個數據節點。元數據節點則被通知此數據塊是複製塊數不足,將來會再創建第三份備份。
在這裏插入圖片描述
練習題
1.練習shell命令
2.在HDFS創建一個文本文件hadoop.test。內容自定;然後,用Java程序在本地終端打印hadoop.test文件內容
3.用Java程序實現copyFromLocal

思考題
1.hdfs的組成部分有哪些,分別解釋一下
2.hdfs的高可靠如何實現
3.hdfs的常用shell命令有哪些
4.hdfs的常用java api有哪些
5.請用shell命令實現目錄、文件的增刪改查
6.請用java api實現目錄、文件的增刪改查

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