1. 程式人生 > >hadoop-hdfs簡介

hadoop-hdfs簡介

repo input rpc 山寨 原理 width core 文件內容 out

原文引自:http://www.cnblogs.com/shishanyuan/p/4637631.html

1、環境說明

部署節點操作系統為CentOS,防火墻和SElinux禁用,創建了一個shiyanlou用戶並在系統根目錄下創建/app目錄,用於存放Hadoop等組件運行包。因為該目錄用於安裝hadoop等組件程序,用戶對shiyanlou必須賦予rwx權限(一般做法是root用戶在根目錄下創建/app目錄,並修改該目錄擁有者為shiyanlou(chown –R shiyanlou:shiyanlou /app)。

Hadoop搭建環境:

l 虛擬機操作系統: CentOS6.6 64位,單核,1G內存

l JDK:1.7.0_55 64位

l Hadoop:1.1.2

2、HDFS原理

HDFS(Hadoop Distributed File System)是一個分布式文件系統,是谷歌的GFS山寨版本。它具有高容錯性並提供了高吞吐量的數據訪問,非常適合大規模數據集上的應用,它提供了一個高度容錯性和高吞吐量的海量數據存儲解決方案。

l高吞吐量訪問:HDFS的每個Block分布在不同的Rack上,在用戶訪問時,HDFS會計算使用最近和訪問量最小的服務器給用戶提供。由於Block在不同的Rack上都有備份,所以不再是單數據訪問,所以速度和效率是非常快的。另外HDFS可以並行從服務器集群中讀寫,增加了文件讀寫的訪問帶寬。

l高容錯性:系統故障是不可避免的,如何做到故障之後的數據恢復和容錯處理是至關重要的。HDFS通過多方面保證數據的可靠性,多份復制並且分布到物理位置的不同服務器上,數據校驗功能、後臺的連續自檢數據一致性功能都為高容錯提供了可能。

l線性擴展:因為HDFS的Block信息存放到NameNode上,文件的Block分布到DataNode上,當擴充的時候僅僅添加DataNode數量,系統可以在不停止服務的情況下做擴充,不需要人工幹預。

2.1HDFS架構

技術分享圖片

如上圖所示HDFS是Master和Slave的結構,分為NameNode、Secondary NameNode和DataNode三種角色。

lNameNode:在Hadoop1.X中只有一個Master節點,管理HDFS的名稱空間和數據塊映射信息、配置副本策略和處理客戶端請求;

lSecondary NameNode:輔助NameNode,分擔NameNode工作,定期合並fsimage和fsedits並推送給NameNode,緊急情況下可輔助恢復NameNode;

lDataNode:Slave節點,實際存儲數據、執行數據塊的讀寫並匯報存儲信息給NameNode;

2.2HDFS讀操作

技術分享圖片

1. 客戶端通過調用FileSystem對象的open()方法來打開希望讀取的文件,對於HDFS來說,這個對象時分布文件系統的一個實例;

2. DistributedFileSystem通過使用RPC來調用NameNode以確定文件起始塊的位置,同一Block按照重復數會返回多個位置,這些位置按照Hadoop集群拓撲結構排序,距離客戶端近的排在前面;

3. 前兩步會返回一個FSDataInputStream對象,該對象會被封裝成DFSInputStream對象,DFSInputStream可以方便的管理datanode和namenode數據流,客戶端對這個輸入流調用read()方法;

4. 存儲著文件起始塊的DataNode地址的DFSInputStream隨即連接距離最近的DataNode,通過對數據流反復調用read()方法,可以將數據從DataNode傳輸到客戶端;

5. 到達塊的末端時,DFSInputStream會關閉與該DataNode的連接,然後尋找下一個塊的最佳DataNode,這些操作對客戶端來說是透明的,客戶端的角度看來只是讀一個持續不斷的流;

6. 一旦客戶端完成讀取,就對FSDataInputStream調用close()方法關閉文件讀取。

2.3HDFS寫操作

技術分享圖片

1. 客戶端通過調用DistributedFileSystem的create()方法創建新文件;

2. DistributedFileSystem通過RPC調用NameNode去創建一個沒有Blocks關聯的新文件,創建前NameNode會做各種校驗,比如文件是否存在、客戶端有無權限去創建等。如果校驗通過,NameNode會為創建新文件記錄一條記錄,否則就會拋出IO異常;

3. 前兩步結束後會返回FSDataOutputStream的對象,和讀文件的時候相似,FSDataOutputStream被封裝成DFSOutputStream,DFSOutputStream可以協調NameNode和Datanode。客戶端開始寫數據到DFSOutputStream,DFSOutputStream會把數據切成一個個小的數據包,並寫入內部隊列稱為“數據隊列”(Data Queue);

4. DataStreamer會去處理接受Data Queue,它先問詢NameNode這個新的Block最適合存儲的在哪幾個DataNode裏,比如重復數是3,那麽就找到3個最適合的DataNode,把他們排成一個pipeline.DataStreamer把Packet按隊列輸出到管道的第一個Datanode中,第一個DataNode又把Packet輸出到第二個DataNode中,以此類推;

5. DFSOutputStream還有一個對列叫Ack Quene,也是有Packet組成,等待DataNode的收到響應,當Pipeline中的所有DataNode都表示已經收到的時候,這時Akc Quene才會把對應的Packet包移除掉;

6. 客戶端完成寫數據後調用close()方法關閉寫入流;

7. DataStreamer把剩余的包都刷到Pipeline裏然後等待Ack信息,收到最後一個Ack後,通知NameNode把文件標示為已完成。

2.4HDFS中常用到的命令

lhadoop fs

hadoop fs -ls /

hadoop fs -lsr

hadoop fs -mkdir /user/hadoop

hadoop fs -put a.txt /user/hadoop/

hadoop fs -get /user/hadoop/a.txt /

hadoop fs -cp src dst

hadoop fs -mv src dst

hadoop fs -cat /user/hadoop/a.txt

hadoop fs -rm /user/hadoop/a.txt

hadoop fs -rmr /user/hadoop/a.txt

hadoop fs -text /user/hadoop/a.txt

hadoop fs -copyFromLocal localsrc dst 與hadoop fs -put功能類似。

hadoop fs -moveFromLocal localsrc dst 將本地文件上傳到hdfs,同時刪除本地文件。

lhadoop fsadmin

hadoop dfsadmin -report

hadoop dfsadmin -safemode enter | leave | get | wait

hadoop dfsadmin -setBalancerBandwidth 1000

lhadoop fsck

lstart-balancer.sh

相關HDFS API可以到Apache官網進行查看:

技術分享圖片

3、測試例子1

3.1測試例子1內容

在Hadoop集群中編譯並運行《權威指南》中的例3.2,讀取HDFS文件內容。

3.2 運行代碼

import java.io.InputStream;

import java.net.URI;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.*;
import org.apache.hadoop.io.IOUtils;

public class FileSystemCat {
public static void main(String[] args) throws Exception {
String uri = args[0];
Configuration conf = new Configuration();
FileSystem fs = FileSystem. get(URI.create (uri), conf);
InputStream in = null;
try {
in = fs.open( new Path(uri));
IOUtils.copyBytes(in, System.out, 4096, false);
} finally {
IOUtils.closeStream(in);
}
}
}

3.3實現過程

3.3.1創建代碼目錄

使用如下命令啟動Hadoop

cd /app/hadoop-1.1.2/bin

./start-all.sh

在/app/hadoop-1.1.2目錄下使用如下命令建立myclass和input目錄:

cd /app/hadoop-1.1.2

mkdir myclass

mkdir input

技術分享圖片

3.3.2建立例子文件上傳到HDFS中

進入/app/hadoop-1.1.2/input目錄,在該目錄中建立quangle.txt文件

cd /app/hadoop-1.1.2/input

touch quangle.txt

vi quangle.txt

內容為:

On the top of the Crumpetty Tree

The Quangle Wangle sat,

But his face you could not see,

On account of his Beaver Hat.

技術分享圖片

使用如下命令在hdfs中建立目錄/class4

hadoop fs -mkdir /class4

hadoop fs -ls /

(如果需要直接使用hadoop命令,需要把/app/hadoop-1.1.2加入到Path路徑中)

技術分享圖片

3.3.3配置本地環境

對/app/hadoop-1.1.2/conf目錄中的hadoop-env.sh進行配置,如下如所示:

cd /app/hadoop-1.1.2/conf

sudo vi hadoop-env.sh

加入對HADOOP_CLASPATH變量值,值為/app/hadoop-1.1.2/myclass,設置完畢後編譯該配置文件,使配置生效

export HADOOP_CLASSPATH=$HADOOP_CLASSPATH:/app/hadoop-1.1.2/myclass

技術分享圖片

3.3.4編寫代碼

進入/app/hadoop-1.1.2/myclass目錄,在該目錄中建立FileSystemCat.java代碼文件,命令如下:

cd /app/hadoop-1.1.2/myclass/

vi FileSystemCat.java

輸入代碼內容:

技術分享圖片

3.3.5編譯代碼

在/app/hadoop-1.1.2/myclass目錄中,使用如下命令編譯代碼:

javac -classpath ../hadoop-core-1.1.2.jar FileSystemCat.java

ls

技術分享圖片

3.3.6使用編譯代碼讀取HDFS文件

使用如下命令讀取HDFS中/class4/quangle.txt內容:

hadoop FileSystemCat /class4/quangle.txt

技術分享圖片

4、測試例子2

4.1測試例子2內容

在本地文件系統生成一個大約100字節的文本文件,寫一段程序讀入這個文件並將其第101-120字節的內容寫入HDFS成為一個新文件。

4.2運行代碼

註意:在編譯前請先刪除中文註釋!

hadoop-hdfs簡介