99999久久久久久亚洲,欧美人与禽猛交狂配,高清日韩av在线影院,一个人在线高清免费观看,啦啦啦在线视频免费观看www

熱線電話:13121318867

登錄
首頁(yè)精彩閱讀大數(shù)據(jù)開(kāi)發(fā)之深入HDFS?_數(shù)據(jù)分析師
大數(shù)據(jù)開(kāi)發(fā)之深入HDFS?_數(shù)據(jù)分析師
2014-11-18
收藏

大數(shù)據(jù)開(kāi)發(fā)之深入HDFS_數(shù)據(jù)分析師

當(dāng)數(shù)據(jù)集的大小超過(guò)一臺(tái)獨(dú)立的物理計(jì)算機(jī)的存儲(chǔ)能力時(shí),就有必要對(duì)它進(jìn)行分區(qū)(partition)并存儲(chǔ)到若干臺(tái)單獨(dú)的計(jì)算機(jī)上。管理網(wǎng)絡(luò)中跨多臺(tái)計(jì)算機(jī)存儲(chǔ)的文件系統(tǒng)稱(chēng)為分布式文件系統(tǒng)(distributed filesystem)。該系統(tǒng)架構(gòu)于網(wǎng)絡(luò)之上,勢(shì)必會(huì)引入網(wǎng)絡(luò)編程的復(fù)雜性,因此分布式文件系統(tǒng)比普通磁盤(pán)文件系統(tǒng)更為復(fù)雜。例如,使文件系統(tǒng)能夠容忍節(jié)點(diǎn)故障且不丟失任何數(shù)據(jù),就是一個(gè)極大的挑戰(zhàn)。

Hadoop有一個(gè)稱(chēng)為HDFS的分布式系統(tǒng),即Hadoop Distributed Filesystem。在非正式文檔或舊文檔以及配置文件中,有時(shí)也簡(jiǎn)稱(chēng)為DFS,它們是一回事兒。HDFSHadoop的旗艦級(jí)文件系統(tǒng),同時(shí)也是本章的重點(diǎn),但實(shí)際上Hadoop是一個(gè)綜合性的文件系統(tǒng)抽象,因此下面我們也將看到Hadoop集成其他文件系統(tǒng)的方法(如本地文件系統(tǒng)和Amazon S3系統(tǒng))。

3.1  HDFS的設(shè)計(jì) 

HDFS以流式數(shù)據(jù)訪問(wèn)模式來(lái)存儲(chǔ)超大文件,運(yùn)行于商用硬件集群上。讓我們仔細(xì)看看下面的描述。


  • 超大文件 “超大文件”在這里指具有幾百M(fèi)B、幾百GB甚至幾百TB大小的文件。目前已經(jīng)有存儲(chǔ)PB級(jí)數(shù)據(jù)的Hadoop 集群了。
  • 流式數(shù)據(jù)訪問(wèn) HDFS的構(gòu)建思路是這樣的:一次寫(xiě)入、多次讀取是最高效的訪問(wèn)模式。數(shù)據(jù)集通常由數(shù)據(jù)源生成或從數(shù)據(jù)源復(fù)制而來(lái),接著長(zhǎng)時(shí)間在此數(shù)據(jù)集上進(jìn)行各種分析。每次分析都將涉及該數(shù)據(jù)集的大部分?jǐn)?shù)據(jù)甚至全部,因此讀取整個(gè)數(shù)據(jù)集的時(shí)間延遲比讀取第一條記錄的時(shí)間延遲更重要。
  • 商用硬件 Hadoop并不需要運(yùn)行在昂貴且高可靠的硬件上。它是設(shè)計(jì)運(yùn)行在商用硬件(在各種零售店都能買(mǎi)到的普通硬件)的集群上的,因此至少對(duì)于龐大的集群來(lái)說(shuō),節(jié)點(diǎn)故障的幾率還是非常高的。HDFS遇到上述故障時(shí),被設(shè)計(jì)成能夠繼續(xù)運(yùn)行且不讓用戶(hù)察覺(jué)到明顯的中斷。同樣,那些不適合在HDFS上運(yùn)行的應(yīng)用也值得研究。目前某些應(yīng)用領(lǐng)域并不適合在HDFS上運(yùn)行,不過(guò)以后可能會(huì)有所改進(jìn)。
  • 低時(shí)間延遲的數(shù)據(jù)訪問(wèn)要求低時(shí)間延遲數(shù)據(jù)訪問(wèn)的應(yīng)用,例如幾十毫秒范圍,不適合在HDFS上運(yùn)行。記住,HDFS是為高數(shù)據(jù)吞吐量應(yīng)用優(yōu)化的,這可能會(huì)以提高時(shí)間延遲為代價(jià)。目前,對(duì)于低延遲的訪問(wèn)需求,HBase(參見(jiàn)第12 章)是更好的選擇。
  • 大量的小文件 由于namenode將文件系統(tǒng)的元數(shù)據(jù)存儲(chǔ)在內(nèi)存中,因此該文件系統(tǒng)所能存儲(chǔ)的文件總數(shù)受限于namenode的內(nèi)存容量。根據(jù)經(jīng)驗(yàn),每個(gè)文件、目錄和數(shù)據(jù)塊的存儲(chǔ)信息大約占150字節(jié)。因此,舉例來(lái)說(shuō),如果有一百萬(wàn)個(gè)文件,且每個(gè)文件占一個(gè)數(shù)據(jù)塊,那至少需要300 MB 的內(nèi)存。盡管存儲(chǔ)上百萬(wàn)個(gè)文件是可行的,但是存儲(chǔ)數(shù)十億個(gè)文件就超出了當(dāng)前硬件的能力。
  • 多用戶(hù)寫(xiě)入,任意修改文件 HDFS中的文件可能只有一個(gè)writer,而且寫(xiě)操作總是將數(shù)據(jù)添加在文件的末尾。它不支持具有多個(gè)寫(xiě)入者的操作,也不支持在文件的任意位置進(jìn)行修改??赡芤院髸?huì)支持這些操作,但它們相對(duì)比較低效。


3.2  HDFS的概念 

3.2.1  數(shù)據(jù)塊 

每個(gè)磁盤(pán)都有默認(rèn)的數(shù)據(jù)塊大小,這是磁盤(pán)進(jìn)行數(shù)據(jù)讀/寫(xiě)的最小單位。構(gòu)建于單個(gè)磁盤(pán)之上的文件系統(tǒng)通過(guò)磁盤(pán)塊來(lái)管理該文件系統(tǒng)中的塊,該文件系統(tǒng)塊的大小可以是磁盤(pán)塊的整數(shù)倍。文件系統(tǒng)塊一般為幾千字節(jié),而磁盤(pán)塊一般為512字節(jié)。這些信息——文件系統(tǒng)塊大小——對(duì)于需要讀/寫(xiě)文件的文件系統(tǒng)用戶(hù)來(lái)說(shuō)是透明的。盡管如此,系統(tǒng)仍然提供了一些工具(如df和fsck)來(lái)維護(hù)文件系統(tǒng),由它們對(duì)文件系統(tǒng)中的塊進(jìn)行操作。

HDFS同樣也有塊(block)的概念,但是大得多,默認(rèn)為64 MB。與單一磁盤(pán)上的文件系統(tǒng)相似,HDFS上的文件也被劃分為塊大小的多個(gè)分塊(chunk),作為獨(dú)立的存儲(chǔ)單元。但與其他文件系統(tǒng)不同的是,HDFS中小于一個(gè)塊大小的文件不會(huì)占據(jù)整個(gè)塊的空間。如果沒(méi)有特殊指出,本書(shū)中提到的“塊”特指HDFS中的塊。

為何HDFS 中的塊如此之大?

HDFS的塊比磁盤(pán)的塊大,其目的是為了最小化尋址開(kāi)銷(xiāo)。如果塊設(shè)置得足夠大,從磁盤(pán)傳輸數(shù)據(jù)的時(shí)間會(huì)明顯大于定位這個(gè)塊開(kāi)始位置所需的時(shí)間。因而,傳輸一個(gè)由多個(gè)塊組成的文件的時(shí)間取決于磁盤(pán)傳輸速率。

我們來(lái)做一個(gè)速算,如果尋址時(shí)間約為10ms,而傳輸速率為100 MB/s,為了使尋址時(shí)間僅占傳輸時(shí)間的1%,我們要將塊大小設(shè)置約為100 MB。默認(rèn)的塊大小實(shí)際為64 MB,但是很多情況下HDFS使用128 MB的塊設(shè)置。以后隨著新一代磁盤(pán)驅(qū)動(dòng)器傳輸速率的提升,塊的大小將被設(shè)置得更大。

但是這個(gè)數(shù)也不會(huì)設(shè)置得過(guò)大。MapReduce中的map任務(wù)通常一次只處理一個(gè)塊中的數(shù)據(jù),因此如果任務(wù)數(shù)太少(少于集群中的節(jié)點(diǎn)數(shù)量),作業(yè)的運(yùn)行速度就會(huì)比較慢。

對(duì)分布式文件系統(tǒng)中的塊進(jìn)行抽象會(huì)帶來(lái)很多好處。第一個(gè)最明顯的好處是,一個(gè)文件的大小可以大于網(wǎng)絡(luò)中任意一個(gè)磁盤(pán)的容量。文件的所有塊并不需要存儲(chǔ)在同一個(gè)磁盤(pán)上,因此它們可以利用集群上的任意一個(gè)磁盤(pán)進(jìn)行存儲(chǔ)。事實(shí)上,盡管不常見(jiàn),但對(duì)于整個(gè)HDFS集群而言,也可以?xún)H存儲(chǔ)一個(gè)文件,該文件的塊占滿(mǎn)集群中所有的磁盤(pán)。

第二個(gè)好處是,使用抽象塊而非整個(gè)文件作為存儲(chǔ)單元,大大簡(jiǎn)化了存儲(chǔ)子系統(tǒng)的設(shè)計(jì)。簡(jiǎn)化是所有系統(tǒng)的目標(biāo),但是這對(duì)于故障種類(lèi)繁多的分布式系統(tǒng)來(lái)說(shuō)尤為重要。將存儲(chǔ)子系統(tǒng)控制單元設(shè)置為塊,可簡(jiǎn)化存儲(chǔ)管理(由于塊的大小是固定的,因此計(jì)算單個(gè)磁盤(pán)能存儲(chǔ)多少個(gè)塊就相對(duì)容易)。同時(shí)也消除了對(duì)元數(shù)據(jù)的顧慮(塊只是存儲(chǔ)數(shù)據(jù)的一部分——而文件的元數(shù)據(jù),如權(quán)限信息,并不需要與塊一同存儲(chǔ),這樣一來(lái),其他系統(tǒng)就可以單獨(dú)管理這些元數(shù)據(jù))。

不僅如此,塊還非常適合用于數(shù)據(jù)備份進(jìn)而提供數(shù)據(jù)容錯(cuò)能力和提高可用性。將每個(gè)塊復(fù)制到少數(shù)幾個(gè)獨(dú)立的機(jī)器上(默認(rèn)為3個(gè)),可以確保在塊、磁盤(pán)或機(jī)器發(fā)生故障后數(shù)據(jù)不會(huì)丟失。如果發(fā)現(xiàn)一個(gè)塊不可用,系統(tǒng)會(huì)從其他地方讀取另一個(gè)復(fù)本,而這個(gè)過(guò)程對(duì)用戶(hù)是透明的。一個(gè)因損壞或機(jī)器故障而丟失的塊可以從其他候選地點(diǎn)復(fù)制到另一臺(tái)可以正常運(yùn)行的機(jī)器上,以保證復(fù)本的數(shù)量回到正常水平。參見(jiàn)4.1節(jié)對(duì)數(shù)據(jù)完整性的討論,進(jìn)一步了解如何應(yīng)對(duì)數(shù)據(jù)損壞。同樣,有些應(yīng)用程序可能選擇為一些常用的文件塊設(shè)置更高的復(fù)本數(shù)量進(jìn)而分散集群中的讀取負(fù)載。 

與磁盤(pán)文件系統(tǒng)相似,HDFS中fsck指令可以顯示塊信息。例如,執(zhí)行以下命令將列出文件系統(tǒng)中各個(gè)文件由哪些塊構(gòu)成(參見(jiàn)10.1.4.2節(jié)): 

  1. % hadoop fsck / -files -blocks   

3.2.2  namenode和datanode 

和多個(gè)datanode(工作者)。namenode管理文件系統(tǒng)的命名空間。它維護(hù)著文件系統(tǒng)樹(shù)及整棵樹(shù)內(nèi)所有的文件和目錄。這些信息以?xún)蓚€(gè)文件形式永久保存在本地磁盤(pán)上:命名空間鏡像文件和編輯日志文件。namenode也記錄著每個(gè)文件中各個(gè)塊所在的數(shù)據(jù)節(jié)點(diǎn)信息,但它并不永久保存塊的位置信息,因?yàn)檫@些信息會(huì)在系統(tǒng)啟動(dòng)時(shí)由數(shù)據(jù)節(jié)點(diǎn)重建。

客戶(hù)端(client)代表用戶(hù)通過(guò)與namenode和datanode交互來(lái)訪問(wèn)整個(gè)文件系統(tǒng)??蛻?hù)端提供一個(gè)類(lèi)似于POSIX(可移植操作系統(tǒng)界面)的文件系統(tǒng)接口,因此用戶(hù)在編程時(shí)無(wú)需知道namenode和datanode也可實(shí)現(xiàn)其功能。

datanode是文件系統(tǒng)的工作節(jié)點(diǎn)。它們根據(jù)需要存儲(chǔ)并檢索數(shù)據(jù)塊(受客戶(hù)端或namenode調(diào)度),并且定期向namenode發(fā)送它們所存儲(chǔ)的塊的列表。

沒(méi)有namenode,文件系統(tǒng)將無(wú)法使用。事實(shí)上,如果運(yùn)行namenode服務(wù)的機(jī)器毀壞,文件系統(tǒng)上所有的文件將會(huì)丟失,因?yàn)槲覀儾恢廊绾胃鶕?jù)datanode的塊重建文件。因此,對(duì)namenode實(shí)現(xiàn)容錯(cuò)非常重要,Hadoop為此提供兩種機(jī)制。

第一種機(jī)制是備份那些組成文件系統(tǒng)元數(shù)據(jù)持久狀態(tài)的文件。Hadoop可以通過(guò)配置使namenode在多個(gè)文件系統(tǒng)上保存元數(shù)據(jù)的持久狀態(tài)。這些寫(xiě)操作是實(shí)時(shí)同步的,是原子操作。一般的配置是,將持久狀態(tài)寫(xiě)入本地磁盤(pán)的同時(shí),寫(xiě)入一個(gè)遠(yuǎn)程掛載的網(wǎng)絡(luò)文件系統(tǒng)(NFS)。

另一種可行的方法是運(yùn)行一個(gè)輔助namenode,但它不能被用作namenode。這個(gè)輔助namenode的重要作用是定期通過(guò)編輯日志合并命名空間鏡像,以防止編輯日志過(guò)大。這個(gè)輔助namenode一般在另一臺(tái)單獨(dú)的物理計(jì)算機(jī)上運(yùn)行,因?yàn)樗枰加么罅緾PU時(shí)間與namenode相同容量的內(nèi)存來(lái)執(zhí)行合并操作。它會(huì)保存合并后的命名空間鏡像的副本,并在namenode發(fā)生故障時(shí)啟用。但是,輔助namenode保存的狀態(tài)總是滯后于主節(jié)點(diǎn),所以在主節(jié)點(diǎn)全部失效時(shí),難免會(huì)丟失部分?jǐn)?shù)據(jù)。在這種情況下,一般把存儲(chǔ)在NFS上的namenode元數(shù)據(jù)復(fù)制到輔助namenode并作為新的主namenode運(yùn)行。

詳情參見(jiàn)10.1.1節(jié)對(duì)文件系統(tǒng)鏡像與編輯日志的討論。

3.2.3  聯(lián)邦HDFS 

namenode在內(nèi)存中保存文件系統(tǒng)中每個(gè)文件和每個(gè)數(shù)據(jù)塊的引用關(guān)系,這意味著對(duì)于一個(gè)擁有大量文件的超大集群來(lái)說(shuō),內(nèi)存將成為限制系統(tǒng)橫向擴(kuò)展的瓶頸(參見(jiàn)9.4.2節(jié))。在2.x發(fā)行版本系列中引入的聯(lián)邦HDFS允許系統(tǒng)通過(guò)添加namenode實(shí)現(xiàn)擴(kuò)展,其中每個(gè)namenode管理文件系統(tǒng)命名空間中的一部分。例如,一個(gè)namenode可能管理/user目錄下的所有文件,而另一個(gè)namenode可能管理/share目錄下的所有文件。

在聯(lián)邦環(huán)境下,每個(gè)namenode維護(hù)一個(gè)命名空間卷(namespace volume),包括命名空間的源數(shù)據(jù)和在該命名空間下的文件的所有數(shù)據(jù)塊的數(shù)據(jù)塊池。命名空間卷之間是相互獨(dú)立的,兩兩之間并不相互通信,甚至其中一個(gè)namenode的失效也不會(huì)影響由其他namenode維護(hù)的命名空間的可用性。數(shù)據(jù)塊池不再進(jìn)行切分,因此集群中的datanode需要注冊(cè)到每個(gè)namenode,并且存儲(chǔ)著來(lái)自多個(gè)數(shù)據(jù)塊池中的數(shù)據(jù)塊。

要想訪問(wèn)聯(lián)邦HDFS集群,客戶(hù)端需要使用客戶(hù)端掛載數(shù)據(jù)表將文件路徑映射到namenode。該功能可以通過(guò)ViewFileSystem和viewfs://URI進(jìn)行配置和管理。

3.2.4  HDFS的高可用性 

通過(guò)聯(lián)合使用在多個(gè)文件系統(tǒng)中備份namenode的元數(shù)據(jù)和通過(guò)備用namenode創(chuàng)建監(jiān)測(cè)點(diǎn)能防止數(shù)據(jù)丟失,但是依舊無(wú)法實(shí)現(xiàn)文件系統(tǒng)的高可用性。Namenode依舊存在單點(diǎn)失效(SPOF)的問(wèn)題。如果namenode失效了,那么所有的客戶(hù)端——包括MapReduce作業(yè)——均無(wú)法讀、寫(xiě)或列 (list)文件,因?yàn)閚amenode是唯一存儲(chǔ)元數(shù)據(jù)與文件到數(shù)據(jù)塊映射的地方。在這一情況下,Hadoop系統(tǒng)無(wú)法提供服務(wù)直到有新的namenode上線。

在這樣的情況下,要想從一個(gè)失效的namenode恢復(fù),系統(tǒng)管理員得啟動(dòng)一個(gè)擁有文件系統(tǒng)元數(shù)據(jù)副本的新的namenode,并配置datanode和客戶(hù)端以便使用這個(gè)新的namenode。新的namenode直到滿(mǎn)足以下情形才能響應(yīng)服務(wù):1)將命名空間的映像導(dǎo)入內(nèi)存中;2)重做編輯日志;3)接收到足夠多的來(lái)自datanode的數(shù)據(jù)塊報(bào)告并退出安全模式。對(duì)于一個(gè)大型并擁有大量文件和數(shù)據(jù)塊的集群,namenode的冷啟動(dòng)需要30分鐘,甚至更長(zhǎng)時(shí)間。

系統(tǒng)恢復(fù)時(shí)間太長(zhǎng),也會(huì)影響到日常維護(hù)。事實(shí)上,namenode失效的可能性非常低,所以在實(shí)際應(yīng)用中計(jì)劃系統(tǒng)失效時(shí)間就顯得尤為重要。

Hadoop的2.x發(fā)行版本系列針對(duì)上述問(wèn)題在HDFS中增加了對(duì)高可用性(HA)的支持。在這一實(shí)現(xiàn)中,配置了一對(duì)活動(dòng)-備用(active-standby) namenode。當(dāng)活動(dòng)namenode失效,備用namenode就會(huì)接管它的任務(wù)并開(kāi)始服務(wù)于來(lái)自客戶(hù)端的請(qǐng)求,不會(huì)有任何明顯中斷。實(shí)現(xiàn)這一目標(biāo)需要在架構(gòu)上做如下修改。


  • namenode之間需要通過(guò)高可用的共享存儲(chǔ)實(shí)現(xiàn)編輯日志的共享。(在早期的高可用實(shí)現(xiàn)版本中,需要一個(gè)NFS過(guò)濾器來(lái)輔助實(shí)現(xiàn),但是在后期版本中將提供更多的選擇,比如構(gòu)建于ZooKeeper之上的BookKeeper這樣的系統(tǒng)。)當(dāng)備用namenode接管工作之后,它將通讀共享編輯日志直至末尾,以實(shí)現(xiàn)與活動(dòng)namenode的狀態(tài)同步,并繼續(xù)讀取由活動(dòng)namenode寫(xiě)入的新條目。
  • datanode需要同時(shí)向兩個(gè)namenode發(fā)送數(shù)據(jù)塊處理報(bào)告,因?yàn)閿?shù)據(jù)塊的映射信息存儲(chǔ)在namenode的內(nèi)存中,而非磁盤(pán)。
  • 客戶(hù)端需要使用特定的機(jī)制來(lái)處理namenode的失效問(wèn)題,這一機(jī)制對(duì)用戶(hù)是透明的。


在活動(dòng)namenode失效之后,備用namenode能夠快速(幾十秒的時(shí)間)實(shí)現(xiàn)任務(wù)接管,因?yàn)樽钚碌臓顟B(tài)存儲(chǔ)在內(nèi)存中:包括最新的編輯日志條目和最新的數(shù)據(jù)塊映射信息。實(shí)際觀察到的失效時(shí)間略長(zhǎng)一點(diǎn)(需要1分鐘左右),這是因?yàn)橄到y(tǒng)需要保守確定活動(dòng)namenode是否真的失效了。

在活動(dòng)namenode失效且備用namenode也失效的情況下,當(dāng)然這類(lèi)情況發(fā)生的概率非常低,管理員依舊可以申明一個(gè)備用namenode并實(shí)現(xiàn)冷啟動(dòng)。這類(lèi)情況并不會(huì)比非高可用(no-HA)的情況更差,并且從操作的角度講這是一個(gè)進(jìn)步,因?yàn)樯鲜鎏幚硪咽且粋€(gè)標(biāo)準(zhǔn)的處理過(guò)程并植入Hadoop中。

故障切換與規(guī)避 

一個(gè)稱(chēng)為故障轉(zhuǎn)移控制器(failover_controller)的系統(tǒng)中有一個(gè)新實(shí)體管理著將活動(dòng)namenode轉(zhuǎn)移為備用namenode的轉(zhuǎn)換過(guò)程。故障轉(zhuǎn)移控制器是可插拔的,但其最初的實(shí)現(xiàn)是基于ZooKeeper的并由此確保有且僅有一個(gè)活動(dòng)namenode。每一個(gè)namenode運(yùn)行著一個(gè)輕量級(jí)的故障轉(zhuǎn)移控制器,其工作就是監(jiān)視宿主namenode是否失效(通過(guò)一個(gè)簡(jiǎn)單的心跳機(jī)制實(shí)現(xiàn))并在namenode失效時(shí)進(jìn)行故障切換。

管理員也可以手動(dòng)發(fā)起故障轉(zhuǎn)移,例如在進(jìn)行日常維護(hù)時(shí)。這稱(chēng)為“平穩(wěn)的故障轉(zhuǎn)移”,因?yàn)楣收限D(zhuǎn)移控制器可以組織兩個(gè)namenode有序切換角色。

但在非平穩(wěn)故障轉(zhuǎn)移的情況下,無(wú)法確切知道失效namenode是否已經(jīng)停止運(yùn)行。例如,在網(wǎng)速非常慢或者網(wǎng)絡(luò)被分割的情況下,同樣也可能激發(fā)故障轉(zhuǎn)移,但是先前的活動(dòng)namenode依然運(yùn)行著并且依舊是活動(dòng)namenode。高可用實(shí)現(xiàn)做了更進(jìn)一步的優(yōu)化,以確保先前活動(dòng)的namenode不會(huì)執(zhí)行危害系統(tǒng)并導(dǎo)致系統(tǒng)崩潰的操作——該方法稱(chēng)為“規(guī)避”(fencing)。系統(tǒng)引入了一系列的規(guī)避機(jī)制,包括殺死namenode進(jìn)程,收回訪問(wèn)共享存儲(chǔ)目錄的權(quán)限(通常使用供應(yīng)商指定的NFS命令),通過(guò)遠(yuǎn)程管理命令以屏蔽相應(yīng)網(wǎng)絡(luò)端口。訴諸的最后手段是,先前活動(dòng)namenode可以通過(guò)一個(gè)相當(dāng)形象的稱(chēng)為STONITH(shootthe other node in the head)的技術(shù)進(jìn)行規(guī)避,該方法主要通過(guò)一個(gè)特定的供電單元對(duì)相應(yīng)主機(jī)進(jìn)行斷電操作。

客戶(hù)端的故障切換通過(guò)客戶(hù)端類(lèi)庫(kù)實(shí)現(xiàn)透明處理。最簡(jiǎn)單的實(shí)現(xiàn)是通過(guò)客戶(hù)端的配置文件實(shí)現(xiàn)故障切換的控制。HDFS URI使用一個(gè)邏輯主機(jī)名,該主機(jī)名映射到一對(duì)namenode地址(在配置文件中設(shè)置),客戶(hù)端類(lèi)庫(kù)會(huì)訪問(wèn)每一個(gè)namenode地址直至處理完成。

3.3  命令行接口 

現(xiàn)在我們通過(guò)命令行交互來(lái)進(jìn)一步認(rèn)識(shí)HDFSHDFS還有很多其他接口,但命令行是最簡(jiǎn)單的,同時(shí)也是許多開(kāi)發(fā)者最熟悉的。

參照附錄A中偽分布模式下設(shè)置Hadoop的說(shuō)明,我們先在一臺(tái)機(jī)器上運(yùn)行HDFS。稍后介紹如何在集群上運(yùn)行HDFS,以提供伸縮性與容錯(cuò)性。

在我們?cè)O(shè)置偽分布配置時(shí),有兩個(gè)屬性項(xiàng)需要進(jìn)一步解釋。第一項(xiàng)是fs.default.name,設(shè)置為hdfs://localhost/,用于設(shè)置Hadoop的默認(rèn)文件系統(tǒng)。文件系統(tǒng)是由URI指定的,這里我們已使用hdfs URI來(lái)配置HDFSHadoop的默認(rèn)文件系統(tǒng)。HDFS的守護(hù)程序通過(guò)該屬性項(xiàng)來(lái)確定HDFS namenode的主機(jī)及端口。我們將在localhost默認(rèn)端口8020上運(yùn)行namenode。這樣一來(lái),HDFS客戶(hù)端可以通過(guò)該屬性得知namenode在哪里運(yùn)行進(jìn)而連接到它。

第二個(gè)屬性dfs.replication,我們?cè)O(shè)為1,這樣一來(lái),HDFS就不會(huì)按默認(rèn)設(shè)置將文件系統(tǒng)塊復(fù)本設(shè)為3。在單獨(dú)一個(gè)datanode上運(yùn)行時(shí),HDFS無(wú)法將塊復(fù)制到3個(gè)datanode上,所以會(huì)持續(xù)給出塊復(fù)本不足的警告。設(shè)置這個(gè)屬性之后,就不會(huì)再有問(wèn)題了。

文件系統(tǒng)的基本操作 

至此,文件系統(tǒng)已經(jīng)可以使用了,我們可以執(zhí)行所有常用的文件系統(tǒng)操作,例如,讀取文件,新建目錄,移動(dòng)文件,刪除數(shù)據(jù),列出目錄,等等??梢暂斎雋adoop fs -help命令獲取每個(gè)命令的詳細(xì)幫助文件。

首先從本地文件系統(tǒng)將一個(gè)文件復(fù)制到HDFS

  1. % hadoop fs -copyFromLocal input/docs/quangle.txt   
  2. hdfs://localhost/user/tom/quangle.txt   

該命令調(diào)用Hadoop文件系統(tǒng)的shell命令fs,后者提供了一系列子命令,在這個(gè)例子中,我們執(zhí)行的是-copyFromLocal。本地文件quangle.txt被復(fù)制到運(yùn)行在localhost上的 HDFS實(shí)例中,路徑為/user/tom/quangle.txt。事實(shí)上,我們可以簡(jiǎn)化命令格式以省略主機(jī)的URI并使用默認(rèn)設(shè)置,即省略hdfs://localhost,因?yàn)樵擁?xiàng)已在core-site.xml中指定。

  1. % hadoop fs -copyFromLocal input/docs/quangle.txt /user/tom/quangle.txt   

我們也可以使用相對(duì)路徑,并將文件復(fù)制到HDFS的home目錄中,本例中為/user/tom: 

  1. % hadoop fs -copyFromLocal input/docs/quangle.txt quangle.txt  

我們把文件復(fù)制回本地文件系統(tǒng),并檢查是否一致: 

  1. % hadoop fs -copyToLocal quangle.txt quangle.copy.txt    
  2. % md5 input/docs/quangle.txt quangle.copy.txt    
  3.  MD5 (input/docs/quangle.txt) = a16f231da6b05e2ba7a339320e7dacd9    
  4.  MD5 (quangle.copy.txt) = a16f231da6b05e2ba7a339320e7dacd9   

MD5鍵值相同,表明這個(gè)文件在HDFS之旅中得以幸存并保存完整。 最后,我們看一下HDFS文件列表。我們新建一個(gè)目錄看它在列表中是怎么顯示的: 

  1. % hadoop fs -mkdir books    
  2. % hadoop fs -ls .    
  3. Found 2 items    
  4. drwxr-xr-x   - tom supergroup   0 2009-04-02 22:41 /user/tom/books    
  5. -rw-r--r--   1 tom supergroup   118 2009-04-02 22:29 /user/tom/quangle.txt   

返回的結(jié)果信息與Unix命令ls -l的輸出結(jié)果非常相似,僅有細(xì)微差別。第1列顯示的是文件模式。第2列是這個(gè)文件的備份數(shù)(這在傳統(tǒng)Unix文件系統(tǒng)是沒(méi)有的)。由于我們?cè)谡麄€(gè)文件系統(tǒng)范圍內(nèi)設(shè)置的默認(rèn)復(fù)本數(shù)為1,所以這里顯示的也都是1。這一列的開(kāi)頭目錄為空,因?yàn)楸纠袥](méi)有使用復(fù)本的概念——目錄作為元數(shù)據(jù)保存在namenode中,而非datanode中。第3列和第4列顯示文件的所屬用戶(hù)和組別。第5列是文件的大小,以字節(jié)為單位,目錄為0。第6列和第7列是文件的最后修改日期與時(shí)間。最后,第8列是文件或目錄的絕對(duì)路徑。 

HDFS中的文件訪問(wèn)權(quán)限

針對(duì)文件和目錄,HDFS的權(quán)限模式與POSIX 非常相似。

一共提供三類(lèi)權(quán)限模式:只讀權(quán)限(r)、寫(xiě)入權(quán)限(w)和可執(zhí)行權(quán)限(x)。讀取文件或列出目錄內(nèi)容時(shí)需要只讀權(quán)限。寫(xiě)入一個(gè)文件或是在一個(gè)目錄上新建及刪除文件或目錄,需要寫(xiě)入權(quán)限。對(duì)于文件而言,可執(zhí)行權(quán)限可以忽略,因?yàn)槟悴荒茉?a href='/map/hdfs/' style='color:#000;font-size:inherit;'>HDFS中執(zhí)行文件(與POSIX不同),但在訪問(wèn)一個(gè)目錄的子項(xiàng)時(shí)需要該權(quán)限。

每個(gè)文件和目錄都有所屬用戶(hù)(owner)、所屬組別(group)及模式(mode)。這個(gè)模式是由所屬用戶(hù)的權(quán)限、組內(nèi)成員的權(quán)限及其他用戶(hù)的權(quán)限組成的。

在默認(rèn)情況下,可以通過(guò)正在運(yùn)行進(jìn)程的用戶(hù)名和組名來(lái)唯一確定客戶(hù)端的標(biāo)識(shí)。但由于客戶(hù)端是遠(yuǎn)程的,任何用戶(hù)都可以簡(jiǎn)單地在遠(yuǎn)程系統(tǒng)上以其名義新建一個(gè)賬戶(hù)來(lái)進(jìn)行訪問(wèn)。因此,作為共享文件系統(tǒng)資源和防止數(shù)據(jù)意外損失的一種機(jī)制,權(quán)限只能供合作團(tuán)體中的用戶(hù)使用,而不能用于在一個(gè)不友好的環(huán)境中保護(hù)資源。注意,最新版的Hadoop已經(jīng)支持Kerberos用戶(hù)認(rèn)證,該認(rèn)證去除了這些限制,詳見(jiàn)第325頁(yè)的“安全”小節(jié)。但是,除了上述限制之外,為防止用戶(hù)或自動(dòng)工具及程序意外修改或刪除文件系統(tǒng)的重要部分,啟用權(quán)限控制還是很重要的(這也是默認(rèn)的配置,參見(jiàn)dfs.permissions屬性)。

如果啟用權(quán)限檢查,就會(huì)檢查所屬用戶(hù)權(quán)限,以確認(rèn)客戶(hù)端的用戶(hù)名與所屬用戶(hù)是否匹配,另外也將檢查所屬組別權(quán)限,以確認(rèn)該客戶(hù)端是否是該用戶(hù)組的成員;若不符,則檢查其他權(quán)限。

這里有一個(gè)超級(jí)用戶(hù)(super-user)的概念,超級(jí)用戶(hù)是namenode進(jìn)程的標(biāo)識(shí)。對(duì)于超級(jí)用戶(hù),系統(tǒng)不會(huì)執(zhí)行任何權(quán)限檢查。

3.4  Hadoop文件系統(tǒng) 

Hadoop有一個(gè)抽象的文件系統(tǒng)概念,HDFS只是其中的一個(gè)實(shí)現(xiàn)。Java抽象類(lèi) org.apache.hadoop.fs.FileSystem定義了Hadoop 中的一個(gè)文件系統(tǒng)接口,并且該抽象類(lèi)有幾個(gè)具體實(shí)現(xiàn),如表3-1所示。

表3-1.  Hadoop文件系統(tǒng) 

文件系統(tǒng) URI方案 Java實(shí)現(xiàn)(均包含在org.apache.hadoop包中) 描述
Local file fs.LocalFileSystem 使用了客戶(hù)端校驗(yàn)和的本地磁盤(pán)文件系統(tǒng)。沒(méi)有使用校驗(yàn)和的本地磁盤(pán)文件系統(tǒng)RawLocalFileSystem。詳情參見(jiàn)4.1.2節(jié)
HDFS hdfs hdfs.DistributedFileSystem Hadoop 的分布式文件系統(tǒng)。將HDFS設(shè)計(jì)成與MapReduce結(jié)合使用,可以實(shí)現(xiàn)高性能
HFTP Hftp hdfs.hftpFileSystem 一個(gè)在HTTP 上提供對(duì)HDFS 只讀訪問(wèn)的文件系統(tǒng)(盡管名稱(chēng)為HFTP,但與FTP無(wú)關(guān))。通常與distcp結(jié)合使用(參見(jiàn)3.8節(jié)),以實(shí)現(xiàn)在運(yùn)行不同版本的HDFS的集群之間復(fù)制數(shù)據(jù)
HSFTP hsftp hdfs.HsftpFileSyste 在HTTPS 上提供對(duì)HDFS只讀訪問(wèn)的文件系統(tǒng)(同上,與FTP 無(wú)關(guān))
WebHDFS Webhdfs Hdfs.web.WebHdfsFileSystem 基于HTTP,對(duì)HDFS提供安全讀寫(xiě)訪問(wèn)的文件系統(tǒng)。WebHDFS是為了替代HFTP和HSFTP而構(gòu)建的
HAR har fs.HarFileSystem

一個(gè)構(gòu)建在其他文件系統(tǒng)之上用于文件存檔的文件系統(tǒng)。Hadoop存檔文件系統(tǒng)通常用于需要將HDFS 中的文件進(jìn)行存檔時(shí),以減少namenode內(nèi)存的使用。參見(jiàn)3.9節(jié)

hfs(云存儲(chǔ)) kfs fs.kfs.kosmosFileSystem CloudStore(其前身為Kosmos文件系統(tǒng))是類(lèi)似于HDFS或是谷歌的GFS的文件系統(tǒng),用C++寫(xiě)。詳情參見(jiàn)http://kosmosfs.sourceforge.net/
FTP ftp fs.ftp.FTPFileSystem 由FTP 服務(wù)器支持的文件系統(tǒng)
S3(原生) S3n fs.s3native.NativeS3FileSystem 由Amazon S3 支持的文件系統(tǒng)。參見(jiàn)http://wiki.apache.org/hadoop/AmazonS3
S3(基于塊) S3 fs.sa.S3FileSystem 由Amazon S3 支持的文件系統(tǒng),以塊格式存儲(chǔ)文件(與HDFS 很相似)以解決S3 的5 GB文件大小限制
分布式RAID hdfs hdfs.DistributedRaidFileSystem RAID版本的HDFS是為了存檔而設(shè)計(jì)的。針對(duì)HDFS中的每個(gè)文件,創(chuàng)建一個(gè)(更小的)校驗(yàn)文件,并允許HDFS中的數(shù)據(jù)副本由3降為2,由此可以減少25%~30%的存儲(chǔ)空間,但是數(shù)據(jù)丟失的概率保持不變。分布式RAID模式需要在集群中運(yùn)行一個(gè)RaidNode后臺(tái)進(jìn)程
View viewfs viewfs.ViewFileSystem 針對(duì)其他Hadoop文件系統(tǒng)掛載的客戶(hù)端表。通常用于聯(lián)邦namenode創(chuàng)建掛載點(diǎn)。詳情參見(jiàn)3.2.3節(jié)。
Hadoop 對(duì)文件系統(tǒng)提供了許多接口,它一般使用URI 方案來(lái)選取合適的文件系統(tǒng)實(shí)例進(jìn)行交互。舉例來(lái)說(shuō),我們?cè)谇耙恍」?jié)中遇到的文件系統(tǒng)命令行解釋器可以操作所有的Hadoop 文件系統(tǒng)命令。要想列出本地文件系統(tǒng)根目錄下的文件,可以輸入以下命令: 

  1. % hadoop fs -ls file:///  

盡管運(yùn)行的MapReduce程序可以訪問(wèn)任何文件系統(tǒng)(有時(shí)也很方便),但在處理大數(shù)據(jù)集時(shí),建議你還是選擇一個(gè)有數(shù)據(jù)本地優(yōu)化的分布式文件系統(tǒng),如HDFS(參見(jiàn)2.4節(jié))。

接口 

Hadoop是用Java寫(xiě)的,通過(guò)Java API可以調(diào)用所有Hadoop文件系統(tǒng)的交互操作。例如,文件系統(tǒng)的命令解釋器就是一個(gè)Java 應(yīng)用,它使用Java 的FileSystem類(lèi)來(lái)提供文件系統(tǒng)操作。其他一些文件系統(tǒng)接口也將在本小節(jié)中做簡(jiǎn)單介紹。這些接口通常與HDFS一同使用,因?yàn)?a href='/map/hadoop/' style='color:#000;font-size:inherit;'>Hadoop中的其他文件系統(tǒng)一般都有訪問(wèn)基本文件系統(tǒng)的工具(對(duì)于FTP,有FTP客戶(hù)端;對(duì)于S3,有S3工具,等等),但它們大多數(shù)都能用于任何Hadoop 文件系統(tǒng)。

1. HTTP 

通過(guò)HTTP來(lái)訪問(wèn)HDFS有兩種方法:直接訪問(wèn),HDFS后臺(tái)進(jìn)程直接服務(wù)于來(lái)自客戶(hù)端的請(qǐng)求;通過(guò)代理(一個(gè)對(duì)多個(gè))訪問(wèn),客戶(hù)端通常使用DistributedFileSystem API訪問(wèn)HDFS。這兩種方法如圖3-1所示。 

圖3-1. 通過(guò)HTTP直接訪問(wèn)HDFS或者通過(guò)多個(gè)HDFS代理訪問(wèn)HDFS 

在第一種情況中,由namenode內(nèi)嵌的web服務(wù)器(運(yùn)行在端口50070上)提供目錄服務(wù),目錄列表以XML或者JSON格式存儲(chǔ),并且文件數(shù)據(jù)由datanode的web服務(wù)器(運(yùn)行在端口50075上)以數(shù)據(jù)流的形式傳輸。 

原來(lái)那個(gè)的HTTP接口(HFTP和HSFTP)是只讀的,但是新的WebHDFS實(shí)現(xiàn)支持所有的文件系統(tǒng)操作,包括Kerberos認(rèn)證。WebHDFS必須通過(guò)將dfs.webhdfs.enalbe選項(xiàng)設(shè)置為真后才能啟用,并且只有啟用它之后,你才可以使用webhdfs URI。

第二種方法依靠一個(gè)或者多個(gè)獨(dú)立代理服務(wù)器通過(guò)HTTP訪問(wèn)HDFS。(由于代理服務(wù)是無(wú)狀態(tài)的,因此可以運(yùn)行在標(biāo)準(zhǔn)的負(fù)載均衡器之后。)所有到集群的網(wǎng)絡(luò)通信都需要經(jīng)過(guò)代理。使用代理服務(wù)器后可以使用更嚴(yán)格的防火墻策略和帶寬限制策略。通常情況下通過(guò)代理服務(wù)器,實(shí)現(xiàn)在不同數(shù)據(jù)中心中部署的Hadoop集群之間的數(shù)據(jù)傳輸。

原來(lái)那個(gè)的HDFS代理服務(wù)器(在src/contrib/hdfsproxy)是只讀的并且客戶(hù)端使用HSFTP Filesystem實(shí)現(xiàn)(hsftp URI)進(jìn)行訪問(wèn)。從1.0.0版本開(kāi)始,實(shí)現(xiàn)了一個(gè)稱(chēng)為HttpFS的新代理服務(wù)器(具備讀和寫(xiě)的能力),并且提供了和WebHDFS的一樣的HTTP接口,因此客戶(hù)端可以通過(guò)webhdfsURI訪問(wèn)這兩類(lèi)接口。

在規(guī)范正式定義了WebHDFS中使用的HTTP REST API,以期望以后使用非Java語(yǔ)言編寫(xiě)的客戶(hù)端有望直接使用這個(gè)API。

2. C語(yǔ)言 

Hadoop提供了一個(gè)名為libhdfs的C語(yǔ)言庫(kù),該語(yǔ)言庫(kù)是Java,F(xiàn)ileSystem接口類(lèi)的一個(gè)鏡像(它被寫(xiě)成訪問(wèn)HDFS的C語(yǔ)言庫(kù),但其實(shí)它可以訪問(wèn)全部Hadoop文件系統(tǒng))。它使用Java原生接口(Java Native Interface,JNI)調(diào)用Java 文件系統(tǒng)客戶(hù)端。

這個(gè)C語(yǔ)言API 與Java的API非常相似,但它的開(kāi)發(fā)一般滯后于Java API,因此目前一些新的特性可能還不支持??梢栽贖apdoop發(fā)行包的Libhdfs/docs/api目錄找到CAPI的相關(guān)文檔。

Hadoop 中自帶預(yù)先編譯好的32位Linux的libhdfs二進(jìn)制編碼,但對(duì)于其他平臺(tái),需要按照http://wiki.apache.org/hadoop/LibHDFS的教程自行編譯。

3. FUSE 

用戶(hù)空間文件系統(tǒng)(Filesystem in Userspace,F(xiàn)USE)允許把按照用戶(hù)空間實(shí)現(xiàn)的文件系統(tǒng)整合成一個(gè)Unix文件系統(tǒng)。通過(guò)使用Hadoop的Fuse-DFS功能模塊,任何一個(gè)Hadoop 文件系統(tǒng)(不過(guò)一般為HDFS)均可以作為一個(gè)標(biāo)準(zhǔn)文件系統(tǒng)進(jìn)行掛載。隨后便可以使用Unix工具(如ls和cat)與該文件系統(tǒng)交互,還可以通過(guò)任意一種編程語(yǔ)言調(diào)用POSIX 庫(kù)來(lái)訪問(wèn)文件系統(tǒng)。

Fuse-DFS是用C語(yǔ)言實(shí)現(xiàn)的,調(diào)用libhdfs并作為訪問(wèn)HDFS的接口。關(guān)于如何編譯和運(yùn)行Fuse-DFS的文檔,可以在Hadoop發(fā)行版的src/contrib./fuse-dfs目錄中找到。

3.5  Java接口 

在本小節(jié)中,我們要深入探索Hadoop的Filesystem類(lèi):它是與Hadoop的某一文件系統(tǒng)進(jìn)行交互的API。雖然我們主要聚焦于HDFS實(shí)例,即DistributedFileSystem,但總體來(lái)說(shuō),還是應(yīng)該集成FileSystem抽象類(lèi),并編寫(xiě)代碼,使其在不同文件系統(tǒng)中可移植。這對(duì)測(cè)試你編寫(xiě)的程序非常重要,例如,你可以使用本地文件系統(tǒng)中的存儲(chǔ)數(shù)據(jù)快速進(jìn)行測(cè)試。

3.5.1  從Hadoop URL讀取數(shù)據(jù) 

要從Hadoop 文件系統(tǒng)讀取文件,最簡(jiǎn)單的方法是使用java.net.URL對(duì)象打開(kāi)數(shù)據(jù)流,從中讀取數(shù)據(jù)。具體格式如下:

  1. InputStream in = null;    
  2.  try {    
  3.       in = new URL(

數(shù)據(jù)分析咨詢(xún)請(qǐng)掃描二維碼

若不方便掃碼,搜微信號(hào):CDAshujufenxi

數(shù)據(jù)分析師資訊
更多

OK
客服在線
立即咨詢(xún)
客服在線
立即咨詢(xún)
') } function initGt() { var handler = function (captchaObj) { captchaObj.appendTo('#captcha'); captchaObj.onReady(function () { $("#wait").hide(); }).onSuccess(function(){ $('.getcheckcode').removeClass('dis'); $('.getcheckcode').trigger('click'); }); window.captchaObj = captchaObj; }; $('#captcha').show(); $.ajax({ url: "/login/gtstart?t=" + (new Date()).getTime(), // 加隨機(jī)數(shù)防止緩存 type: "get", dataType: "json", success: function (data) { $('#text').hide(); $('#wait').show(); // 調(diào)用 initGeetest 進(jìn)行初始化 // 參數(shù)1:配置參數(shù) // 參數(shù)2:回調(diào),回調(diào)的第一個(gè)參數(shù)驗(yàn)證碼對(duì)象,之后可以使用它調(diào)用相應(yīng)的接口 initGeetest({ // 以下 4 個(gè)配置參數(shù)為必須,不能缺少 gt: data.gt, challenge: data.challenge, offline: !data.success, // 表示用戶(hù)后臺(tái)檢測(cè)極驗(yàn)服務(wù)器是否宕機(jī) new_captcha: data.new_captcha, // 用于宕機(jī)時(shí)表示是新驗(yàn)證碼的宕機(jī) product: "float", // 產(chǎn)品形式,包括:float,popup width: "280px", https: true // 更多配置參數(shù)說(shuō)明請(qǐng)參見(jiàn):http://docs.geetest.com/install/client/web-front/ }, handler); } }); } function codeCutdown() { if(_wait == 0){ //倒計(jì)時(shí)完成 $(".getcheckcode").removeClass('dis').html("重新獲取"); }else{ $(".getcheckcode").addClass('dis').html("重新獲取("+_wait+"s)"); _wait--; setTimeout(function () { codeCutdown(); },1000); } } function inputValidate(ele,telInput) { var oInput = ele; var inputVal = oInput.val(); var oType = ele.attr('data-type'); var oEtag = $('#etag').val(); var oErr = oInput.closest('.form_box').next('.err_txt'); var empTxt = '請(qǐng)輸入'+oInput.attr('placeholder')+'!'; var errTxt = '請(qǐng)輸入正確的'+oInput.attr('placeholder')+'!'; var pattern; if(inputVal==""){ if(!telInput){ errFun(oErr,empTxt); } return false; }else { switch (oType){ case 'login_mobile': pattern = /^1[3456789]\d{9}$/; if(inputVal.length==11) { $.ajax({ url: '/login/checkmobile', type: "post", dataType: "json", data: { mobile: inputVal, etag: oEtag, page_ur: window.location.href, page_referer: document.referrer }, success: function (data) { } }); } break; case 'login_yzm': pattern = /^\d{6}$/; break; } if(oType=='login_mobile'){ } if(!!validateFun(pattern,inputVal)){ errFun(oErr,'') if(telInput){ $('.getcheckcode').removeClass('dis'); } }else { if(!telInput) { errFun(oErr, errTxt); }else { $('.getcheckcode').addClass('dis'); } return false; } } return true; } function errFun(obj,msg) { obj.html(msg); if(msg==''){ $('.login_submit').removeClass('dis'); }else { $('.login_submit').addClass('dis'); } } function validateFun(pat,val) { return pat.test(val); }