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