Google公司的三駕馬車GFS、Bigtable和MapReduce經(jīng)常被大家看作是云計(jì)算的經(jīng)典之作,Amazon公司的Dynamo和開(kāi)源項(xiàng)目Hadoop也是云計(jì)算世界里的明星產(chǎn)品,實(shí)際上從技術(shù)角度來(lái)看它們都屬于分布式系統(tǒng)的范疇。
分布式文件系統(tǒng)是如何發(fā)展起來(lái)的呢?
從20世紀(jì)70年代誕生至今,大致上可以將分布式文件系統(tǒng)的發(fā)展歷程劃分為四個(gè)階段。1990年之前的分布式文件系統(tǒng)主要以提供標(biāo)準(zhǔn)接口的遠(yuǎn)程文件訪問(wèn)為目的,比較關(guān)注系統(tǒng)性能和可靠性。這一階段的典型代表包括Sun公司研制的NFS(NetworkFile System)和美國(guó)卡內(nèi)基梅隆大學(xué)開(kāi)發(fā)的AFS(Andrew File System)。
1990年到1995年期間,互聯(lián)網(wǎng)逐步得到推廣應(yīng)用,網(wǎng)絡(luò)中傳輸實(shí)時(shí)多媒體數(shù)據(jù)的需求和應(yīng)用也逐漸流行,這一階段出現(xiàn)了不少為了實(shí)現(xiàn)上述需求而開(kāi)發(fā)設(shè)計(jì)的分布式文件系統(tǒng),例如加利福尼亞大學(xué)研制的xFS(x File System)和IBM公司針對(duì)AIX操作系統(tǒng)開(kāi)發(fā)的TigerShark。
1995年到2000年期間,網(wǎng)絡(luò)技術(shù)和存儲(chǔ)技術(shù)持續(xù)發(fā)展,NAS和SAN等新的存儲(chǔ)技術(shù)開(kāi)始得到大量應(yīng)用,與之相應(yīng)的分布式文件系統(tǒng)也應(yīng)運(yùn)而生,例如美國(guó)明尼蘇達(dá)大學(xué)研制的GFS(Global File System)和IBM公司在TigerSpark基礎(chǔ)上開(kāi)發(fā)的GPFS(General Parallel File System)。
進(jìn)入21世紀(jì)以來(lái),隨著網(wǎng)格計(jì)算和云計(jì)算技術(shù)的發(fā)展,以Google公司為代表的軟件公司和研究機(jī)構(gòu)針對(duì)Web應(yīng)用的特色,陸續(xù)推出了新型的分布式文件系統(tǒng)。這其中最為著名的當(dāng)屬Google公司的GFS(Google File System)和Hadoop開(kāi)源項(xiàng)目的HDFS(Hadoop Distributed File System)。
注意上面提到了兩個(gè)GFS,一個(gè)是明尼蘇達(dá)大學(xué)研制的Global File System,另一個(gè)是Google公司開(kāi)發(fā)的Google File System,后續(xù)我們提到的GFS都是特指后者,不再專門(mén)說(shuō)明。
看起來(lái),好像進(jìn)入21世紀(jì)之后的分布式文件系統(tǒng)才與云計(jì)算產(chǎn)生了交集,是這樣嗎?
應(yīng)該說(shuō),GFS和HDFS都是在云計(jì)算時(shí)代應(yīng)運(yùn)而生的產(chǎn)物,它們與傳統(tǒng)的分布式文件系統(tǒng)有很大的不同,更能夠滿足云計(jì)算的需求。
但是,GFS的新穎之處并不在于它采用了多么令人驚訝的新技術(shù),而在于它采用廉價(jià)的商用計(jì)算機(jī)集群構(gòu)建分布式文件系統(tǒng),在降低成本的同時(shí)經(jīng)受了實(shí)際應(yīng)用的考驗(yàn)。
與傳統(tǒng)的分布式文件系統(tǒng)相比,GFS有哪些新的設(shè)計(jì)需求呢?
在性能、伸縮性、可靠性等方面,GFS的設(shè)計(jì)目標(biāo)與傳統(tǒng)的分布式文件系統(tǒng)沒(méi)有什么區(qū)別;但是考慮Google各種應(yīng)用的實(shí)際情況后,GFS在許多方面的設(shè)計(jì)目標(biāo)又具有鮮明的特色。這主要體現(xiàn)在下述方面。
(1)Google的數(shù)據(jù)中心均采用廉價(jià)的計(jì)算機(jī)和IDE硬盤(pán)構(gòu)建,因此硬件故障是一種常見(jiàn)的狀況,在軟件設(shè)計(jì)上必須提高容錯(cuò)能力。
(2)系統(tǒng)需要處理數(shù)以百萬(wàn)計(jì)的文件,大多數(shù)是100MB或更大,其中出現(xiàn)GB級(jí)別的文件也不奇怪,必須在設(shè)計(jì)時(shí)充分考慮這些因素。
(3)系統(tǒng)主要考慮支持兩種讀操作:大規(guī)模數(shù)據(jù)流讀和小規(guī)模隨機(jī)讀。前者通常連續(xù)讀取1MB或更多數(shù)據(jù),后者通常讀取幾kB數(shù)據(jù)。
(4)系統(tǒng)中存在兩種寫(xiě)操作:大規(guī)模順序?qū)懞托∫?guī)模隨機(jī)寫(xiě)。前者通常連續(xù)寫(xiě)入1MB或更多數(shù)據(jù),需要在設(shè)計(jì)時(shí)考慮性能優(yōu)化。
(5)經(jīng)常會(huì)出現(xiàn)多個(gè)應(yīng)用程序同時(shí)向同一個(gè)文件進(jìn)行追加寫(xiě)操作,必須保證這些并發(fā)操作的正確性。
(6)希望系統(tǒng)在針對(duì)大數(shù)據(jù)量操作時(shí)獲得高性能,不關(guān)注單個(gè)讀寫(xiě)操作所花費(fèi)的時(shí)間。
GFS為應(yīng)用程序提供了哪些訪問(wèn)接口?
GFS提供了一個(gè)類似傳統(tǒng)文件系統(tǒng)的接口,按照層次型的目錄樹(shù)來(lái)管理文件,并提供傳統(tǒng)的Create、Delete、Open、Close、Read和Write操作。除此之外,GFS還專門(mén)提供了Snapshot和Record Append兩種操作。其中Snapshot以最小的開(kāi)銷創(chuàng)建一個(gè)目錄或文件的副本,Record Append則用來(lái)保證多個(gè)應(yīng)用程序同時(shí)對(duì)文件進(jìn)行追加寫(xiě)操作時(shí)的正確性。
GFS采用了怎樣的系統(tǒng)架構(gòu)?
如圖1所示,一個(gè)GFS的集群包括一個(gè)主服務(wù)器(master)和多個(gè)塊服務(wù)器(chunk server),能夠同時(shí)為多個(gè)客戶端應(yīng)用程序(Application)提供文件服務(wù)。每個(gè)服務(wù)器或應(yīng)用程序都是運(yùn)行在Linux服務(wù)器中的一個(gè)進(jìn)程,只要性能允許,可以將服務(wù)器進(jìn)程和應(yīng)用進(jìn)程運(yùn)行在同一個(gè)物理服務(wù)器上。
圖1 GFS的系統(tǒng)架構(gòu)
GFS中文件劃分為固定大小的塊,每個(gè)塊在創(chuàng)建時(shí)由主服務(wù)器分配一個(gè)64位的句柄。塊服務(wù)器將塊以Linux文件的形式保存在本地硬盤(pán)上,并通過(guò)句柄實(shí)現(xiàn)對(duì)其指定的字節(jié)范圍進(jìn)行讀寫(xiě)的操作。缺省情況下,GFS對(duì)每個(gè)塊在三個(gè)不同的塊服務(wù)器上保持三個(gè)備份,用戶也可定制備份策略。
主服務(wù)器負(fù)責(zé)維護(hù)所有文件系統(tǒng)的元數(shù)據(jù),包括命名空間、存取控制信息、文件和塊的映射關(guān)系以及塊的物理位置等。主服務(wù)器還負(fù)責(zé)管理文件系統(tǒng),包括塊的租用、垃圾塊的回收以及塊在不同塊服務(wù)器之間的遷移。此外,主服務(wù)器還周期性地與每個(gè)塊服務(wù)器通過(guò)心跳消息交互,以監(jiān)視運(yùn)行狀態(tài)或下達(dá)命令。應(yīng)用程序采用GFS提供的API函數(shù)接口通過(guò)與主服務(wù)器和塊服務(wù)器的交互來(lái)實(shí)現(xiàn)對(duì)應(yīng)用數(shù)據(jù)的讀寫(xiě),應(yīng)用與主服務(wù)器之間的交互僅限于元數(shù)據(jù),所有的數(shù)據(jù)操作都是直接與塊服務(wù)器交互的。
GFS中應(yīng)用和塊服務(wù)器都沒(méi)有針對(duì)數(shù)據(jù)采用緩存機(jī)制。絕大多數(shù)應(yīng)用的流數(shù)據(jù)都是大型文件,因此在客戶端無(wú)法采用數(shù)據(jù)緩存機(jī)制;而塊服務(wù)器在Linux文件中已經(jīng)采用了緩存機(jī)制,因此也不需要重復(fù)實(shí)現(xiàn)塊的緩存了。當(dāng)然,客戶端針對(duì)元數(shù)據(jù)還是采取了緩存機(jī)制。
塊的大小是如何設(shè)計(jì)的?
這是一個(gè)關(guān)鍵設(shè)計(jì)參數(shù),GFS選擇了64MB,該方案優(yōu)點(diǎn)如下。
(1)降低了客戶與主服務(wù)器之間的交互。對(duì)于在同一塊之內(nèi)讀寫(xiě)操作需要的塊服務(wù)器信息,客戶只需要向主服務(wù)器請(qǐng)求一次就可以了,因此降低了客戶與主服務(wù)器之間的交互。由于GFS的應(yīng)用大多是面向大文件的,因此這個(gè)優(yōu)點(diǎn)體現(xiàn)得很明顯。
(2)降低了集群中的網(wǎng)絡(luò)負(fù)荷。由于客戶的讀寫(xiě)操作大多被限制在同一塊服務(wù)器之內(nèi),客戶就不需要建立與多個(gè)塊服務(wù)器的TCP連接,因此降低了網(wǎng)絡(luò)負(fù)荷。
(3)減少了主服務(wù)器中元數(shù)據(jù)的存儲(chǔ)容量。該方案的缺點(diǎn)如下:如果多個(gè)客戶同時(shí)訪問(wèn)一個(gè)僅有幾個(gè)塊組成的小文件的話,存儲(chǔ)該小文件的塊服務(wù)器就會(huì)成為性能瓶頸。由于Google公司實(shí)際應(yīng)用中絕大多數(shù)操作都是對(duì)大數(shù)據(jù)文件的讀取,因此并沒(méi)有出現(xiàn)這樣的情況。
GFS的讀操作是如何實(shí)現(xiàn)的?
讀操作的步驟如下。
(1)客戶根據(jù)指定位置和塊大小計(jì)算得到文件中的塊索引;
(2)客戶將文件名和塊索引發(fā)給主服務(wù)器查詢對(duì)應(yīng)的塊服務(wù)器及句柄;
(3)客戶將這些信息緩存在本地;
(4)客戶向最近的塊服務(wù)器發(fā)送讀請(qǐng)求,包括塊句柄及讀取范圍;
(5)塊服務(wù)器返回客戶要求讀取的塊內(nèi)容。GFS的寫(xiě)操作又是如何實(shí)現(xiàn)的?
如圖2所示,寫(xiě)操作包括7個(gè)步驟:
圖2 GFS的寫(xiě)操作
(1)客戶向主服務(wù)器查詢寫(xiě)入塊對(duì)應(yīng)的主副本及次副本所在的塊服務(wù)器,主服務(wù)器通過(guò)租約從多個(gè)塊服務(wù)器中選擇主副本。
(2)主服務(wù)器向客戶返回寫(xiě)入塊的位置信息。
(3)客戶將寫(xiě)入數(shù)據(jù)推送到所有副本上,每個(gè)塊服務(wù)器將這些數(shù)據(jù)保存在內(nèi)部緩存中,直到數(shù)據(jù)被使用或過(guò)期。
(4)客戶向主副本所在的塊服務(wù)器發(fā)送寫(xiě)請(qǐng)求。
(5)主副本將客戶的寫(xiě)請(qǐng)求傳遞到所有的次副本。
(6)寫(xiě)入完成后,各次副本將完成情況反饋給主副本。
(7)主副本將完成情況反饋給客戶,如果出錯(cuò)則重復(fù)(3)~(7)步驟。
HDFS的架構(gòu)是怎樣的?
如圖3所示,一個(gè)HDFS的集群包括一個(gè)名稱節(jié)點(diǎn)(NameNode)和多個(gè)數(shù)據(jù)節(jié)點(diǎn)(DataNode),能夠?yàn)槎鄠€(gè)客戶程序(Client)提供服務(wù)。HDFS采用Java語(yǔ)言開(kāi)發(fā),因此任何支持Java的計(jì)算機(jī)都可以用來(lái)部署NameNode和DataNode。
圖3 HDFS的架構(gòu)
HDFS內(nèi)部將文件劃分為若干個(gè)數(shù)據(jù)塊,每個(gè)文件都存儲(chǔ)為一系列的數(shù)據(jù)塊,除最后一個(gè)外所有數(shù)據(jù)塊的大小是相同的。缺省情況下,HDFS同時(shí)保存每個(gè)數(shù)據(jù)塊的三個(gè)副本。
NameNode管理文件系統(tǒng)的命令空間,并維護(hù)文件到數(shù)據(jù)塊的映射關(guān)系。DataNode負(fù)責(zé)處理客戶程序的文件讀寫(xiě)請(qǐng)求,并在NameNode統(tǒng)一調(diào)度下進(jìn)行數(shù)據(jù)塊的創(chuàng)建、復(fù)制和刪除工作。
大型的HDFS集群一般跨越多個(gè)機(jī)架,不同機(jī)架之間通過(guò)交換機(jī)通信。一般將數(shù)據(jù)塊的不同副本存放在不同的機(jī)架上,這樣可以有效防止整個(gè)機(jī)架失效時(shí)數(shù)據(jù)的丟失,還可以在執(zhí)行讀操作時(shí)充分利用多機(jī)架的帶寬實(shí)現(xiàn)負(fù)載均衡。
HDFS的讀操作是如何實(shí)現(xiàn)的?
如圖4所示,客戶程序通過(guò)調(diào)用FileSystem對(duì)象的open()方法打開(kāi)希望讀取的文件DistributedFileSystem實(shí)例,后者通過(guò)遠(yuǎn)程進(jìn)程調(diào)用訪問(wèn)NameNode得到文件起始?jí)K的位置。DistributedFileSystem實(shí)例返回一個(gè)輸入流FSDataInputStream對(duì)象給客戶程序以讀取數(shù)據(jù),該輸入流對(duì)象專門(mén)封裝一個(gè)DFSInputStream對(duì)象管理NameNode和DataNode。
圖4 HDFS的讀操作
客戶程序?qū)υ撦斎肓鲗?duì)象調(diào)用read()方法,DFSInputStream對(duì)象即連接到距離最近的DataNode,通過(guò)反復(fù)調(diào)用read()就可以將數(shù)據(jù)塊從DataNode傳輸?shù)娇蛻舫绦?。到達(dá)塊的末端后,DFSInputStream會(huì)關(guān)閉與該DataNode的連接,轉(zhuǎn)而尋找下一個(gè)塊的最佳DataNode。所有的數(shù)據(jù)塊都讀取完成后會(huì)調(diào)用FSDataInputStream對(duì)象的close()方法結(jié)束本次讀操作。
HDFS的寫(xiě)操作又是如何實(shí)現(xiàn)的?
如圖5所示,客戶程序通過(guò)對(duì)DistributedFileSystem對(duì)象調(diào)用create()方法來(lái)創(chuàng)建文件,該對(duì)象同時(shí)對(duì)NameNode創(chuàng)建一個(gè)遠(yuǎn)程進(jìn)程進(jìn)程調(diào)用,在文件系統(tǒng)的命名空間中創(chuàng)建新文件。之后DistributedFileSystem向客戶程序返回一個(gè)FSDataOutputStream對(duì)象,由此客戶端開(kāi)始寫(xiě)入數(shù)據(jù)。同時(shí)還會(huì)封裝一個(gè)DFSOutputStream對(duì)象負(fù)責(zé)管理NameNode和DataNode。
圖5 HDFS的寫(xiě)操作
在數(shù)據(jù)寫(xiě)入過(guò)程中,DFSOutputStream將寫(xiě)入數(shù)據(jù)劃分為多個(gè)數(shù)據(jù)包,并采用數(shù)據(jù)隊(duì)列方式向多個(gè)DataNode寫(xiě)入副本,收到確認(rèn)消息后繼續(xù)上述過(guò)程寫(xiě)入其他數(shù)據(jù)塊。所有數(shù)據(jù)塊寫(xiě)入完成后會(huì)調(diào)用close()方法結(jié)束本次寫(xiě)入操作,并通知NameNode。
看起來(lái)HDFS與GFS非常相似啊,它們是什么關(guān)系呢?
Google在一份公開(kāi)發(fā)布的論文中介紹了GFS的基本原理,但是并沒(méi)有公開(kāi)其源代碼,Hadoop開(kāi)源項(xiàng)目參考GFS公開(kāi)的設(shè)計(jì)文檔設(shè)計(jì)實(shí)現(xiàn)了HDFS,所以兩者看起來(lái)是非常相似的。
一般認(rèn)為HDFS是GFS的一個(gè)簡(jiǎn)化版的實(shí)現(xiàn),兩者有很多相似之處,例如都采用單主服務(wù)器和多數(shù)據(jù)服務(wù)器的架構(gòu)、都采用數(shù)據(jù)塊的方式來(lái)組織和管理文件。但是兩者還是有不少差異的,例如HDFS不支持Record Append和Snapshot操作。
985大學(xué) 211大學(xué) 全國(guó)院校對(duì)比 專升本