這篇文章主要為大家展示了“怎么在HDFS中組織和使用數(shù)據(jù)”,內容簡而易懂,條理清晰,希望能夠幫助大家解決疑惑,下面讓小編帶領大家一起研究并學習一下“怎么在HDFS中組織和使用數(shù)據(jù)”這篇文章吧。
創(chuàng)新互聯(lián)網(wǎng)站建設提供從項目策劃、軟件開發(fā),軟件安全維護、網(wǎng)站優(yōu)化(SEO)、網(wǎng)站分析、效果評估等整套的建站服務,主營業(yè)務為網(wǎng)站設計制作、成都網(wǎng)站建設,手機APP定制開發(fā)以傳統(tǒng)方式定制建設網(wǎng)站,并提供域名空間備案等一條龍服務,秉承以專業(yè)、用心的態(tài)度為用戶提供真誠的服務。創(chuàng)新互聯(lián)深信只要達到每一位用戶的要求,就會得到認可,從而選擇與我們長期合作。這樣,我們也可以走得更遠!4.1 組織數(shù)據(jù)
組織數(shù)據(jù)是使用Hadoop最具挑戰(zhàn)性的方面之一。企業(yè)中存在來自不同部門和不同人員的壓力,例如數(shù)據(jù)科學家和集群管理員,每個人對數(shù)據(jù)都有自己的要求。更重要的是,這些要求通常是在數(shù)據(jù)應用程序投入生產(chǎn)并且已經(jīng)積累大量數(shù)據(jù)之后提出。
Hadoop中組織數(shù)據(jù)有多個維度。首先,我們需要學習如何在HDFS中組織數(shù)據(jù),之后將面臨實際操作問題,例如對數(shù)據(jù)進行分區(qū)和壓縮,決定是否啟用Kerberos來保護集群以及管理和傳遞數(shù)據(jù)更改。本章目標是關注組織數(shù)據(jù)過程中一些復雜問題,包括數(shù)據(jù)分區(qū)和壓縮,讓我們從在HDFS中構建數(shù)據(jù)開始吧。
4.1.1 目錄和文件布局
定義數(shù)據(jù)組織方式的集群范圍標準是一項值得探究的工作,因為它可以更容易地發(fā)現(xiàn)數(shù)據(jù)位置,并且應用和管理可通過數(shù)據(jù)存儲解決的問題。因為我們在文件系統(tǒng)可以表達的范圍內工作,所以安排數(shù)據(jù)的常用方法是創(chuàng)建與企業(yè)組織或功能結構一致的層級結構。例如,如果在分析團隊工作并且正在將新數(shù)據(jù)集引入集群,那么組織目錄的一種方法將如圖4.1所示。
圖4.1 HDFS目錄布局示例
在學習之前,企業(yè)最好已經(jīng)確定了一種數(shù)據(jù)格式,例如Avro,這可以隨時間推移改進模式。 通過在結構中粘貼版本號,你可以靈活地轉移到任何一種新的數(shù)據(jù)格式,并使用目錄路徑傳達不同的文件格式。
在目錄中放置版本號面臨的唯一挑戰(zhàn)是如何將更改有效傳達給數(shù)據(jù)使用者。如果確實有該問題,企業(yè)可以嘗試將HCatalog視為從客戶端抽象出的一種數(shù)據(jù)格式。
按日期和其他字段進行分區(qū)
你可能會使用目錄結構來模擬企業(yè)不同部門的數(shù)據(jù)演變需求,但為什么還需要按日期進一步分區(qū)?這是Hive早期使用的一種技術,可以幫助加快查詢速度。如果將所有數(shù)據(jù)放入一個目錄中,那么每次訪問數(shù)據(jù)實際都在進行等效的Hadoop全表掃描。相反,根據(jù)對數(shù)據(jù)的訪問方式對數(shù)據(jù)進行分區(qū)更為明智。
因為我們事先很難確切知道如何訪問數(shù)據(jù),但按數(shù)據(jù)生成日期對數(shù)據(jù)進行分段是合理的分區(qū)嘗試。如果數(shù)據(jù)沒有日期,那么請與數(shù)據(jù)生產(chǎn)者討論添加日期,因為創(chuàng)建事件或記錄的時間是應始終捕獲的關鍵數(shù)據(jù)點。
4.1.2 數(shù)據(jù)層
在2012年的Strata演講中,Eric Sammer提出了對數(shù)據(jù)存儲進行分層的想法,這也很好地與Nathan Marz的Lambda架構的主要原則相關——永遠不會刪除或修改原始數(shù)據(jù)。
乍一看,這似乎沒有任何意義。因為你只需要提取數(shù)據(jù)源的重要部分,其余部分可以舍棄,畢竟保留全部原始數(shù)據(jù)有些浪費,特別是如果有部分未被積極使用,但你很難保證未來堅決不會從未使用的數(shù)據(jù)中提取到有價值的信息。
我們的軟件偶爾也會出現(xiàn)錯誤。想象一下,如果你正在軟件中傳輸數(shù)據(jù),獲得想要的結果之后,你決定丟棄源數(shù)據(jù),但是你突然發(fā)現(xiàn)操作邏輯中存在錯誤,因為丟棄了源數(shù)據(jù)將無法返回并重新生成結果。
因此,建議企業(yè)根據(jù)以下層級考慮數(shù)據(jù)存儲:
原始數(shù)據(jù)是第一層。這是從源捕獲的未更改數(shù)據(jù),永遠不應修改此層數(shù)據(jù),因為生成衍生物或聚合的邏輯可能存在錯誤,如果丟棄原始數(shù)據(jù),則無法在發(fā)生錯誤時恢復。
第二層:從原始數(shù)據(jù)創(chuàng)建派生數(shù)據(jù)。該層,你可以執(zhí)行重復數(shù)據(jù)刪除和任何其他數(shù)據(jù)治理要求。
第三層:匯總數(shù)據(jù)。這是根據(jù)派生數(shù)據(jù)計算出來的,可能會被輸入HBase系統(tǒng)或選擇的NoSQL系統(tǒng),以便在生產(chǎn)和分析過程中實時訪問數(shù)據(jù)。
數(shù)據(jù)層也應該在目錄布局中有所展示,以便用戶可以輕松區(qū)分這些層。
一旦確定了用于對數(shù)據(jù)進行分區(qū)的目錄布局,下一步就是弄清楚如何將數(shù)據(jù)導入這些分區(qū)。
4.1.3 分區(qū)
分區(qū)是獲取數(shù)據(jù)集并將其拆分為不同部分的過程。這些部分是分區(qū),代表了對數(shù)據(jù)的有意義劃分。數(shù)據(jù)中的公共分區(qū)示例是時間,因為它允許查詢數(shù)據(jù)的人在特定的時間窗口內縮小范圍。4.1.2節(jié)將時間作為決定在HDFS中布局數(shù)據(jù)的關鍵因素。
如果在HDFS中有一個大型數(shù)據(jù)集,需要對其進行分區(qū),應該怎么做呢?本節(jié)將介紹兩種可用于對數(shù)據(jù)進行分區(qū)的方法。
使用MultipleOutputs對數(shù)據(jù)進行分區(qū)
想象一下,你將股票價格數(shù)據(jù)流入HDFS,并且希望編寫MapReduce作業(yè),以根據(jù)當天的股票報價對數(shù)據(jù)進行分區(qū)。為此,你需要在單個任務中寫入多個輸出文件,讓我們來看看如何實現(xiàn)這一目標。
問題
需要對數(shù)據(jù)進行分區(qū),但大多數(shù)輸出格式僅為每個任務創(chuàng)建一個輸出文件。
解決方案
使用與MapReduce捆綁在一起的MultipleOutputs類。
討論
Hadoop中的MultipleOutputs類繞過了在Hadoop中生成輸出的正常通道。它提供了一個單獨的API來寫入分區(qū)輸出,并將輸出直接寫入HDFS中的任務嘗試目錄,這可以繼續(xù)提供給作業(yè)的Context對象的標準write方法來收集輸出,還可以使用MultipleOutputs來編寫分區(qū)輸出。當然,你也可以選擇僅使用MultipleOutputs類并忽略標準的基于上下文的輸出。
在此技術中,你將使用MultipleOutputs按報價日期對股票進行分區(qū)。第一步是設置MultipleOutputs以便在工作中使用。 在驅動程序中,你將指明輸出格式以及鍵和值類型:
為什么需要在驅動程序中命名輸出?你可能想知道為什么MultipleOutputs要求指定輸出名稱(前面示例中的分區(qū))。這是因為MultipleOutputs支持兩種操作模式 - 靜態(tài)分區(qū)和動態(tài)分區(qū)。
如果提前知道分區(qū)名稱,靜態(tài)分區(qū)可以正常工作,這為每個分區(qū)指定不同輸出的格式提供了額外的靈活性(只需要對具有不同命名輸出的MultipleOutputs.addNamedOutput進行多次調用)。對于靜態(tài)分區(qū),在調用addNamedOutput時指定的輸出名稱與在mapper或reducer中發(fā)出輸出時使用的名稱相同。
命名輸出主要針對于動態(tài)分區(qū),因為在大多數(shù)情況下,操作者不會提前知道分區(qū)名稱。在這種情況下,仍然需要提供輸出名稱,當然這也可能被忽略,因為可以在mapper或reducer中動態(tài)指定分區(qū)名稱。
正如以下代碼所示,map(或reduce)類將獲取MultipleOutputs實例的句柄,然后使用write方法寫入分區(qū)輸出。請注意,第三個參數(shù)是分區(qū)名稱,即股票日期:
不要忘記close()方法! 在任務完成后調用MultipleOutputs上的close方法非常重要。否則,輸出可能會丟失數(shù)據(jù),甚至造成文件損壞。
正如你在以下輸出中所看到的,運行上一個示例會為單個mapper生成許多分區(qū)文件。我們還可以看到原始map輸出文件,該文件為空,因為沒有使用Context對象發(fā)出任何記錄:
此示例使用了僅map作業(yè),但在生產(chǎn)中,你可能希望限制創(chuàng)建分區(qū)的任務數(shù)。有兩種方法可以做到這一點:
使用CombineFileInputFormat或自定義輸入格式來限制作業(yè)中的mapper數(shù)量。
使用reducer明確指定合理數(shù)量的reducer。
總結
MultipleOutputs有很多值得關注的東西:它支持“舊”和“新”MapReduce API,并支持多種輸出格式類。但是,使用MultipleOutputs應該注意一些問題:
在mapper中使用MultipleOutput時請記住,最終會得到NumberOfMappers * NumberOfPartition輸出文件,根據(jù)經(jīng)驗,這會降低具有大量兩個值的集群!
每個分區(qū)在任務期間都會產(chǎn)生HDFS文件句柄開銷。
你經(jīng)常會遇到大量小文件,這些文件會在分區(qū)程序的多次使用中累積。當然,這可以采用壓縮策略來緩解(有關詳細信息,請參閱第4.1.4節(jié))。
盡管Avro附帶了AvroMultipleOutputs類,但由于代碼效率低下,速度很慢。
除了MultipleOutputs方法之外,Hadoop還附帶了一個MultipleOutputFormat類,其功能類似于MultipleOutputs,主要缺陷是只支持舊的MapReduce API,并且只有一種輸出格式可用于所有分區(qū)。
我們可以使用的另一種分區(qū)策略是MapReduce分區(qū)程序,它可以幫助減輕可能使用MultipleOutputs生成的大量文件。
使用自定義MapReduce分區(qū)程序
另一種分區(qū)方法是使用MapReduce中內置的分區(qū)工具。默認情況下,MapReduce使用分區(qū)程序來計算每個map輸出鍵的散列,并對reducer的數(shù)量執(zhí)行計數(shù)以確定應將記錄發(fā)送到哪個reducer。我們可以編寫自定義分區(qū)程序,然后根據(jù)分區(qū)方案路由記錄來控制分區(qū)生成方式。
這種技術比以前的技術有額外的好處,因為通常會得到更少的輸出文件,每個reducer只會創(chuàng)建一個輸出文件,而MultipleOutputs則每個map或reduce任務都會產(chǎn)生N個輸出文件,每個分區(qū)一個。
問題
對輸入數(shù)據(jù)進行分區(qū)。
解決方案
編寫自定義分區(qū)程序,將記錄分區(qū)到適當?shù)膔educer。
討論
自定義分區(qū)器可向MapReduce驅動程序公開輔助方法,允許定義從日期到分區(qū)的map,并將此map寫入作業(yè)配置。然后,當MapReduce加載分區(qū)器時,MapReduce調用setConf方法; 在分區(qū)器中,我們將讀取mapping到map中,隨后在分區(qū)時使用。
驅動程序代碼需要設置自定義分區(qū)程序配置。此示例中的分區(qū)是日期,如果希望確保每個reducer對應唯一的日期。股票示例數(shù)據(jù)有10個唯一日期,因此可以使用10個reducer配置作業(yè),還可以調用先前定義的分區(qū)幫助程序函數(shù)設置將每個唯一日期map到唯一reducer配置。
除了從輸入數(shù)據(jù)中提取股票日期并將其作為輸出key之外,mapper幾乎沒有其他功能:
運行前面示例的命令如下:
此作業(yè)將生成10個輸出文件,每個文件包含當天的股票信息。
總結
使用MapReduce框架自然地對數(shù)據(jù)進行分區(qū)可以帶來以下幾個優(yōu)點:
對分區(qū)中的數(shù)據(jù)進行排序,因為shuffle將確保對流式傳輸?shù)絩educer的所有數(shù)據(jù)進行排序,這允許對數(shù)據(jù)使用優(yōu)化的連接策略。
可以對reducer中的數(shù)據(jù)進行重復數(shù)據(jù)刪除,這也是shuffle階段的一個好處。
使用這種技術需要注意的主要問題是數(shù)據(jù)偏差,如果希望確保盡可能地將負載分散到reducer上,數(shù)據(jù)會存在自然偏差,這可能是一個問題。例如,如果分區(qū)是天數(shù),那么大多數(shù)記錄可能是一天,而可能只有一些記錄可用于前一天或后一天。 在這種情況下,理想情況是將大多數(shù)Reducer分配到一天對記錄進行分區(qū),然后可能在前一天或后一天分配一兩個記錄,也可以對輸入進行采樣,并根據(jù)樣本數(shù)據(jù)動態(tài)確定最佳reducer數(shù)量。
生成分區(qū)輸出后,下一個挑戰(zhàn)是處理分區(qū)產(chǎn)生的大量潛在小文件。
4.1.4 數(shù)據(jù)壓縮
在HDFS中有小文件是無法避免的,也許你正在使用類似于前面描述的分區(qū)技術,或者數(shù)據(jù)可能以小文件大小有機地落在HDFS中。 無論哪種方式,都將暴露HDFS和MapReduce的一些弱點,比如:
Hadoop的NameNode將所有HDFS元數(shù)據(jù)保留在內存中,以實現(xiàn)快速元數(shù)據(jù)操作。雅虎估計每個文件平均占用內存600字節(jié)的空間,轉換為10億個文件的元數(shù)據(jù)開銷,總計60 GB,所有文件都需要存儲在NameNode內存中。即使是當今的中端服務器RAM容量,這也代表著單個進程的大量內存。
如果對MapReduce作業(yè)的輸入是大量文件,則將運行的mapper數(shù)量(假設文件是文本或可拆分的)將等于這些文件占用的塊數(shù)。如果運行一個輸入數(shù)千或數(shù)百萬個文件的MapReduce作業(yè),那么將花費更多時間在內核層處理創(chuàng)建和銷毀map任務流程,而不是實際工作。
最后,如果在具有調度程序的受控環(huán)境中運行,則可能會限制MapReduce作業(yè)可以使用的任務數(shù)。由于每個文件(默認情況下)至少會生成一個map任務,因此這可能會導致作業(yè)被調度程序拒絕。
如果認為不會有這個問題,那就再想一想,文件百分比小于HDFS塊大小嗎?小多少?50%?70%?還是90%?如果大數(shù)據(jù)項目突然需要擴展以處理大幾個數(shù)量級的數(shù)據(jù)集,該怎么辦?這不是你首先使用Hadoop的原因嗎?擴展就要添加更多節(jié)點,企業(yè)肯定不接受重新設計Hadoop并處理遷移文件。因此,在設計階段最好盡早思考和準備這些可能的問題。
本節(jié)介紹了一些可用于在HDFS中組合數(shù)據(jù)的技術。首先討論一個名為filecrush的實用程序,它可以將小文件壓縮在一起以創(chuàng)建較少數(shù)量的較大文件。
使用filecrush壓縮數(shù)據(jù)
壓縮是將小文件組合在一起生成更大文件的行為,這有助于緩解NameNode上的堆壓力。
就與Hadoop版本的兼容性而言,filecrush實用程序僅適用于Hadoop版本1。但是compacter(https://github.com/alexholmes/hdfscompact)以及Archive與Hadoop 版本2兼容。
問題
希望壓縮小文件以減少NameNode需要保留在內存中的元數(shù)據(jù)
解決方案
使用filecrush實用程序。
討論
filecrush實用程序組合或壓縮多個小文件以形成更大的文件。該實用程序非常復雜,并能夠
確定壓縮文件的大小閾值(并通過關聯(lián),保留足夠大的文件)
指定壓縮文件的大大小
使用不同的輸入和輸出格式以及不同的輸入和輸出壓縮編解碼器(用于移動到不同的文件格式或壓縮編解碼器)
使用較新的壓縮文件交換較小的文件
我們在一個簡單示例中使用filecrush ,粉碎一個小文本文件的目錄,并用gzipped SequenceFiles替換。
首先,在HDFS目錄人為創(chuàng)建10個輸入文件:
運行filecrush,此示例使用新的大文件替換小文件,并將文本文件轉換為壓縮的SequenceFile:
運行filecrush后會發(fā)現(xiàn)輸入目錄中的文件已被單個SequenceFile替換:
還可以運行文本Hadoop命令來查看SequenceFile的文本表示:
你會注意到原始的小文件已全部移動到命令中指定的輸出目錄:
如果在沒有--clone選項的情況下運行filecrush,則輸入文件將保持不變,并且已壓碎的文件將被寫入輸出目錄。
輸入和輸出文件大小閾值
filecrush如何確定文件是否需要粉碎?通過查看輸入目錄中的每個文件,并將其與塊大小進行比較(在Hadoop 2中,可以在-Ddfs.block.size命令中指定大小)。如果文件小于塊大小的75%,則會被壓縮??梢酝ㄟ^--threshold參數(shù)自定義此閾值,例如,如果需要將值提高到85%,則指定--threshold 0.85。
同樣,filecrush使用塊大小來確定輸出文件大小。默認情況下,它不會創(chuàng)建占用超過八個塊的輸出文件,但可以使用--max-file-blocks參數(shù)進行自定義。
總結
Filecrush是一種將小文件組合在一起的簡單快捷的方法。只要存在關聯(lián)的輸入格式和輸出格式類,就支持任何類型的輸入或輸出文件。遺憾的是,它不能與Hadoop 2一起使用,并且在過去幾年中項目中沒有太多變化,因此可能企業(yè)不會考慮該程序。
因為filecrush需要輸入和輸出格式,所以如果正在處理二進制數(shù)據(jù)并且需要一種將小二進制文件組合在一起的方法,那么它顯然還有不足之處。
使用Avro存儲多個小型二進制文件
假設正在開發(fā)一個類似于Google圖像的項目,可以在其中抓取網(wǎng)頁并從網(wǎng)站下載圖像文件,該項目是互聯(lián)網(wǎng)規(guī)模,因此下載了數(shù)百萬個文件并將它們單獨存儲在HDFS中。你已經(jīng)知道HDFS不能很好地處理大量小文件,因此我們嘗試一下Avro。
問題
希望在HDFS中存儲大量二進制文件,并且無需遵守NameNode內存限制即可。
解決方案
在HDFS中處理小型二進制文件的最簡單方法是將其打包到一個更大的文件中。此技術將讀取存儲在本地磁盤目錄中的所有文件,并將它們保存在HDFS的單個Avro文件中。你還將了解如何使用MapReduce中的Avro文件來處理原始文件內容。
討論
圖4.2顯示了該技術的第一部分,可以創(chuàng)建HDFS中的Avro文件。這樣做可以在HDFS中創(chuàng)建更少的文件,這意味著存儲在NameNode內存中的數(shù)據(jù)更少,這也意味著可以存儲更多內容。
圖4.2 在Avro中存儲小文件以允許存儲更多文件
Avro是由Hadoop的創(chuàng)建者Doug Cutting發(fā)明的數(shù)據(jù)序列化和RPC庫。Avro具有強大的架構演進功能,其優(yōu)勢已經(jīng)超過競爭對手,比如SequenceFile等,第3章詳細介紹了這一內容,此處不再贅述。
請查看以下Java代碼,該代碼將創(chuàng)建Avro文件:
代碼4.1讀取包含小文件的目錄,并在HDFS中生成單個Avro文件
要運行本章代碼需要在主機上安裝Snappy和LZOP壓縮編解碼器。有關如何安裝和配置它們的詳細信息,此處不作贅述。
當針對Hadoop的config目錄運行此腳本時會發(fā)生什么(將$ HADOOP_CONF_DIR替換為包含Hadoop配置文件的目錄):
讓我們確保輸出文件是HDFS:
為確保一切正常運行,還可以編寫代碼以從HDFS讀取Avro文件,并為每個文件的內容輸出MD5哈希值:
此代碼比寫入更簡單。由于Avro將架構寫入每個Avro文件,因此無需在反序列化過程中向Avro提供有關架構的信息:
此時,我們已經(jīng)在HDFS中擁有了Avro文件。盡管本章是關于HDFS的,但可能要做的下一件事是處理在MapReduce中編寫的文件。這需要編寫一個Map-only MapReduce作業(yè),它可以讀取Avro記錄作為輸入,并輸出一個包含文件名和文件內容的MD5哈希值的文本文件,如圖4.3所示。
圖4.3 map作業(yè)讀取Avro文件并輸出文本文件
以下顯示了此MapReduce作業(yè)的代碼:
代碼4.2 一個MapReduce作業(yè),包含小文件的Avro文件作為輸入
如果通過之前創(chuàng)建的Avro文件運行此MapReduce作業(yè),則作業(yè)日志文件將包含文件名和哈希:
該技術假設使用的文件格式(例如圖像文件)無法將單獨的文件連接在一起。如果文件可以連接,應該考慮該選項。采用該方法請盡量確保文件大小與HDFS塊一樣,以大限度減少存儲在NameNode中的數(shù)據(jù)。
總結
我們可以使用Hadoop的SequenceFile作為保存小文件的機制。SequenceFile是一種比較成熟的技術,比Avro文件更成熟。但是SequenceFiles是特定于Java的,并且不提供Avro帶來的豐富的互操作性和版本控制語義。
谷歌的Protocol Buffers以及Apache Thrift(源自Facebook)也可用于存儲小文件。 但是都沒有適用于本機Thrift或Protocol Buffers文件的輸入格式。我們也可以使用另一種方法就是將文件寫入zip文件。缺點是必須編寫自定義輸入格式來處理zip文件,其次是zip文件不可拆分(與Avro文件和SequenceFiles相反)。這可以通過生成多個zip文件并嘗試使它們接近HDFS塊大小來減輕。Hadoop還有一個CombineFileInputFormat,可以將多個輸入拆分(跨多個文件)提供給單個map任務,這大大減少了運行所需的map任務數(shù)量。
我們還可以創(chuàng)建一個包含所有文件的tarball文件,生成一個單獨的文本文件,其中包含HDFS中tarball文件的位置。此文本文件將作為MapReduce作業(yè)的輸入提供,mapper將直接打開tarball。但是,這種方法會繞過MapReduce的局部性,因為mapper將被安排在包含文本文件的節(jié)點上執(zhí)行,因此可能需要從遠程HDFS節(jié)點讀取tarball塊,從而導致不必要的網(wǎng)絡I/O。
Hadoop歸檔文件(HAR)是專門為解決小文件問題而創(chuàng)建的,是位于HDFS之上的虛擬文件系統(tǒng)。HAR文件的缺點是無法針對MapReduce中的本地磁盤訪問進行優(yōu)化,并且無法進行壓縮。Hadoop版本2支持HDFS Federation,其中HDFS被劃分為多個不同的命名空間,每個命名空間由一個單獨的NameNode獨立管理。實際上,這意味著將塊信息保存在內存中的總體影響可以分布在多個NameNode上,從而支持更多數(shù)量的小文件。
最后,提供Hadoop發(fā)行版的MapR擁有自己的分布式文件系統(tǒng),支持大量小文件。將MapR用于分布式存儲對系統(tǒng)來說需要很大改變,因此,企業(yè)不太可能轉移到MapR來緩解HDFS的這個問題。你可能會遇到想要在Hadoop中處理小文件的時間,并且直接使用它們會導致膨脹的NameNode內存和運行緩慢的MapReduce作業(yè)。此技術通過將小文件打包到更大的容器文件中來幫助緩解這些問題。我之所以選擇Avro是因為它支持可拆分文件,壓縮及其富有表現(xiàn)力的架構語言,這將有助于版本控制。如果文件很大,想要更有效地存儲應該怎么辦呢?這將在第4.2節(jié)得到解決。
4.1.5原子數(shù)據(jù)移動
分區(qū)和壓縮等行為往往遵循類似的模式,比如在暫存目錄中生成輸出文件,然后需要在成功暫存所有輸出文件后以原子方式移動到最終目標目錄。這可能會帶來一些問題:
使用什么觸發(fā)器來確定已準備好執(zhí)行原子移動?
如何在HDFS中原子移動數(shù)據(jù)?
數(shù)據(jù)移動對最終數(shù)據(jù)讀者有何影響?
使用MapReduce驅動程序作為后處理步驟執(zhí)行原子移動可能很好,但如果客戶端進程在MapReduce應用程序完成之前死亡會發(fā)生什么?這是在Hadoop中使用OutputCommitter非常有用的地方,因為可以將任何原子文件移動作為工作的一部分,而不是使用驅動程序。
接下來的問題是如何在HDFS中原子移動數(shù)據(jù)。在最長的時間內,人們認為DistributedFileSystem類(這是支持HDFS的具體實現(xiàn))上的重命名方法是原子的。但事實證明,在某些情況下,這不是原子操作。這在HADOOP-6240中得到了解決,但出于向后兼容性原因,重命名方法未更新。因此,重命名方法仍然不是真正的原子。相反,你需要使用新的API。如下所示,代碼很麻煩,只適用于較新版本的Hadoop:
HDFS缺少的是原子交換目錄能力,這在壓縮等情況下非常有用。因為在這些情況下,你需要替換其他進程(如Hive)正在使用的目錄的全部內容。有一個名為““Atomic Directory Swapping Operation”的項目可能有對你有些幫助。
以上是“怎么在HDFS中組織和使用數(shù)據(jù)”這篇文章的所有內容,感謝各位的閱讀!相信大家都有了一定的了解,希望分享的內容對大家有所幫助,如果還想學習更多知識,歡迎關注創(chuàng)新互聯(lián)-成都網(wǎng)站建設公司行業(yè)資訊頻道!