溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

MapReuce中對(duì)大數(shù)據(jù)處理最合適的數(shù)據(jù)格式是什么?

發(fā)布時(shí)間:2020-07-27 21:51:39 來源:網(wǎng)絡(luò) 閱讀:389 作者:首席數(shù)據(jù)師 欄目:大數(shù)據(jù)

本節(jié)作為《Hadoop從入門到精通》大型專題的第三章第二節(jié)將教大家如何在Mapreduce中使用XML和JSON兩大常見格式,并分析比較最適合Mapreduce大數(shù)據(jù)處理的數(shù)據(jù)格式。

在本章的第一章節(jié)介紹中,我們簡(jiǎn)單了解了Mapreduce數(shù)據(jù)序列化的概念,以及其對(duì)于XML和JSON格式并不友好。本節(jié)作為《Hadoop從入門到精通》大型專題的第三章第二節(jié)將教大家如何在Mapreduce中使用XML和JSON兩大常見格式,并分析比較最適合Mapreduce大數(shù)據(jù)處理的數(shù)據(jù)格式。

MapReuce中對(duì)大數(shù)據(jù)處理最合適的數(shù)據(jù)格式是什么?

3.2.1 XML

XML自1998年誕生以來就作為一種數(shù)據(jù)格式來表示機(jī)器和人類都可讀的數(shù)據(jù)。它成為系統(tǒng)之間數(shù)據(jù)交換的通用語言,現(xiàn)在被許多標(biāo)準(zhǔn)所采用,例如SOAP和RSS,并且被用作Microsoft Office等產(chǎn)品的開放數(shù)據(jù)格式。

MapReduce和XML

MapReduce捆綁了與文本一起使用的InputFormat,但沒有支持XML,也就是說,原生Mapreduce對(duì)XML十分不友好。在MapReduce中并行處理單個(gè)XML文件很棘手,因?yàn)閄ML不包含其數(shù)據(jù)格式的同步標(biāo)記。

問題

希望在MapReduce中使用大型XML文件,并能夠并行拆分和處理。

解決方案

Mahout的XMLInputFormat可用于MapReduce處理HDFS中的XML文件。 它讀取由特定XML開始和結(jié)束標(biāo)記分隔的記錄,此技術(shù)還解釋了如何在MapReduce中將XML作為輸出發(fā)送。

MapReduce不包含對(duì)XML的內(nèi)置支持,因此我們轉(zhuǎn)向另一個(gè)Apache項(xiàng)目——Mahout,一個(gè)提供XML InputFormat的機(jī)器學(xué)習(xí)系統(tǒng)。 要了解XML InputFormat,你可以編寫一個(gè)MapReduce作業(yè),該作業(yè)使用Mahout的XML輸入格式從Hadoop的配置文件(HDFS)中讀取屬性名稱和值。

第一步是對(duì)作業(yè)進(jìn)行配置:

Mahout的XML輸入格式很簡(jiǎn)陋,我們需要指定文件搜索的確切開始和結(jié)束XML標(biāo)記,并使用以下方法拆分文件(并提取記錄):

文件沿著HDFS塊邊界分成不連續(xù)的部分,用于數(shù)據(jù)本地化。

每個(gè)map任務(wù)都在特定的輸入拆分上運(yùn)行,map任務(wù)尋求輸入拆分的開始,然后繼續(xù)處理文件,直到第一個(gè)xmlinput.start。

重復(fù)發(fā)出xmlinput.start和xmlinput.end之間的內(nèi)容,直到輸入拆分的末尾。

接下來,你需要編寫一個(gè)映射器來使用Mahout的XML輸入格式。Text表單已提供XML元素,因此需要使用XML解析器從XML中提取內(nèi)容。

表3.1 使用Java的STAX解析器提取內(nèi)容

該map具有一個(gè)Text實(shí)例,該實(shí)例包含start和end標(biāo)記之間數(shù)據(jù)的String表示。在此代碼中,我們可以使用Java的內(nèi)置Streaming API for XML(StAX)解析器提取每個(gè)屬性的鍵和值并輸出。

如果針對(duì)Cloudera的core-site.xml運(yùn)行MapReduce作業(yè)并使用HDFS cat命令顯示輸出,將看到以下內(nèi)容:

此輸出顯示已成功使用XML作為MapReduce的輸入序列化格式。不僅如此,還可以支持巨大的XML文件,因?yàn)檩斎敫袷街С植鸱諼ML。

寫XML

當(dāng)可以正常讀XML之后,我們要解決的就是如何寫XML。 在reducer中,調(diào)用main reduce方法之前和之后都會(huì)發(fā)生回調(diào),可以使用它來發(fā)出開始和結(jié)束標(biāo)記,如下所示。

表3.2 用于發(fā)出開始和結(jié)束標(biāo)記的reducer

這也可以嵌入到OutputFormat中。

Pig

如果想在Pig中使用XML,Piggy Bank library(用戶貢獻(xiàn)的Pig代碼庫)包含一個(gè)XMLLoader。其工作方式與此技術(shù)非常相似,可捕獲開始和結(jié)束標(biāo)記之間的所有內(nèi)容,并將其作為Pig元組中的單字節(jié)數(shù)組字段提供。

Hive

目前沒有辦法在Hive中使用XML,必須寫一個(gè)自定義SerDe。

總結(jié)

Mahout的XmlInputFormat可幫助使用XML,但它對(duì)開始和結(jié)束元素名稱的精確字符串匹配很敏感。如果元素標(biāo)記包含具有變量值的屬性,無法控制元素生成或者可能導(dǎo)致使用XML命名空間限定符,則此方法不可用。

如果可以控制輸入中的XML,則可以通過在每行使用單個(gè)XML元素來簡(jiǎn)化此練習(xí)。這允許使用內(nèi)置的MapReduce基于文本的輸入格式(例如TextInputFormat),它將每一行視為記錄并拆分。

值得考慮的另一個(gè)選擇是預(yù)處理步驟,可以將原始XML轉(zhuǎn)換為每個(gè)XML元素的單獨(dú)行,或者將其轉(zhuǎn)換為完全不同的數(shù)據(jù)格式,例如SequenceFile或Avro,這兩種格式都解決了拆分問題。

現(xiàn)在,你已經(jīng)了解如何使用XML,讓我們來處理另一種流行的序列化格式JSON。

3.2.2 JSON

JSON共享XML的機(jī)器和人類可讀特征,并且自21世紀(jì)初以來就存在。它比XML簡(jiǎn)潔,但是沒有XML中豐富的類型和驗(yàn)證功能。

如果有一些代碼正在從流式REST服務(wù)中下載JSON數(shù)據(jù),并且每小時(shí)都會(huì)將文件寫入HDFS。由于下載的數(shù)據(jù)量很大,因此生成的每個(gè)文件大小為數(shù)千兆字節(jié)。

如果你被要求編寫一個(gè)MapReduce作業(yè),需要將大型JSON文件作為輸入。你可以將問題分為兩部分:首先,MapReduce沒有與JSON一起使用的InputFormat; 其次,如何分割JSON?

圖3.7顯示了拆分JSON問題。 想象一下,MapReduce創(chuàng)建了一個(gè)拆分,如圖所示。對(duì)此輸入拆分進(jìn)行操作的map任務(wù)將執(zhí)行對(duì)輸入拆分的搜索,以確定下一條記錄的開始。對(duì)于諸如JSON和XML之類的文件格式,由于缺少同步標(biāo)記或任何其他標(biāo)識(shí)記錄開頭,因此知道下一條記錄何時(shí)開始是很有挑戰(zhàn)性的。

JSON比XML等格式更難分割成不同的段,因?yàn)镴SON沒有token(如XML中的結(jié)束標(biāo)記)來表示記錄的開頭或結(jié)尾。

問題

希望在MapReduce中使用JSON輸入,并確??梢詾椴l(fā)讀取分區(qū)輸入JSON文件。

解決方案

Elephant Bird LzoJsonInputFormat被用來作為創(chuàng)建輸入格式類以使用JSON元素的基礎(chǔ),該方法可以使用多行JSON。

圖3.7 使用JSON和多個(gè)輸入拆分的問題示例

討論

Elephant Bird(https://github.com/kevinweil/elephant-bird)是一個(gè)開源項(xiàng)目,包含用于處理LZOP壓縮的有用程序,它有一個(gè)可讀取JSON的LzoJsonInputFormat,盡管要求輸入文件是LZOP-compressed。,但可以將Elephant Bird代碼用作自己的JSON InputFormat模板,該模板不具有LZOP compression要求。

此解決方案假定每個(gè)JSON記錄位于單獨(dú)的行上。JsonRecordFormat很簡(jiǎn)單,除了構(gòu)造和返回JsonRecordFormat之外什么也沒做,所以我們將跳過該代碼。JsonRecordFormat向映射器發(fā)出LongWritable,MapWritable key/value,其中MapWritable是JSON元素名稱及其值的映射。

我們來看看RecordReader的工作原理,它使用LineRecordReader,這是一個(gè)內(nèi)置的MapReduce讀取器。要將該行轉(zhuǎn)換為MapWritable,讀取器使用json-simple解析器將該行解析為JSON對(duì)象,然后迭代JSON對(duì)象中的鍵并將它們與其關(guān)聯(lián)值一起放到MapWritable。映射器在LongWritable中被賦予JSON數(shù)據(jù),MapWritable pairs可以相應(yīng)地處理數(shù)據(jù)。

以下顯示了JSON對(duì)象示例:

該技巧假設(shè)每行一個(gè)JSON對(duì)象,以下代碼顯示了在此示例中使用的JSON文件:

現(xiàn)在將JSON文件復(fù)制到HDFS并運(yùn)行MapReduce代碼。MapReduce代碼寫入每個(gè)JSON key/value對(duì)并輸出:

寫JSON

類似于3.2.1節(jié),編寫XML的方法也可用于編寫JSON。

Pig

Elephant Bird包含一個(gè)JsonLoader和LzoJsonLoader,可以使用它來處理Pig中的JSON,這些加載器使用基于行的JSON。每個(gè)Pig元組都包含該行中每個(gè)JSON元素的chararray字段。

Hive

Hive包含一個(gè)可以序列化JSON的DelimitedJSONSerDe類,但遺憾的是無法對(duì)其進(jìn)行反序列化,因此無法使用此SerDe將數(shù)據(jù)加載到Hive中。

總結(jié)

此解決方案假定JSON輸入的結(jié)構(gòu)為每個(gè)JSON對(duì)象一行。那么,如何使用跨多行的JSON對(duì)象?GitHub上有一個(gè)項(xiàng)目( https://github.com/alexholmes/json-mapreduce)可以在單個(gè)JSON文件上進(jìn)行多個(gè)輸入拆分,此方法可搜索特定的JSON成員并檢索包含的對(duì)象。

你可以查看名為hive-json-serde的Google項(xiàng)目,該項(xiàng)目可以同時(shí)支持序列化和反序列化。

正如你所看到的,在MapReduce中使用XML和JSON是非常糟糕的,并且對(duì)如何布局?jǐn)?shù)據(jù)有嚴(yán)格要求。MapReduce對(duì)這兩種格式的支持也很復(fù)雜且容易出錯(cuò),因?yàn)樗鼈儾贿m合拆分。顯然,需要查看具有內(nèi)部支持且可拆分的替代文件格式。

下一步是研究更適合MapReduce的復(fù)雜文件格式,例如Avro和SequenceFile。

3.3 大數(shù)據(jù)序列化格式

當(dāng)使用scalar或tabular數(shù)據(jù)時(shí),非結(jié)構(gòu)化文本格式很有效。諸如XML和JSON之類的半結(jié)構(gòu)化文本格式可以對(duì)包括復(fù)合字段或分層數(shù)據(jù)的復(fù)雜數(shù)據(jù)結(jié)構(gòu)進(jìn)行建模。但是,當(dāng)處理較大數(shù)據(jù)量時(shí),我們更需要具有緊湊序列化表單的序列化格式,這些格式本身支持分區(qū)并具有模式演變功能。

在本節(jié)中,我們將比較最適合MapReduce大數(shù)據(jù)處理的序列化格式,并跟進(jìn)如何將它們與MapReduce一起使用。

3.3.1 比較SequenceFile,Protocol Buffers,Thrift和Avro

根據(jù)經(jīng)驗(yàn),在選擇數(shù)據(jù)序列化格式時(shí),以下特征非常重要:

代碼生成——某些序列化格式具有代碼生成作用的庫,允許生成豐富的對(duì)象,使更容易與數(shù)據(jù)交互。生成的代碼還提供了類似安全性等額外好處,以確保消費(fèi)者和生產(chǎn)者使用正確的數(shù)據(jù)類型。

架構(gòu)演變 - 數(shù)據(jù)模型隨著時(shí)間的推移而發(fā)展,重要的是數(shù)據(jù)格式支持修改數(shù)據(jù)模型的需求。模式演變功能允許你添加、修改并在某些情況下刪除屬性,同時(shí)為讀和寫提供向后和向前兼容性。

語言支持 - 可能需要使用多種編程語言訪問數(shù)據(jù),主流語言支持?jǐn)?shù)據(jù)格式非常重要。

數(shù)據(jù)壓縮 - 數(shù)據(jù)壓縮非常重要,因?yàn)榭梢允褂么罅繑?shù)據(jù)。并且,理想的數(shù)據(jù)格式能夠在寫入和讀取時(shí)內(nèi)部壓縮和解壓縮數(shù)據(jù)。如果數(shù)據(jù)格式不支持壓縮,那么對(duì)于程序員而言,這是一個(gè)很大的問題,因?yàn)檫@意味著必須將壓縮和解壓縮作為數(shù)據(jù)管道的一部分進(jìn)行管理(就像使用基于文本的文件格式一樣)。

可拆分性 - 較新的數(shù)據(jù)格式支持多個(gè)并行讀取器,可讀取和處理大型文件的不同塊。文件格式包含同步標(biāo)記至關(guān)重要(可隨機(jī)搜索和掃描到下一條記錄開頭)。

支持MapReduce和Hadoop生態(tài)系統(tǒng) - 選擇的數(shù)據(jù)格式必須支持MapReduce和其他Hadoop生態(tài)系統(tǒng)關(guān)鍵項(xiàng)目,例如Hive。如果沒有這種支持,你將負(fù)責(zé)編寫代碼以使文件格式適用于這些系統(tǒng)。

表3.1比較了流行的數(shù)據(jù)序列化框架,以了解它們?nèi)绾蜗嗷クB加。以下討論提供了有關(guān)這些技術(shù)的其他背景知識(shí)。

表3.1數(shù)據(jù)序列化框架的功能比較

讓我們更詳細(xì)地看一下這些格式。

SequenceFile

創(chuàng)建SequenceFile格式是為了與MapReduce、Pig和Hive一起使用,因此可以很好地與所有工具集成。缺點(diǎn)主要是缺乏代碼生成和版本控制支持,以及有限的語言支持。

Protocol Buffers

Protocol Buffers 已被Google大量用于互操作,其優(yōu)勢(shì)在于其版本支持二進(jìn)制格式。缺點(diǎn)是MapReduce(或任何第三方軟件)缺乏對(duì)讀取Protocol Buffers 序列化生成的文件支持。但是,Elephant Bird可以在容器文件中使用Protocol Buffers序列化。

Thrift

Thrift是Facebook內(nèi)部開發(fā)的數(shù)據(jù)序列化和RPC框架,在本地?cái)?shù)據(jù)序列化格式中不支持MapReduce,但可以支持不同的wire-level數(shù)據(jù)表示,包括JSON和各種二進(jìn)制編碼。 Thrift還包括具有各種類型服務(wù)器的RPC層。本章將忽略RPC功能,并專注于數(shù)據(jù)序列化。

Avro

Avro格式是Doug Cutting創(chuàng)建的,旨在幫助彌補(bǔ)SequenceFile的不足。

Parquet

Parquet是一種具有豐富Hadoop系統(tǒng)支持的柱狀文件格式,可以與Avro、Protocol Buffers和Thrift等友好工作。盡管 Parquet 是一個(gè)面向列的文件格式,不要期望每列一個(gè)數(shù)據(jù)文件。Parquet 在同一個(gè)數(shù)據(jù)文件中保存一行中的所有數(shù)據(jù),以確保在同一個(gè)節(jié)點(diǎn)上處理時(shí)一行的所有列都可用。Parquet 所做的是設(shè)置 HDFS 塊大小和最大數(shù)據(jù)文件大小為 1GB,以確保 I/O 和網(wǎng)絡(luò)傳輸請(qǐng)求適用于大批量數(shù)據(jù)。

基于上述評(píng)估標(biāo)準(zhǔn),Avro似乎最適合作為Hadoop中的數(shù)據(jù)序列化框架。SequenceFile緊隨其后,因?yàn)樗cHadoop具有內(nèi)在兼容性(它設(shè)計(jì)用于Hadoop)。

你可以在Github上查看jvm-serializers項(xiàng)目,該項(xiàng)目運(yùn)行各種基準(zhǔn)測(cè)試,以根據(jù)序列化和反序列化時(shí)間等比較文件格式。它包含Avro,Protocol Buffers和Thrift基準(zhǔn)測(cè)試以及許多其他框架。

在了解了各種數(shù)據(jù)序列化框架后,我們將在接下來幾節(jié)中專門討論這些格式。

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI