04HDFS簡介

来源:https://www.cnblogs.com/touch-fish/archive/2023/01/28/17069835.html
-Advertisement-
Play Games

隨著業務的發展,系統會越來越龐大,原本簡單穩定的功能,可能在不斷迭代後複雜度上升,潛在的風險也隨之暴露,導致最終服務不穩定,造成業務價值的損失。而為了減少這種情況,其中一種比較好的方式就是提高代碼質量,比如通過代碼審查,從而降低錯誤風險,但是,代碼審查難度大,代碼缺陷、漏洞不易發現,且審查工作隨著代 ...


HDFS簡介

一、什麼是HDFS

HDFS全稱是Hadoop Distributed File System,簡稱HDFS。這是一個分散式文件系統,當數據規模大小超過一臺物理電腦的存儲能力時,就有必要進行分區並存儲到若幹台物理電腦上。管理網路中跨多台電腦的文件系統稱為分散式文件系統。

Hadoop的文件系統是一個抽象的概念,java的抽象類是org.apache.hadoop.fs.FileSystem,在創建一個FileSystem的時候,FileSystem使用文件系統URI的Schema作為查詢配置或者SPI尋找實現類(類似JDBC)。FileSystem有很多實現,HDFS只是其中的一個實現,它的實現類是org.apache.hadoop.hdfs.DistributedFileSystem,它的URI schema為hdfs。Hadoop預設配置的文件系統實現是org.apache.hadoop.fs.LocalFileSystem,URI schema為file,用於管理本地文件。


二、HDFS的基礎概念

1、數據塊

塊設備(例如硬碟)一般會有一個預設塊大小,這是設備讀寫的最小單位,這類設備的塊大小一般為幾千位元組。HDFS同樣有塊的概念,預設情況下HDFS的塊大小為128MB。但是與硬碟的文件系統不一樣,當文件小於HDFS的塊大小時,不會占用整個塊的空間,例如一個1MB大小的文件只占用了1MB的空間,而不是128MB。HDFS的塊比硬碟的大是為了最小化定址開銷,如果塊足夠大,從磁碟傳輸數據的時間會明顯大於定位這個塊位置需要的時間,所以傳輸一個大文件的時間取決於磁碟傳輸速率。

使用塊來管理分散式文件系統有很多好處,例如一個文件可以大於某個物理設備的容量,文件並不需要存儲在一個物理設備上。另一個好處是塊可以存儲在多個節點上,防止某個設備因為故障而丟失數據。

2、namenode和datanode

HDFS集群有兩種節點,分別是namenode和datanode。以管理節點——工作節點方式對外提供服務,即client連接namenode,一個namenode節點負責管理多個datanode。

namenode負責管理文件系統的命名空間,它維護文件系統元數據信息,例如目錄和文件名稱。這些信息以文件的形式永久保存在硬碟上:分別是命令空間鏡像文件和編輯日誌文件。namenode也記錄每個文件的塊所在的數據節點信息,但它並不永久保存塊的位置,這些信息會在啟動的時候根據數據節點的數據重建。

datanode就是文件系統的工作節點。它們根據需要存儲數據塊信息,並且定期向namenode發送所存儲的塊列表。HDFS通過把數據塊冗餘到多個datanode實現數據的安全性,預設副本數量為3。

namenode對外提供服務的時候需要把所有的文件元數據載入到記憶體,重啟的時候會利用鏡像文件和編輯日誌重建數據,鏡像文件類似於Redis的rdb文件。namenode會周期性歸檔編輯日誌來生成一個更加新的鏡像文件,由於歸檔編輯日誌的時候namenode也會對外提供服務,這段時間的操作會寫入到編輯日誌中,所以namenode需要鏡像文件和編輯日誌一起重建文件元數據。一個大規模的HDFS的恢復是非常消耗時間的(取決於所管理的數據規模),由於namenode是管理節點,沒有namenode整個文件系統將無法使用,所以相對datanode,namenode的高可用非常重要。本節主要為對HDFS簡單介紹,故先不討論HDFS的高可用方案。

3、聯邦HDFS

由於namenode在記憶體中維護系統內文件和數據塊的關係,很明顯namenode運行機器的記憶體會限制整個集群能存儲的文件數量。Hadoop在2.x版本引入的聯邦namenode,在聯邦環境下,每個namenode管理一個命名空間的一部分。例如一個namenode管理/a目錄下的所有文件,另一個namenode管理/b目錄下的所有文件。在聯邦環境下,每個namenode是獨立的,其中一個namenode失效了也不會影響其他namenode。


三、hadoop命令行

Hadoop命令行的fs參數提供了一些方便訪問文件系統的操作,所有的參數和格式可以在官網文檔FileSystemShell中查詢到,這裡簡單列舉一些常用的操作。

-cat:讀取文件,並且輸出到標準輸出

格式:hadoop fs -cat [-ignoreCrc] URI [URI ...]

例如:

  • 列印本地文件系統下的text.txt內容

    hadoop fs -cat file:///D:/test.txt
    
  • 列印hdfs上根目錄下的a.txt內容

    hadoop fs -cat hdfs://192.168.73.130:8082/a.txt
    

-ls:列出路徑下的文件內容

格式:hadoop fs -ls URI

例如:

  • 列出hdfs上根目錄的文件內容

    hadoop fs -ls hdfs://192.168.73.130:8082/
    

輸出每一列含義為:許可權,副本數,所屬用戶,所屬用戶組,文件大小,修改時間,文件名。許可權欄位由有7個標識位,第一個標識位含義是文件類型,如果是目錄則為d,然後緊跟的6個標識位表示所屬用戶、所屬用戶組、其他用戶的是否可讀、可寫、可執行,可執行許可權可以忽略,因為不能在HDFS中執行。第二列為副本數,目錄的元數據保存在namenode上,所以沒有副本數。

示例輸入如下:

hadoop fs -ls hdfs://192.168.73.130:8082/
Found 2 items
-rw-r--r--   3 debian supergroup  19481 2023-01-25 15:30 hdfs://192.168.73.130:8082/a.txt
drwxr-xr-x   - debian supergroup      0 2023-01-28 09:08 hdfs://192.168.73.130:8082/test

-copyFromLocal:複製本地文件到HDFS

格式:hadoop fs -copyFromLocal localsrc URI

例如:

  • 把本地的文件a.txt複製到HDFS的/testDir/a.txt上

    hadoop fs -copyFromLocal a.txt hdfs://192.168.73.130:8082/testDir/a.txt
    

-copyToLocal:複製HDFS文件到本地

格式:hadoop fs -copyToLocal URI localsrc

例如:

  • 把HDFS的/testDir/a.txt複製到本地

    hadoop fs -copyToLocal hdfs://localhost:8082/testDir/a.txt a.txt
    

四、FileSystem常用api

1、文件的讀取

使用方法FileSystem#open()可以打開一個FSDataInputStream輸入流,然後可以像讀取本地文件一樣文件中的數據。但是與一般的輸入流不一樣,FSDataInputStream實現了Seekable和介面PositionedReadable,它們分別支持隨機讀取和指定位置讀取。

Seekable的聲明如下:

public interface Seekable {
  /**
   * 設置下一次讀取的時,使用的偏移量
   */
  void seek(long pos) throws IOException;
  
  /**
   * 返回當前讀取偏移量
   */
  long getPos() throws IOException;
}

getPos返回當前讀取偏移量,seek設置下一次read的偏移量,偏移量是當前距離文件起始位置的位元組數。例如可以用如下代碼重覆讀取文件開頭的2048個位元組;

FSDataInputStream in = .....;
byte[] buff = new buff[2048];
in.read(buff);
in.seek(0);
in.read(buff);

seek使用起來很方便,但是是一個相對高開銷的操作,需要慎重使用。

PositionedReadable的聲明如下:

public interface PositionedReadable {
  /**
   * 從position指定的位置開始讀取length個長度的數據,複製到buffer的offset處,返回實際讀取到的位元組數
   */
  int read(long position, byte[] buffer, int offset, int length)
    throws IOException;
  
  /**
   * 從position指定的位置開始讀取length個長度的數據,複製到buffer的offset處
   * 如果到達文件結尾拋出EOFException
   */
  void readFully(long position, byte[] buffer, int offset, int length) throws IOException;
  
   /**
   * 從position指定的位置開始讀取buffer.length個長度的數據,複製到buffer的offset處
   * 如果到達文件結尾拋出EOFException
   */
  void readFully(long position, byte[] buffer) throws IOException;
}

read函數把指定偏移量數據讀取到buffer中,但是實際讀取的位元組數需要調用者接受返回值進行判斷。readFully效果也類似,但是如果到達文件結尾會拋出EOFException。PositionedReadable所有的方法都不會改變當前流讀取文件的位置,同時它的方法也都是線程安全的。

2、文件的寫入

傳入一個Path對象,然後使用FileSystem#create可以創建一個新文件,並且返回一個FSDataOutputStream對象。與java其他的api不一樣,調用create方法會自動創建父級目錄。

使用FileSystem#append()可以向一個已存在的文件尾追加內容,需要說明的是這個方法是一個可選的實現,並不是每一個文件系統都正常此方法。

3、目錄創建

調用FileSystem#mkdirs()方法可以新建一個目錄,通常創建文件不需要顯示調用此方法,因為創建文件會自動創建對應的父級目錄。

4、文件的刪除

調用FileSystem#delete()可以刪除一個文件或者目錄。

5、文件元數據信息

使用FileSystem#getFileStatus方法可以返回一個FileStatus對象來獲取文件或者目錄的的狀態信息,例如是否為目錄、許可權、文件長度等數據。

FileSystem#listStatus可以列出目錄下所有的文件信息。listStatus有多個重載方法,可以額外傳入一個org.apache.hadoop.fs.PathFilter用來過濾目錄的文件。

6、HDFS的一致性模型

對於創建一個目錄,HDFS可以保證操作是立即可見的。但是對於寫入數據並不能保證其可見性。例如對於以下一段Java程式代碼:

OutputStream out = ...;
out.write(buff);
out.flush();

如果是操作本地文件,調用flush方法,會把緩衝區數據刷新到硬碟上,保證其可見性。然而對於HDFS,即使調用了flush方法也不能保證可見性,需要等到數據超過一個塊之後才能對其他讀取進程可見。但是HDFS的實現提供了兩個方法用於保證可見性,分別是FSDataOutputStream#hflushFSDataOutputStream#hsynchsync和操作系統的sync方法類似,保證數據已經存儲在datanode的硬碟上,而hflush僅僅保證數據寫入到datanode的記憶體。調用close關閉流會自動調用一次hflush


五、demo程式

我使用FileSystem常用api實現了一個客戶端demo,代碼地址在github 的hdfsApiExample模塊,打包此模塊可以得到一個hdfs-api-example-1.0-SNAPSHOT.jar的文件,它的使用方法如下:

參數:

  • fs:指定hdfs的namenode地址,假設你有一個namenode地址是hdfs://192.168.73.130:8082
  • u:操作hdfs的用戶,根據hdfs配置情況,寫入的時候可能需要這個參數
  • o:實際需要執行的命令,分別支持ls(查詢目錄文件),rm(刪除),mkdir(創建目錄),cp(複製文件)

示例:

  • 列出hdfs上,根目錄的文件

    hadoop jar hdfs-api-example-1.0-SNAPSHOT.jar -fs hdfs://192.168.73.130:8082 -u debian -o ls /
    
  • 刪除hdfs上,/cnblog目錄。使用額外的r參數遞歸刪除非空目錄

    hadoop jar hdfs-api-example-1.0-SNAPSHOT.jar -fs hdfs://192.168.73.130:8082 -u debian -o rm r /cnblog
    
  • 在根目錄下創建一個cnblog目錄

    hadoop jar hdfs-api-example-1.0-SNAPSHOT.jar -fs hdfs://192.168.73.130:8082 -u debian -o mkdir /cnblog
    
  • 複製本地文件test.txt到hdfs的根目錄上

    hadoop jar hdfs-api-example-1.0-SNAPSHOT.jar -fs hdfs://192.168.73.130:8082 -u debian -o cp text.txt hdfs:/test.text
    
  • 複製hdfs的根目錄文件text.txt到本地目錄上

    hadoop jar hdfs-api-example-1.0-SNAPSHOT.jar -fs hdfs://192.168.73.130:8082 -u debian -o cp hdfs:/test.text text.txt
    

您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • *以下內容為本人的學習筆記,如需要轉載,請聲明原文鏈接 微信公眾號「englyf」https://mp.weixin.qq.com/s/2GFLTstDC7w6u3fTJxflNA 本文大概 1685 個字,閱讀需花 6 分鐘內容不多, 但也花了一些精力如要交流, 歡迎關註我然後評論區留言 謝謝你的 ...
  • 題目描述 運行 C 程式,輸出 100 至 200 之間的質數。 輸入描述 無 輸出描述 輸出 100 至 200 之間的質數,每行輸出一個質數,每個質數前面需要帶有序號。 輸出樣例 解題思路 在《一文解決如何使用 C 語言判斷質數(素數)》一文中,我詳細講解了質數以及如何使用 C 語言判斷質數,本 ...
  • 實現Spring底層機制-02 3.實現任務階段1 3.1知識拓展-類載入器 Java的類載入器有三種: Bootstrap類載入器 對應路徑 jre/lib Ext類載入器 對應路徑 jre/lib/ext App類載入器 對應路徑 classpath classpath 類路徑,就是java.e ...
  • 這篇文章主要討論在RPC框架下如何優雅關閉和啟動服務,包括服務提供方如何通知調用方服務關閉重啟信息,服務提供方如何在關閉後處理現有請求和心情求;服務啟動時,如何實現啟動預熱和延遲暴露。 ...
  • Collection常用方法彙總 Collection公共的方法 Collection是單列結合的祖宗介面,它的方法是所有單列集合都可以繼承使用的。 //把給定元素添加到集合中 public boolean add(E e) //把給定元素從集合中刪除 public boolean remove(E ...
  • 談談你對 Java 平臺的理解?“Java 是解釋執行”,這句話正確嗎? Java 本身是一種面向對象的語言,最顯著的特性有兩個方面,一是所謂的“一處編譯,處處運行”(Write once,run anywhere),能夠非常容易地獲得跨平臺能力;另外就是垃圾收集(GC,Garbage Collec ...
  • 首先我們來嘗試將分片的圖片複原為正常的圖片 這裡是六張切成小細條的圖片,原本是一張大圖的,現在我們用python將他們合併到一塊,題外話圖片來源於中華連環畫,*http://www.zhlhh.com/* 這個網站內有很多優秀的連環畫,而且大部分都是免費,推薦給大家 我的思路是用matlib讀圖片, ...
  • IoC 反轉控制原則也被叫做依賴註入 DI, 容器按照配置註入實例化的對象. 本文將實現一個輕量化的 IoC 容器, 完成對象的實例化和註入, 基於註解不依賴於任何庫. (註解參考 JSR-330) ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...