您好,登錄后才能下訂單哦!
如何進行HDFS的特性和JavaAPI源碼分析,相信很多沒有經驗的人對此束手無策,為此本文總結了問題出現的原因和解決方法,通過這篇文章希望你能解決這個問題。
HDFS 是一個 Apache Software Foundation 項目,是 Apache Hadoop 項目的一個子項目。Hadoop 非常適于存儲大型數據(比如 terabytes和petabytes),并使用 HDFS 作為其存儲系統。HDFS 允許您連接多個集群中包含的節點 (普通個人計算機),那些集群上分布著一些數據文件。然后您可以將那些數據文件作為一個無縫文件系統來進行訪問和存儲。對數據文件的訪問通過一種流線型(streaming) 方式進行處理,這意味著應用程序或命令通過 MapReduce 處理模型直接執行(參見 參考資料)。HDFS 是容錯的,且提供對大數據集的高吞吐量訪問。
HDFS 與其他分布式文件系統有許多相似點,但也有幾個不同點。一個明顯的區別是 HDFS 的 “一次寫入、多次讀取(write-once-read-many)” 模型,該模型降低了并發性控制要求,簡化了數據聚合性,支持高吞吐量訪問。
HDFS 的另一個獨特的特性是下面這個觀點:將處理邏輯放置到數據附近通常比將數據移向應用程序空間更好。
HDFS 將數據寫入嚴格限制為一次一個寫入程序。字節總是被附加到一個流的末尾,字節流總是以寫入順序存儲。
HDFS 有許多目標,下面是一些最明顯的目標:
通過檢測故障和應用快速、自動的恢復實現容錯性
通過 MapReduce 流進行數據訪問
簡單可靠的聚合模型
處理邏輯接近數據,而不是數據接近處理邏輯
跨異構普通硬件和操作系統的可移植性
可靠存儲和處理大量數據的可伸縮性
通過跨多個普通個人計算機集群分布數據和處理來節約成本
通過分布數據和邏輯到數據所在的多個節點上進行平行處理來提高效率
通過自動維護多個數據副本和在故障發生時自動重新部署處理邏輯來實現可靠性
HDFS應用程序接口(API)
您可以以多種不同的方法訪問 HDFS。HDFS 提供了一個原生 Java? 應用程序編程接口(API重點介紹)和一個針對這個 Java API 的原生 C 語言封裝器。另外,您可以使用一個 web 瀏覽器來瀏覽 HDFS 文件.例外還有以下可以來訪問HDFS:
既然HDFS 是存取數據的分布式文件系統,那么對HDFS 的操作,就是文件系統的基本操作,比如文件的創建、修改、刪除、修改權限等,文件夾的創建、刪除、重命名等。對HDFS 的操作命令類似于lLinux 的shell 對文件的操作,如ls、mkdir、rm 等。我們執行以下操作的時候,一定要確定hadoop 是正常運行的,使用jps 命令確保看到各個hadoop 進程。SHELL操作較多,簡介見文檔Hadoop-Shell.pdf還有該鏈接http://hadoop.apache.org/docs/r1.0.4/cn/hdfs_shell.html,就不一個一個介紹啦。
我們通過hadoop shell 上傳的文件是存放在DataNode 的block 中,通過linux shell 是看不到文件的,只能看到block。可以一句話描述HDFS:把客戶端的大文件存放在很多節點的數據塊中。在這里,出現了三個關鍵詞:文件、節點、數據塊。HDFS 就是圍繞著這三個關鍵詞設計的,我們在學習的時候也要緊抓住這三個關鍵詞來學習。
HDFS 由一些互聯的節點集群組成,文件和目錄駐留在那些節點上。一個 HDFS 集群包含一個節點,稱為 NameNode,該節點管理文件系統名稱空間并規范客戶端對文件的訪問。另外, Data node (DataNodes)將數據作為塊存儲在文件中。HDFS的架構圖如下:
由上圖可知:在 HDFS 中,一個給定的NameNode是整個文件系統的管理節點。它維護著整個文件系統的文件目錄樹,文件/目錄的元信息和每個文件對應的數據塊列表兩套數據,Namenode還將數據塊映射到Data node,處理來自 HDFS 客戶端的讀寫請求。 Data node 還根據 Name node 的指令創建、刪除和復制數據塊。
其中的文件放在指定目錄(有配置文件core-site.xml的dfs.name.dir屬性決定).在該目錄下包括:
fsimage:元數據鏡像文件。存儲某一時段NameNode內存元數據信息。在內存...
edits:操作日志文件。
fstime:保存最近一次checkpoint的時間
這些的文件保存在linux系統下的文件系統下.HDFS的客戶端所有的操作必須經過NameNode
提供真實文件的存儲服務.
文件塊(Block):最基本的存儲單位。對于文件內容而言,一個文件的長度大小是size,那么從文件的0偏移開始,按照固定的大小,順序對文件進行劃分并編號,劃分好的每一個塊稱一個Block。HDFS默認Block大小是128MB(可配置),以一個256MB文件,共有256/128=2個Block.block 本質上是一個邏輯概念,意味著block 里面不會真正的存儲數據,只是劃分文件的.不同于普通文件系統的是,HDFS中,如果一個文件小于一個數據塊的大小,并不占用整個數據塊存儲空間.
在每臺主機Linux文件系統中都能找到:
副本(replication):多副本,默認是三個.可配置:hdfs-site.xml中dfs.replication的屬性.機柜意識:
通常,大型 HDFS 集群跨多個安裝點(機柜)排列。一個安裝中的不同節點之間的網絡流量通常比跨安裝點的網絡流量更高效。一個 Name node 盡量將一個塊的多個副本放置到多個安裝上以提高容錯能力。但是,HDFS 允許管理員決定一個節點屬于哪個安裝點。因此,每個節點都知道它的機柜 ID,也就是說,它具有機柜意識。
見下圖:就不做解釋啦.
Data node 持續循環,詢問 Name node 的指令。 Name node 不能直接連接到 Data node ,它只是從 Data node 調用的函數返回值。每個 Data node 都維護一個開放的服務器套接字,以便客戶端代碼或其他 Data node 能夠讀寫數據。 Name node 知道這個服務器的主機或端口,將信息提供給有關客戶端或其他 Data node 。所有 HDFS 通信協議都構建于 TCP/IP 協議之上。HDFS 客戶端連接到 Name node 上打開的一個 Transmission Control Protocol (TCP) 端口,然后使用一個基于 Remote Procedure Call (RPC) 的專有協議與 Name node 通信。 Data node 使用一個基于塊的專有協議與 Name node 通信。Hadoop整個生態系統都是基于RPC協議之上的。??????關于RPC的通信原理將例外寫一篇博客.鏈接。。。??????
實際上,為了提高整個集群的可靠性和可維護性,各大公司和社區都提出來很多改進HDFS的方案,在這里,我就暫時介紹HDFS其中的一種,以后博客會詳細描述HDFS HA的解決方案,并且進行總結.
Secondary NameNode通過定期下載NameNode的元數據和日志文件,并進行合并更新,來對NameNode進行備份。當NameNode故障時,可以通過Secondary NameNode進行恢復,但是不足之處在于Secondary NameNode的備份知識NameNode的Checkpoint,并沒有與NameNode實時同步,恢復后的數據存在一定的元信息丟失,由于在恢復過程中存在一段系統不可用的時間,該方案只能是一種備份方案,并不是真正意義上的HA方案.該流程圖如下:
NameNode的執行:
Namenode始終在內存中保存metedata,用于處理“讀請求”. 等到有“寫請求”到來時,namenode會首先寫editlog到磁盤,即向edits文件中寫日志,成功返回后,才會修改內存,并且向客戶端返回。 Hadoop會維護一個fsimage文件,也就是namenode中metedata的鏡像,但是fsimage不會隨時與namenode內存中的metedata保持一致,而是每隔一段時間通過合并edits文件來更新內容。有誰來合并呢??---->Secondary namenode就是用來合并fsimage和edits文件來更新NameNode的metedata的。
Secondary namendoe的工作流程:
1.secondary通知namenode切換edits文件(這時NameNode會生成newedits文件) 2.secondary從namenode獲得fsimage和edits(通過http) 3.secondary將fsimage載入內存,然后開始合并(以一定的算法)edits 4.secondary將新的fsimage發回給namenode 5.namenode用新的fsimage替換舊的fsimage
直接上代碼:
HadoopUtil.java package com.codewatching.hadoop.service; import java.net.URI; import org.apache.hadoop.conf.Configuration; import org.apache.hadoop.fs.FileSystem; /** * Hadoop簡單工具類 * @author LISAI */ public class HadoopUtil { public static FileSystem getFileSystem(){ try { Configuration conf = new Configuration(); URI uri = new URI("hdfs://yun10-0:9000/"); FileSystem fileSystem = FileSystem.get(uri, conf, "lisai"); return fileSystem; } catch (Exception e) { e.printStackTrace(); } return null; } }
HadoopBasicAPIService.java package com.codewatching.hadoop.service; import java.io.FileOutputStream; import java.io.OutputStream; import org.apache.hadoop.fs.FSDataInputStream; import org.apache.hadoop.fs.FileSystem; import org.apache.hadoop.fs.Path; import org.apache.hadoop.io.IOUtils; /** * Hadoop API的操作 * @author LISAI */ public class HadoopBasicAPIService { private FileSystem fileSystem = HadoopUtil.getFileSystem(); /** * 傳統方式---下載 */ @Deprecated public void downLoadTraditional(String uri,String dest) throws Exception{ FSDataInputStream dataInputStream = fileSystem.open(new Path(uri)); OutputStream outputStream = new FileOutputStream(dest); IOUtils.copyBytes(dataInputStream, outputStream, fileSystem.getConf()); } /** * 常用方式---下載(windows環境下注意事項) */ public void downLoadSimple(String src,String dest) throws Exception{ fileSystem.copyToLocalFile(new Path(src), new Path(dest)); } /** * 上傳 * @param src * @param dest * @throws Exception */ public void upload(String src,String dest) throws Exception{ fileSystem.copyFromLocalFile(new Path(src),new Path(dest)); } /** * 創建文件夾 * @param makeDir * @throws Exception */ public void mkdir(String makeDir) throws Exception{ fileSystem.mkdirs(new Path(makeDir)); } /** * 刪除文件夾 */ public void deldir(String delDir) throws Exception{ fileSystem.delete(new Path(delDir),true); } }
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進行相關操作。RPC過程的原理,以后的博客會有大幅邊幅談論.
dfs===========DFSClient[clientName=DFSClient_NONMAPREDUCE_1386880610_1, ugi=lisai (auth:SIMPLE)]
fs===========DFS[DFSClient[clientName=DFSClient_NONMAPREDUCE_1386880610_1, ugi=lisai (auth:SIMPLE)]]
初始化完畢。。。。。。
中間省略幾個方法調用..........
這下就拿到了FSDataInputStream流到客戶端。接下來的步驟就是COPY的事啦。
看完上述內容,你們掌握如何進行HDFS的特性和JavaAPI源碼分析的方法了嗎?如果還想學到更多技能或想了解更多相關內容,歡迎關注億速云行業資訊頻道,感謝各位的閱讀!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。