1. 程式人生 > >Hadoop分散式檔案系統——HDFS概念以及hdfs讀寫資料

Hadoop分散式檔案系統——HDFS概念以及hdfs讀寫資料

HDFS一流式資料訪問模式來儲存超大檔案,運行於商用硬體叢集上。
一、HDFS 的概念
1、資料塊:
(1) 每個磁碟都有預設的資料塊大小,這是磁碟進行資料讀/寫的最小單位
(2) HDFS有資料塊的概念,預設是64M,hadoop2中是128M。對分散式檔案系統中的塊進行抽象會帶來很多好處。
* 最明顯的好處就是,一個檔案的大小可以大於網路中任意一個磁碟的容量。檔案的所有快並不要儲存在其他任意一個磁碟中,可以利用叢集儲存在任意一個磁碟中。
* 使用抽象塊而非整個檔案作為儲存單元,大大簡化了儲存系統的設計。
2、namenode和datanode
HDFS叢集上有兩類節點以管理者-工作者模式執行,即一個namenode(管理者)和多個datanode(工作者)
(1)namenode管理檔案系統的名稱空間。他維護這檔案系統樹及整個樹內所有的檔案和目錄這些資訊一兩個檔案形式永久儲存在本地磁碟上:名稱空間映象檔案和編輯日誌檔案。namenode也記錄著每個檔案中各個塊所在的資料節點資訊,但它並不永久的儲存塊的位置資訊。
(2)客戶端(client)代表使用者通過與namenode和datanode互動來訪問整個檔案系統。
(3)datanode是檔案系統的工作節點。根據需要儲存檢索資料塊,並且定期向namenode傳送他們所儲存的塊的塊的列表。
(4) 對namenode實現容錯非常重要,Hadoop為此要兩種機制:
* 第一種機制是備份那些組成檔案系統元資料持久狀態的檔案。Hadoop通過配置使namenode在多個檔案系統上實時同步的儲存元資料的持久狀態(原子操作)。一般配置是將持久狀態寫入一個遠端掛載的網路檔案系統(NFS)。
* 另一種可行的方法就是執行一個輔助的namenode,但他不能作為namenode使用。輔助namenode的作用是定期通過編輯日誌合併名稱空間映象,以防止編輯日誌過大。輔助namenode的儲存狀態滯後主namenode,當主namenode失效時,把儲存在NFS上的namenode元資料複製到輔助namenode上,並作為主namenode。
(5)HDFS高可用性,namenode是唯一儲存元資料與檔案到資料塊對映的的地方。
如何恢復一個失效的namenode?
* 系統管理員要啟動一個擁有檔案系統元資料副本的新的namenode,並配置datanode和客戶端以便使用這個新的namenode。
* 新的namenode響應服務的條件:
一是將名稱空間的映像匯入記憶體中;
二是重做編輯日誌;三是接受足夠多的來自datanode的資料塊報告並退出安全模式。
* 故障切換與規避:一個稱為故障轉移控制器的系統中有一個新實體管理這將活動namenode轉移為備用namenode的轉換過程。每個namenode執行一個輕量級的故障轉移控制器,其工作就是監視宿主namenode是否失效並在namenode失效時進行故障切換,可以組織兩個namenode進行有序切換。

二、HDFS常用命令:
hadoop fs
注:path 為路徑 src為檔案路徑 dist 為資料夾
1、-help[cmd] 顯示命令的幫助資訊
2、-ls(r) 顯示當前目錄下的所有檔案 -R層層循出文件夾
3、-du(s) 顯示目錄中所有檔案大小
4、-count[-q] 顯示當前目錄下的所有檔案大小
5、-mv 移動多個檔案目錄到目標目錄
6、-cp 複製多個檔案到目標目錄
7、-rm(r) 刪除檔案(夾)
8、-put 本地檔案複製到hdfs
9、-copyFromLocal 本地檔案複製到hdfs
10、-moveFromLocal 本地檔案移動到hdfs
11、-get[-ignoreCrc] 複製檔案到本地,可以忽略crc校驗
12、-getmerge 將源目錄中的所有檔案排序合併到一個檔案中
13、-cat 在終端顯示檔案內容
14、-text 在終端顯示檔案內容
15、-copyToLocal[-ignoreCrc] 複製檔案到本地
16、-moveToLocal 移動檔案到本地
17、-mkdir 建立資料夾 後跟-p 可以建立不存在的父路徑
例:bin/hdfs dfs -mkdir -p /dir1/dir11/dir111
18、-touchz 建立一個空檔案

三、Hadoop檔案系統
1、從Hadoop URL讀取資料

public class HdfsTest {
             static{
         URL. setURLStreamHandlerFactory(new FsUrlStreamHandlerFactory());//每個Java虛擬機器只能呼叫一次這個方法,因此在靜態方法中呼叫。
            }
  @Test
public void testURL(String path){
      path= "hdfs://hadoop:8020/words.txt";
      InputStream input= null
; try { input= new URL( path).openStream(); IOUtils. copyBytes(input, System. out, 4096,false ); } catch (MalformedURLException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); }finally { IOUtils. closeStream(input); } } }

這裡採用的方法是通過FsUrlStreamHandlerFactory例項去呼叫java.net.URL物件的setURLStreamHandlerFactory方法。然後呼叫org.apache.hadoop.io.IOUtils類,並在finally自劇中關閉資料流,同時也可以在輸入流和輸出流之間複製資料copyBytes方法的最後兩個引數第一個設定用於複製緩衝區大小,第二個設定用於複製結束後是否關閉資料流。
2、通過org.apache.hadoop.fs.FileSystem API讀取資料
FileSystem是一個通用的檔案系統API,獲取FileSystem例項有以下幾個靜態工廠方法。

Configuration物件封裝了客戶端或伺服器的配置,通過設定配置檔案讀取類路徑來實現(如conf/core-site.xml)
 public staticFileSystem get(Configurationconf)throwsException{}//返回的是預設檔案系統在(conf/core-site.xml中指定的,如果沒有指定,則使用預設的本地檔案系統)
public static FileSystem get(URI uri,Configuration conf ) throws Exception{}//第二個方法通過給定的URI方案和許可權來確定要使用的檔案系統,如過給定的URI沒有指定方案,則返回預設    的檔案系統
public static FileSystem get(URI uri,Configuration conf ,String user) throws Exception{}//作為給定使用者訪問檔案系統,對安全來說至關重要。

獲取本地系統的執行例項,可以通過getLocal()方法獲取

public static LocalFileSystem getLocal(Configuration conf) throws Exception{}

獲取FileSystem例項後,可以呼叫open()函式來獲取檔案的輸入流:

  public FSDataInputStream open(Path path ) throws Exception{}
  public abstract FSDataInputStream open(Path path, int buffSize) throws Exception{}

例項:

public void testFileSystem() throws Exception{
                        String uri= "hdfs://hadoop:8020/words.txt";
                        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);
                        }
            }

FSDataInputStream物件
FileSystem物件中的open()方法返回的是FSDataInputStream物件,此物件是繼承了java.io.DataInputStream介面,同時實現了org.apache.hadoop.fs.Seekable介面以及org.apache.hadoop.fs.PositionedReadable介面的一個特殊類

  public class FSDataInputStream extends DataInputStream implements Seekable,PositionedReadable{}

Seekable介面支援檔案中找到指定位置,並提供了一個查詢當前位置相對與檔案起始位置偏移量(getPos())的查詢方法。而其中的seek()方法可以移動到檔案中任意一個絕對位置,與java.io.InputStram中的skip()方法不同,skip()方法只能相對於當前位置定位到另一個新位置。

public interface Seekable{
             void seek( long pos) throws Exception;
             void getPos() throws Exception;
             boolean seekToNewSource(long targetPos) throws Exception;
}

PositionedReadable介面從一個指定偏移量處讀取檔案的一部分。
其中的read()方法從指定position處讀取至多為length位元組的資料並存入緩衝區buffer的指定偏移量offset處。返回值是實際讀到的位元組數。
readFully()方法將指定length長度的位元組數資料讀取到buffer中,除非讀取到檔案的末尾,這種情況將丟擲EOFException異常。

public interface PositionReadable{
             public static read(long postion, byte[] buffer,int offset,int length) throws Exception;
             public void readFully(long postion,byte[] buffer, int offset, int length) throws Exception;
             public void readFully(long postion,byte[] buffer) throws Exception;
}

所有的這些方法都會保留檔案的當前偏移量,並且是執行緒安全的。
最後,seek()方法是一個相對於高開銷的操作,需要謹慎使用。建議使用流資料來建立應用的訪問模式(如使用MapReduce),而非之行大量seek()方法。
3、 寫入資料
(1)最簡單的方法就是給準備見的檔案指定一個Path物件,然後返回一個用於寫入資料的輸出流。

public FSDataOutputStream create(Path path ) throws Exception{}

此方法的有多個過載版本,指定是否需要強制覆蓋現有的檔案,檔案備份數量,寫入檔案時所用的緩衝區大小、檔案塊大小以及檔案許可權。create()方法能夠為需要寫入且當前不存在的檔案建立父目錄。如果希望父目錄不存在就導致檔案寫入失敗,則可以先呼叫exists()方法檢查父目錄是否存在。

@Test
public void uploadFilt2Hdfs() throws Exception{
   String localFile= "D://log_network.txt";
   String hdfsFile= "hdfs://hadoop:8020/upload/log.txt" ;//把本地檔案寫入到輸入流
   InputStream input= new BufferedInputStream( new FileInputStream( localFile));
   FileSystem fs=FileSystem. get(new URI( hdfsFile), new Configuration());
   OutputStream out= fs.create( new Path( hdfsFile), new Progressable() {
   @Override
  public void progress() {
     System. err.println("" );
     }
 });
  IOUtils. copyBytes(input, out, 4096,true);
}

(2)另一種新建檔案的方法是使用append()方法在一個已有檔案末尾追加資料。

public FSDataOutputStream append(Path path ) throws Exception{}

此追加操作允許一個writer開啟一個檔案後在訪問該檔案的最後偏移量出追加資料,可以建立無邊界檔案。例如在關閉日誌檔案之後繼續追加日誌。
(3)FSDataOutputStream物件
也有一個查詢當前位置的方法:

public class FSDataOutpueStream extends DataOutputStream implements Syncable{
             public long getPos() throws IOException{}
}

與FSDataInputStream類不同的是,FSDataOutputStream類不允許在檔案中定位。HDFS值允許對一個已開啟的檔案順序寫入,或在現有的檔案末尾追加資料,他不支援出文件末尾外的其他位置寫入資料。因此寫入資料時定位沒什麼卵用。
(4)目錄
FileSystem提供了建立目錄的方法:

public boolean mkdirs(Path path) throws Exception{}

此方法可任意一次性建立所有必要但還沒有的父目錄。若建立成功則返回true。若不想顯示建立一個目錄,可呼叫create()方法寫入檔案時會自動建立檔案的父目錄。
4、查詢檔案系統
(1)檔案元資料:FileStatus:FileStatus封裝了檔案系統中檔案和目錄的元資料,包括檔案的長度,塊大小,複本,修改時間,所有者以及許可權資訊。FileSystem中的getFileStatus()方法用於獲取檔案或目錄的FileStatus物件。
檢查檔案或目錄是否存在,可以呼叫exists()方法:

public boolean exists(Path path) throws Exception{}

(2)列出檔案:FileSystem的listStatus()方法的功能。

public FileStatus[] listStatus(Path path) throws Exception{}
public FileStatus[] listStatus(Path path,PathFilter filter) throws Exception{}
public FileStatus listStatus(Path[] paths) throws Exception{}
public FileStatus listStatus(Path[] paths,PathFilter filter) throws Exception{}

當傳入的引數是一個檔案時,他會簡單轉變成一陣列方式返回長度為1的FileStatus物件。當傳入引數是一個目錄時,則返回0或多個FileStatus物件,表示目錄中包含的檔案和目錄。
而它的過載方法允許使用PathFilter來顯示匹配的檔案和目錄。
如果指定一組路徑,其執行結果相當於依次輪流傳遞每條路徑對其呼叫listStatus()方法,再將FileStatus物件陣列累積存入同一陣列中,簡便。可運用於從檔案系統樹的不同分支構建輸入檔案列表。

import java.net.URI;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.FileStatus;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.FileUtil;
import org.apache.hadoop.fs.Path;

public class ListStatus {
             public static void main(String[] args) throws Exception {
                        String uri= args[0];
                        Configuration conf= new Configuration();
                        FileSystem fs=FileSystem. get(URI.create (uri ),conf );
                        Path[] paths= new Path[ args. length];
                         for ( int i = 0; i < paths. length; i++) {
                                     paths[ i]= new Path( args[ i]);
                        }
                        FileStatus[] listStatus= fs.listStatus( paths);
                         /**
                         * 注意:FileUtil中的stat2Paths方法的使用,
                         * 他將一個FileStatus物件陣列轉換為一個Path物件的陣列
                         */
                        Path[] listedPaths=FileUtil. stat2Paths(listStatus);
                         for (Path path : listedPaths) {
                                    System. err.println(path );
                        }
            }
}

(3)檔案模式
一個處理日誌的MapReduce作業可能需要分析一個月內包含大量目錄中的日誌檔案。在一個表示式中使用萬用字元來匹配多個檔案時比較方便的,無需列舉每個檔案和目錄來指定輸入,該操作成為“通配”(globbing)。Hadoop為之行通配提供了兩個FileSystem方法:

  public FileStatus[] globStatus(Path pathPattern) throws Exception{}
 public FileStatus[] globStatus(Path pathPattern,PathFilter filter) throws Exception{}

globStatus()方法返回與其路徑匹配指定模式的所有檔案的FileStatus物件陣列,並按路徑進行排序。PathFilter命令作為可選項可以進一步對匹配結果進行限制。
萬用字元及其含義:
這裡寫圖片描述
有日誌檔案儲存在按日期分層組織的目錄結構中,日期萬用字元為:
這裡寫圖片描述
(4)PathFilter:匹配正則表示式的路徑

import org.apache.hadoop.fs.Path;
import org.apache.hadoop.fs.PathFilter;
public class RegexExcludePathFilter implements PathFilter {
             private final String regex ;
             public RegexExcludePathFilter(String regex ) {
                         this. regex = regex;
            }
             @Override
             public boolean accept(Path path) {
                         return !path .toString().matches(regex);
            }
}

還可以過濾優化結果,如例將擴充套件到/2007/12/30
fs .globStatus(new Path(“/2007//“), new RegexExcludePathFilter(“^.*/2007/12/31$”));
過濾器由Path表示,只能作用於英文名。不能針對檔案的屬性(例如建立時間)來構建過濾器,萬用字元模式和正則表示式同樣無法對檔案屬性進行匹配。例如,如果將檔案儲存在按照日起排列的目錄結構中,則可以根據PathFilter在給定時間範圍內選出檔案。
(5) 刪除檔案
使用FileSystem的delete()方法可以永久性刪除檔案或目錄。

public boolean delete(Path path,boolean recursice ) throws IOException{}

如果path是一個檔案或空目錄,那麼recursice的值就會忽略。只有在recursice為true時,非空目錄及其內容才會被刪除,否則會丟擲IOException異常。

相關推薦

Hadoop分散式檔案系統——HDFS概念以及hdfs資料

HDFS一流式資料訪問模式來儲存超大檔案,運行於商用硬體叢集上。 一、HDFS 的概念 1、資料塊: (1) 每個磁碟都有預設的資料塊大小,這是磁碟進行資料讀/寫的最小單位 (2) HDFS有資料塊的概念,預設是64M,hadoop2中是

Hadoop分散式檔案系統HDFS架構

1 Master(NameNode/NN) 帶 N個Slaves(DataNode/DN) HDFS/YARN/HBase 1個檔案會被拆分成多個Block blocksize:128M 130M =

深入理解HDFSHadoop分散式檔案系統

文字詳細介紹了HDFS中的許多概念,對於理解Hadoop分散式檔案系統很有幫助。 1. 介紹 在現代的企業環境中,單機容量往往無法儲存大量資料,需要跨機器儲存。統一管理分佈在叢集上的檔案系統稱為分散式檔案系統。而一旦在系統中,引入網路,就不可避免地引入了所有

Hadoop分散式檔案系統HDFS架構和設計(3)

HDFS被設計成能夠在一個大叢集中跨機器可靠地儲存超大檔案。它將每個檔案儲存成一系列的資料塊,除了最後一個,所有的資料塊都是同樣大小的。為了容錯,檔案的所有資料塊都會有副本。每個檔案的資料塊大小和副本系數都是可配置的。應用程式可以指定某個檔案的副本數目。副本系數可以在檔案建立的時候指定,也可以在之後改變。

Hadoop分散式檔案系統HDFS):架構和設計

HDFS被設計成能夠在一個大叢集中跨機器可靠地儲存超大檔案。它將每個檔案儲存成一系列的資料塊,除了最後一個,所有的資料塊都是同樣大小的。為了容 錯,檔案的所有資料塊都會有副本。每個檔案的資料塊大小和副本系數都是可配置的。應用程式可以指定某個檔案的副本數目。副本系數可以在檔案建立的時候指 定,也可以在之後改

Hadoop分散式檔案系統——HDFS詳解

這篇主要聊一下Hadoop分散式檔案系統—HDFS 大綱: 1.HDFS設計目標 2.HDFS裡面的NameNode和DataNode 3.操作HDFS的兩種方式 1.HDFS設計目標 硬體錯誤 硬體錯誤是常態而不是異常。(每每讀這句我就想到了:程式設計師加

Hadoop分散式檔案系統(HDFS)的基本命令

轉載於:https://blog.csdn.net/zhaojw_420/article/details/531616241、-help[cmd] 顯示命令的幫助資訊./hdfs dfs -help ls12、-ls(r) 顯示當前目錄下的所有檔案 -R層層循出文件夾./hd

Hadoop分散式檔案系統——HDFS

        HDFS是執行在通用硬體平臺上的可容錯分散式檔案系統。它優化了大檔案的流式讀取模式,適用於那些高吞吐並且對延遲性要求相對比較低的場景。它還通過檔案“一次寫入,多次讀取”的簡單策略保證了資料的一致性。HDFS亦使用了“塊複製”的概念,讓資料在叢集的

hadoop分散式檔案系統HDFS)常用API學習

1、org.apache.hadoop.fs.FileSystem 範圍 方法 返回值 描述 addDelegationTokens(String renewer, Cre

hadoop分散式檔案系統HDFS)常用操作

使用命令hadoop fs可以檢視所有的命令,基本上和linux系統命令類似 1、建立資料夾(預設使用者根目錄) hadoop fs -mkdir peom 2、檢視檔案(可以看到許可權,檔案所屬,以及組屬性) hadoop fs -ls /user/lhy 3、將

[hadoop]HDFSHadoop分散式檔案系統)(一)

Hadoop的起源: Hadoop是Google的集群系統的開源實現 Google集群系統:GFS(Google File System)、 MapReduce、BigTableHadoop主要由HDFS(Hadoop Distributed File System Ha

Hadoop分散式檔案系統--HDFS結構分析

前言 在Hadoop內部,具體實現了許多類的檔案系統,當然最最被我們用到的就是他的分散式檔案系統HDFS了。但是本篇文章不會講HDFS的主從架構等東西,因為這些東西網上和資料書中都講得很多了。所以,我決定以我個人的學習所得,來講講HDFS內部的一些有意思的東西

Hadoop分散式檔案系統搭建以及基本操作

1. 環境搭建 jdk-1.8 jdk下載地址 export JAVA_HOME = /usr/lib/java/jdk1.7.0_21 export PATH =$JAVA_HOME/bin:$PATH hadoop-2.7.3 hadoop各個版本

第3章:Hadoop分散式檔案系統(2)

資料流 讀取檔案資料的剖析 為了知道客戶端與HDFS,NameNode,DataNode互動過程中資料的流向,請看圖3-2,這張圖顯示了讀取檔案過程中主要的事件順序。 客戶端通過呼叫FileSystem物件的open()方法開啟一個希望從中讀取資料的檔案,對於HDFS來說,FileSystem是一個Dis

Hadoop分散式檔案系統

Hadoop的核心是HDFS和Map-Reduce,兩者只是理論基礎,不是什麼具體可使用的高階應用。 Hadoop有一個稱為HDFS的分散式系統(Hadoop Distributed FileSystem): 當資料集的大小超過一臺獨立物理計算機的儲存能力時,就

Hadoop分散式檔案系統架構及設計要點

Datanode    HDFS採用master/slave架構。一個HDFS叢集是有一個Namenode和一定數目的Datanode組成。Namenode是一箇中心伺服器,負責管理檔案系統的namespace和客戶端對檔案的訪問。Datanode在叢集中一般是一個節點一個,負責管理節點上它們附帶的儲存。在內

Hadoop分散式檔案系統:架構和設計要點

Hadoop分散式檔案系統:架構和設計要點原文:http://hadoop.apache.org/core/docs/current/hdfs_design.html一、前提和設計目標1、硬體錯誤是常態,而非異常情況,HDFS可能是有成百上千的server組成,任何一個元件都

Apache Hadoop分散式檔案系統說明

==========本文采用谷歌翻譯,請參照中英文學習=========== 在本例中,我們將詳細討論Apache Hadoop分散式檔案系統(HDFS),其元件和體系結構。 HDFS是Apache Hadoop生態系統的核心元件之一。 1.介紹 Apache Hadoo

Hadoop分散式檔案系統利用 java API 實現

(前提:自己的linux系統中的叢集已搭建完畢 )1 . 首先在電腦中安裝 hadoop     配置環境變數:    右鍵點選“計算機”--> 屬性 --> 高階系統設定 --> 環境變數     建立一個 “HADOOP_HOME”,值為hadoop安裝

Hadoop分散式檔案系統:架構和設計要點(翻譯)

Hadoop分散式檔案系統:架構和設計要點一、前提和設計目標1、硬體錯誤是常態,而非異常情況,HDFS可能是有成百上千的server組成,任何一個元件都有可能一直失效,因此錯誤檢測和快速、自動的恢復是HDFS的核心架構目標。2、跑在HDFS上的應用與一般的應用不同,它們主要