Hadoop的實現原理及基本使用方法

    網上有很多介紹Hadoop安裝部署的資料,這篇文章不會向大家介紹Hadoop的安裝及部署方法,我會重點向大家介紹Hadoop實現的基本原理,這樣當我們今後學習Hadoop生態相關的知識時可以快速入門。

        

Hadoop是什麼

    我們首先要知道Hadoop是什麼,按照官方的解釋,Hadoop是一個由Apache基金會開發的分佈式系統基礎架構,可提供高可用、高擴展、高效、低成本的服務

Hadoop提供的服務包括HDFS、MapReduce和YARN;其中HDFS用於海量數據的存儲,MapReduce用於海量數據的分析和計算,YARN怎用於資源的管理和調度,

Hadoop的高可用、高擴展及低成本的特性就是通過以上三種服務實現的。Hadoop適用於處理海量數據,如果數據量不大則不建議使用Hadoop。

    Hadoop的生態圈包括以下常用的軟件,其中HDFS、YARN、MapReduce是Hadoop提供的核心服務;其它的則是依賴Hadoop構建的應用。

image.png

HDFS介紹

    HDFS即Hadoop分佈式文件系統(Hadoop Distribute File System),用於存儲海量數據,HDFS維護了一套虛擬的文件系統用戶管理保存的數據;HDFS使用普通的PC機即可,這也是使用Hadoop處理大數據成本相對較低的原因。文件保存在Hadoop上時,Hadoop會根據配置將文件保存多個副本,這樣當有一臺機器宕機時,獲取文件不受任何影響,實現了高可用。

    HDFS主要提供了NameNode和DataNode兩個服務,其中Name用於接收客戶端的請求、保存元數據;DateNode是真正保存數據的地方。當我們HDFS啓動成功後使用JPS命令可以看到實際上就是啓動了NameNode服務和DataNode服務,如下圖所示:

image.png          image.png

    NameNode中的元數據信息包括:HDFS文件的虛擬目錄、文件副本數量、文件塊名稱、文件塊所屬機器,如元數據:/test/a.log, 2 ,{blk_1,blk_2}, [{blk_1:[10.2.200.1]},{blk_2:[10.2.200.2]}]表示,在Hadoop中的/test目錄下存在a.log文件,且這個文件被切分成2塊blk_1和blk_2,沒有副本,blk_1在10.2.200.1機器上,blk_2在10.2.200.2,元文件保存在NameNode所在的機器上,文件名爲fsimage_*,如下圖所示:

image.png

    DataNode是真正保存文件數據的地方,DataNode接收客戶端的請求,並完成文件的讀或寫,HDFS會將大文件切分保存,默認情況下塊的大小爲128M。

    HDFS處理客戶端請求的大致流程如下圖所示:

image.png

    向Hadoop上傳文件的過程爲(write):1、客戶端向NameNode請求上傳文件,NameNode維護虛擬目錄信息,根據文件大小計算出需要切分成多少塊,並分配DataNode節點,2、NameNode將分塊信息、分配的DataNode節點信息返回給客戶端,3、客戶端根據獲取的DataNode節點信息和DataNode節點通信,將文件上傳至DataNode節點。DataNode節點保存文件的實際位置通過dfs.namenode.name.dir配置。

    從Hadoop下載文件的過程爲(read):1、客戶端向NameNode請求下載文件,2、NameNode根據提供的虛擬目錄返回元數據信息,3、客戶端根據返回的元數據信息到具體的DateNode上下載文件。


HDFS實現原理

    HDFS的服務是通過RPC調用的方式實現服務端和客戶端的通信,具體來說就是DataNode和NameNode均開啓了socket服務,客戶端和服務端實現了相同的接口,客戶端根據接口定義的方法,通過Java的動態代理調用相關的方法。(如果瞭解Dubbo,就能瞭解的比較具體,調用方式和Dubbo類似)。

    HDFS的RPC框架使用方式如下:

// 服務端開啓服務
Builder builder = new RPC.Builder(new Configuration());

// 設置服務的地址、端口、協議、及服務的實現實例
builder.setBindAddress("hadoop").setPort(18080).setProtocol(ILogin.class).setInstance(new LoginImpl());

// 啓動服務
Server server =builder.build();
server.start();


// 客戶端調用方式
ILogin login = RPC.getProxy(ILogin.class,1L,new InetSocketAddress("192.168.1.1",18080), new Configuration());
String returnMsg = login.login("tom");

HDFS相關API和shell

    HDFS提供了Java相關的API,以便通過程序調用的方式操作HDFS,通過HDFS的API我們可以對HDFS上的文件實現上傳、下載、刪除、修改、壓縮等操作。

// 下載文件
FSDataInputStream inputStream = fs.open(new Path("/test.txt"));
FileOutputStream fio = new FileOutputStream("/home/hadoop/hdfs.txt");
IOUtils.copy(inputStream, fio);

// 上傳文件
FSDataOutputStream os = fs.create(new Path("/test.txt"));
FileInputStream is = new FileInputStream("/home/hadoop/hdfs.txt");
IOUtils.copy(is, os);

// 刪除文件
fs.delete(new Path("/testHadoop"), true);

HDFS中經常使用的Shell包括

hadoop fs -ls /hadoop   查看HDFS目錄列表

hadoop fs -mkdir /test  創建目錄test

hadoop fs -put ./test.txt /test 或 hadoop fs -copyFromLocal ./test.txt /test 上傳文件至HDFS

hadoop fs -get /test/test.txt 或 hadoop fs -getToLocal /test/test.txt  從HDFS上下載文件

hadoop fs -cp /test/test.txt /test1 拷貝文件

hadoop fs -rm /test1/test.txt 刪除文件

hadoop fs -mv /test/test.txt /test1  修改文件名


MapReduce介紹

    Hadoop中HDFS用於存儲數據,MapReduce用於處理數據,MapReduce程序的運行依賴於YARN分配資源;MapReduce程序主要有兩個階段構成:Map和Reduce,客戶端只要分別實現map()函數和reduce()函數,即可實現分佈式計算。

    map任務的處理過程爲:讀取文件中每一行的內容,根據具體的業務邏輯處理行數據,並將處理結果生成鍵值對輸出

    reduce任務的處理過程爲:在做reduce操作之前,會有一個shuffle的操作,該操作主要是對map的處理結果進行合併、排序,然後對map輸出的鍵值對進行處理,得到處理結果後,同樣以鍵值對的形式保存到文件。

    MapReduce的任務提交流程大致如下圖所示:

image.png


MapReduce Java API

    MapReduce提供了Java相關的API,我們可以根據提供的API實現MapReduce程序,這樣我們就可以根據實際的業務需求完成對大數據的處理,API示例如下:

// map函數處理過程
@Override
protected void map(LongWritable key, Text value, Context context) throws IOException, InterruptedException {
    // 將該行內容轉換爲字符串
    String strValue = value.toString();
    String[] words = StringUtils.split(strValue, ' ');

    // 遍歷數組,並將數據輸出(key-value形式)
    for(String word : words) {
        context.write(new Text(word), new LongWritable(1));
    }
}

// reduce函數處理過程
@Override
protected void reduce(Text key, Iterable<LongWritable> values, Context context) throws IOException, InterruptedException {
    int count = 0;

    for(LongWritable value : values) {
        count += value.get();
    }

    context.write(key, new LongWritable(count));
}

// 調用Map和Reduce
// job使用的mapper和reducer
job.setMapperClass(WordCountMapper.class);
job.setReducerClass(WordCountReduce.class);

// 設置reducer的輸入輸出類型
job.setOutputKeyClass(Text.class);
job.setOutputValueClass(LongWritable.class);

// 設置mapper的輸入輸出類型
job.setMapOutputKeyClass(Text.class);
job.setMapOutputValueClass(LongWritable.class);

// 設置map處理數據所在的路徑
FileInputFormat.setInputPaths(job, new Path("/upload/"));

// 設置reducer處理數據的輸出路徑(注:wordcount文件夾不能創建,程序會自動創建,如果自己創建會報錯)
FileOutputFormat.setOutputPath(job, new Path("/wordcount/"));

job.waitForCompletion(true);

Hive簡介

    通過上面的介紹我們知道對大數據的處理和運算需要通過編寫MapReduce程序來實現,這就對大數據處理人員提出了編碼要求,爲了簡化大數據處理的實現,Hive出現了,Hive的本質就是實現了對MapReduce的封裝,Hive通過解析SQL語句,將SQL語句中的相關內容作爲MapReduce程序的入參,調用預先實現好的MapReduce任務,從而完成大數據的處理任務。通過編寫SQL進而實現數據處理,避免了開發人員親自編碼實現MapReduce,從而大大降低了數據處理的難度,提高了開發效率。

    Hive建庫就是在HDFS上創建文件夾,建表就是在庫對應的文件夾下創建子文件夾,表名即文件夾名,分區表就是在表下創建子文件夾,分桶表就是將一個大文件按照一定的規則劃分爲幾個小文件,執行Hive SQL的過程就是處理相關表對應的文件夾下文件的過程。

    額外說明下,Hive處理數據實際上就是執行MapReduce的過程,而執行MapReduce會有大量讀寫磁盤的操作,因此Hive處理大數據的過程會比較慢;Spark的出現解決了這個問題,Spark處理數據的原理和MapReduce總體相似,但是Spark處理數據和磁盤交互比較少,大部分都是在內存中計算數據,所以Spark處理數據的效率要比MapReduce高的多。

HBase簡介

    HBase可以理解爲構建在HDFS上的NoSql數據庫,Hbase通過key、value的方式保存海量數據,Hbase的數據文件保存在HDFS上,Hbase的Tabel在行的方向上分割爲多個HRegion,每個Region由[startKey,EndKey]表示,Region分佈在RegionServer,示意圖如下:

image.png

文章中相關API完整的源碼信息可關注微信公衆號 布衣暖 回覆hadoop獲取

buyinuan.jpg


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