隨著企業(yè)要處理的數(shù)據(jù)量越來越大,MapReduce思想越來越受到重視,。Hadoop是MapReduce的一個開源實(shí)現(xiàn),,由于其良好的擴(kuò)展性和容錯性,已得到越來越廣泛的應(yīng)用,。Hadoop作為一個基礎(chǔ)數(shù)據(jù)處理平臺,,雖然其應(yīng)用價值已得到大家認(rèn)可,但仍存在很多問題,,以下是主要幾個: (1) Namenode/jobtracker單點(diǎn)故障,。 Hadoop采用的是master/slaves架構(gòu),該架構(gòu)管理起來比較簡單,,但存在致命的單點(diǎn)故障和空間容量不足等缺點(diǎn),,這已經(jīng)嚴(yán)重影響了Hadoop的可擴(kuò)展性。 (2) HDFS小文件問題,。在HDFS中,,任何block,文件或者目錄在內(nèi)存中均以對象的形式存儲,,每個對象約占150byte,,如果有1000 0000個小文件,每個文件占用一個block,,則namenode需要2G空間,。如果存儲1億個文件,則namenode需要20G空間,。這樣namenode內(nèi)存容量嚴(yán)重制約了集群的擴(kuò)展,。 (3) jobtracker同時進(jìn)行監(jiān)控和調(diào)度,負(fù)載過大,。為了解決該問題,,yahoo已經(jīng)開始著手設(shè)計(jì)下一代Hadoop MapReduce(見參考資料1),。他們的主要思路是將監(jiān)控和調(diào)度分離,,獨(dú)立出一個專門的組件進(jìn)行監(jiān)控,而jobtracker只負(fù)責(zé)總體調(diào)度,,至于局部調(diào)度,,交給作業(yè)所在的client。 (4) 數(shù)據(jù)處理性能,。 很多實(shí)驗(yàn)表明,,其處理性能有很大的提升空間,。Hadoop類似于數(shù)據(jù)庫,可能需要專門的優(yōu)化工程師根據(jù)實(shí)際的應(yīng)用需要對Hadoop進(jìn)行調(diào)優(yōu),,有人稱之為“Hadoop Performance Optimization” (HPO),。 為了提高其數(shù)據(jù)性能,很多人開始優(yōu)化Hadoop,??偨Y(jié)看來,對于Hadoop,,當(dāng)前主要有幾個優(yōu)化思路: (1) 從應(yīng)用程序角度進(jìn)行優(yōu)化,。由于mapreduce是迭代逐行解析數(shù)據(jù)文件的,怎樣在迭代的情況下,,編寫高效率的應(yīng)用程序,,是一種優(yōu)化思路。 (2) 對Hadoop參數(shù)進(jìn)行調(diào)優(yōu),。當(dāng)前hadoop系統(tǒng)有190多個配置參數(shù),,怎樣調(diào)整這些參數(shù),使hadoop作業(yè)運(yùn)行盡可能的快,,也是一種優(yōu)化思路,。 (3) 從系統(tǒng)實(shí)現(xiàn)角度進(jìn)行優(yōu)化。這種優(yōu)化難度是最大的,,它是從hadoop實(shí)現(xiàn)機(jī)制角度,,發(fā)現(xiàn)當(dāng)前Hadoop設(shè)計(jì)和實(shí)現(xiàn)上的缺點(diǎn),然后進(jìn)行源碼級地修改,。該方法雖難度大,,但往往效果明顯。 以上三種思路出發(fā)點(diǎn)均是提高h(yuǎn)adoop應(yīng)用程序的效率,。實(shí)際上,隨著社會的發(fā)展,,綠色環(huán)保觀念也越來越多地融入了企業(yè),,因而很多人開始研究Green Hadoop,即怎樣讓Hadoop完成相應(yīng)數(shù)據(jù)處理任務(wù)的同時,,使用最少的能源(見參考資料[14][15]),。 本文主要介紹了當(dāng)前學(xué)術(shù)界的一些優(yōu)化思路,有人試圖從Hadoop自動配置角度對Hadoop進(jìn)行優(yōu)化,,但更多的是從系統(tǒng)實(shí)現(xiàn)角度進(jìn)行優(yōu)化,,概括其優(yōu)化點(diǎn)和實(shí)驗(yàn)效果如下: (1) 論文[6]試圖從參數(shù)自動調(diào)優(yōu)角度對Hadoop進(jìn)行優(yōu)化,論文只給出了可能的解決方案,,并未給出實(shí)現(xiàn),,因而效果不可知,。但它給出了一種Hadoop優(yōu)化的新思路,即怎樣對其190多個配置參數(shù)進(jìn)行自動調(diào)整,,使應(yīng)用程序執(zhí)行效率最高,。 (2) 論文[7]提出prefetching和preshuffling機(jī)制,在不同負(fù)載不同規(guī)模集群下測試,,效率提升了約73%,。 (3) 論文[8]研究了影響Hadoop效率的五個因素,并通過提出相應(yīng)的解決方案,,使Hadoop效率提高了2.5~3.5倍,。 (4) 論文[9]為Hadoop提供了一種索引機(jī)制– Trojan Index,同時提出了一種高效的join算法– Trojan Join,,實(shí)驗(yàn)表明,,效率比Hadoop和HadoopDB高很多。 除了學(xué)術(shù)界的優(yōu)化,,工業(yè)界也在不斷進(jìn)行優(yōu)化以適應(yīng)自己公司的產(chǎn)品需要,,主要有: (1)Baidu公司。baidu對Hadoop中關(guān)鍵組件使用C++進(jìn)行了重寫(包括map, shuffler和reducer等),,經(jīng)他們內(nèi)部測試(5 nodes,,40GB data),效率提升了約20%(見參考資料[4]),。 (2)淘寶,。淘寶針對自己集群特點(diǎn)(作業(yè)小,slot多,,作業(yè)之間有依賴,,集群共享,有些作業(yè)有時效性),,對jobtracker和namenode進(jìn)行了優(yōu)化,,據(jù)其官方博客稱,其jobtracker有較大性能提升,,且namenode吞吐量提升了8+倍(見參考資料[5]),。但其具體優(yōu)化方法,未公開,。 2. 從應(yīng)用程序角度進(jìn)行優(yōu)化 (1) 避免不必要的reduce任務(wù) 如果要處理的數(shù)據(jù)是排序且已經(jīng)分區(qū)的,,或者對于一份數(shù)據(jù), 需要多次處理, 可以先排序分區(qū);然后自定義InputSplit, 將單個分區(qū)作為單個mapred的輸入,;在map中處理數(shù)據(jù), Reducer設(shè)置為空,。 這樣, 既重用了已有的 “排序”, 也避免了多余的reduce任務(wù)。 (2)外部文件引入 有些應(yīng)用程序要使用外部文件,如字典,,配置文件等,,這些文件需要在所有task之間共享,可以放到分布式緩存DistributedCache中(或直接采用-files選項(xiàng),,機(jī)制相同),。 更多的這方面的優(yōu)化方法,還需要在實(shí)踐中不斷積累,。 (3) 為job添加一個Combiner 為job添加一個combiner可以大大減少shuffle階段從map task拷貝給遠(yuǎn)程reduce task的數(shù)據(jù)量,。一般而言,combiner與reducer相同,。 (4) 根據(jù)處理數(shù)據(jù)特征使用最適合和簡潔的Writable類型 Text對象使用起來很方便,,但它在由數(shù)值轉(zhuǎn)換到文本或是由UTF8字符串轉(zhuǎn)換到文本時都是低效的,且會消耗大量的CPU時間,。當(dāng)處理那些非文本的數(shù)據(jù)時,,可以使用二進(jìn)制的Writable類型,如IntWritable,, FloatWritable等,。二進(jìn)制writable好處:避免文件轉(zhuǎn)換的消耗;使map task中間結(jié)果占用更少的空間,。 (5) 重用Writable類型 很多MapReduce用戶常犯的一個錯誤是,,在一個map/reduce方法中為每個輸出都創(chuàng)建Writable對象。例如,,你的Wordcout mapper方法可能這樣寫:
這樣會導(dǎo)致程序分配出成千上萬個短周期的對象,。Java垃圾收集器就要為此做很多的工作。更有效的寫法是:
(6) 使用StringBuffer而不是String 當(dāng)需要對字符串進(jìn)行操作時,,使用StringBuffer而不是String,,String是read-only的,如果對它進(jìn)行修改,,會產(chǎn)生臨時對象,,而StringBuffer是可修改的,不會產(chǎn)生臨時對象,。 (7)調(diào)試 最重要,,也是最基本的,是要掌握MapReduce程序調(diào)試方法,,跟蹤程序的瓶頸,。具體可參考: http://www./blog/2009/12/7-tips-for-improving-mapreduce-performance/ 3. 對參數(shù)進(jìn)行調(diào)優(yōu) 3.1 參數(shù)自動調(diào)優(yōu) 論文[6]試圖從自動化參數(shù)調(diào)優(yōu)角度對hadoop應(yīng)用程序運(yùn)行效率進(jìn)行優(yōu)化,。Hadoop目前有190多個配置參數(shù),,其中大約有25個對hadoop應(yīng)用程序效率有顯著的影響。 論文首先分析了database優(yōu)化思路,。Database會根據(jù)用戶輸入的SQL建立一個代價模型:,,其中y表示查詢q優(yōu)化目標(biāo)(如運(yùn)行時間),,p表示q的查詢計(jì)劃,r表示為執(zhí)行計(jì)劃p而申請的資源量,,d表示一些統(tǒng)計(jì)信息,。數(shù)據(jù)庫會根據(jù)該代價模型評估不同的查詢計(jì)劃,并選擇一個最優(yōu)的執(zhí)行查詢,。這種數(shù)據(jù)庫模型很難擴(kuò)展應(yīng)用到mapreduce環(huán)境中,,主要是因?yàn)椋?/p> (1) mapreduce作業(yè)一般是采用C,C++或java編寫,,與聲明性語言SQL有明顯不同,。 (2) 缺少有關(guān)輸入數(shù)據(jù)的統(tǒng)計(jì)信息。Mapreduce作業(yè)通常是運(yùn)行時解析動態(tài)輸入文件的,,因而運(yùn)行之前schema或者統(tǒng)計(jì)信息均是未知的,。 (3) 它們的優(yōu)化空間不同。數(shù)據(jù)庫的查詢優(yōu)化空間(主要是選擇最優(yōu)的plan)與mapreduce的優(yōu)化空間(主要是配置參數(shù)調(diào)優(yōu))不同,。 本論文提出了三種可行的方案,,第一種是基于采樣的方法,借鑒Terasort作業(yè)的思路,,先對輸入數(shù)據(jù)進(jìn)行采樣,,然后通過樣本估算不同配置下作業(yè)的執(zhí)行時間,最后選擇一種最優(yōu)的配置,。該方法需要解決的一個問題是,,由于reduce階段和map階段存在數(shù)據(jù)依賴,因而map完成之前,,reduce的所有信息均是未知的,。有一種也是可行的思路是,執(zhí)行作業(yè)之前,,先采樣選擇一個樣本組成一個小作業(yè),,然后執(zhí)行該小作業(yè)以估算大作業(yè)性能。該方法也存在一個需要解決的問題,,怎樣采樣才能使樣本最能代表總體,? 第二種是Late Binding,即延遲綁定,,其思想是延遲設(shè)置其中的一個或多個參數(shù),,直到j(luò)ob已經(jīng)部分執(zhí)行,且這些參數(shù)可以確定,。比如hadoop中的combiner操作實(shí)際就是采用的這一機(jī)制,,作業(yè)在執(zhí)行完map()之前不知道要不要進(jìn)行combine。 第三種是Competition-based Approaches,其思想是,,首先,,同時執(zhí)行多個配置有不同參數(shù)的task,然后,,盡快決定哪種配置的task執(zhí)行速度快,,最后,殺掉其它task,。 該文章完全是個調(diào)研性的論文,,它先研究了數(shù)據(jù)庫的一些調(diào)優(yōu)方法,經(jīng)過研究發(fā)現(xiàn)不可以直接將這些方法應(yīng)用于mapreduce系統(tǒng)中,,進(jìn)而針對mapreduce獨(dú)有的特點(diǎn),,提出了幾種也許可行的方法,但論文中并未給出實(shí)現(xiàn),。 3.2 參數(shù)手工配置 3.2.1 Linux文件系統(tǒng)參數(shù)調(diào)整 (1) noatime 和 nodiratime屬性 文件掛載時設(shè)置這兩個屬性可以明顯提高性能,。。默認(rèn)情況下,,Linux ext2/ext3 文件系統(tǒng)在文件被訪問,、創(chuàng)建、修改時會記錄下文件的時間戳,,比如:文件創(chuàng)建時間,、最近一次修改時間和最近一次訪問時間。如果系統(tǒng)運(yùn)行時要訪問大量文件,,關(guān)閉這些操作,,可提升文件系統(tǒng)的性能。Linux 提供了 noatime 這個參數(shù)來禁止記錄最近一次訪問時間戳,。 (2) readahead buffer 調(diào)整linux文件系統(tǒng)中預(yù)讀緩沖區(qū)地大小,,可以明顯提高順序讀文件的性能。默認(rèn)buffer大小為256 sectors,,可以增大為1024或者2408 sectors(注意,,并不是越大越好)??墒褂胋lockdev命令進(jìn)行調(diào)整,。 (3) 避免RAID和LVM操作 避免在TaskTracker和DataNode的機(jī)器上執(zhí)行RAID和LVM操作,這通常會降低性能,。 3.2.2 Hadoop通用參數(shù)調(diào)整 (1) dfs.namenode.handler.count或mapred.job.tracker.handler.count namenode或者jobtracker中用于處理RPC的線程數(shù),,默認(rèn)是10,較大集群,,可調(diào)大些,,比如64,。 (2) dfs.datanode.handler.count datanode上用于處理RPC的線程數(shù)。默認(rèn)為3,,較大集群,可適當(dāng)調(diào)大些,,比如8,。需要注意的是,每添加一個線程,,需要的內(nèi)存增加,。 (3) tasktracker.http.threads HTTP server上的線程數(shù)。運(yùn)行在每個TaskTracker上,,用于處理map task輸出,。大集群,可以將其設(shè)為40~50,。 3.2.3 HDFS相關(guān)配置 (1) dfs.replication 文件副本數(shù),,通常設(shè)為3,不推薦修改,。 (2) dfs.block.size HDFS中數(shù)據(jù)block大小,,默認(rèn)為64M,對于較大集群,,可設(shè)為128MB或者256MB,。(也可以通過參數(shù)mapred.min.split.size配置) (3) mapred.local.dir和dfs.data.dir 這兩個參數(shù)mapred.local.dir和dfs.data.dir 配置的值應(yīng)當(dāng)是分布在各個磁盤上目錄,這樣可以充分利用節(jié)點(diǎn)的IO讀寫能力,。運(yùn)行 Linux sysstat包下的iostat -dx 5命令可以讓每個磁盤都顯示它的利用率,。 3.2.4 map/reduce 相關(guān)配置 (1) {map/reduce}.tasks.maximum 同時運(yùn)行在TaskTracker上的最大map/reduce task數(shù),一般設(shè)為(core_per_node)/2~2*(cores_per_node),。 (2) io.sort.factor 當(dāng)一個map task執(zhí)行完之后,,本地磁盤上(mapred.local.dir)有若干個spill文件,map task最后做的一件事就是執(zhí)行merge sort,,把這些spill文件合成一個文件(partition),。執(zhí)行merge sort的時候,每次同時打開多少個spill文件由該參數(shù)決定,。打開的文件越多,,不一定merge sort就越快,所以要根據(jù)數(shù)據(jù)情況適當(dāng)?shù)恼{(diào)整,。 (3) mapred.child.java.opts 設(shè)置JVM堆的最大可用內(nèi)存,,需從應(yīng)用程序角度進(jìn)行配置。 3.2.5 map task相關(guān)配置 (1) io.sort.mb Map task的輸出結(jié)果和元數(shù)據(jù)在內(nèi)存中所占的buffer總大小,。默認(rèn)為100M,,對于大集群,,可設(shè)為200M。當(dāng)buffer達(dá)到一定閾值,,會啟動一個后臺線程來對buffer的內(nèi)容進(jìn)行排序,,然后寫入本地磁盤(一個spill文件)。 (2) io.sort.spill.percent 這個值就是上述buffer的閾值,,默認(rèn)是0.8,,即80%,當(dāng)buffer中的數(shù)據(jù)達(dá)到這個閾值,,后臺線程會起來對buffer中已有的數(shù)據(jù)進(jìn)行排序,,然后寫入磁盤。 (3) io.sort.record Io.sort.mb中分配給元數(shù)據(jù)的內(nèi)存百分比,,默認(rèn)是0.05,。這個需要根據(jù)應(yīng)用程序進(jìn)行調(diào)整。 (4) mapred.compress.map.output/ Mapred.output.compress 中間結(jié)果和最終結(jié)果是否要進(jìn)行壓縮,,如果是,,指定壓縮方式(Mapred.compress.map.output.codec/ Mapred.output.compress.codec)。推薦使用LZO壓縮,。Intel內(nèi)部測試表明,,相比未壓縮,使用LZO壓縮的TeraSort作業(yè)運(yùn)行時間減少60%,,且明顯快于Zlib壓縮,。 3.2.6 reduce task相關(guān)配置 (1) Mapred.reduce.parallel Reduce shuffle階段copier線程數(shù)。默認(rèn)是5,,對于較大集群,,可調(diào)整為16~25。 4. 從系統(tǒng)實(shí)現(xiàn)角度進(jìn)行優(yōu)化 4.1 在可移植性和性能之間進(jìn)行權(quán)衡 論文[16]主要針對HDFS進(jìn)行了優(yōu)化,,它分析了HDFS性能低下的兩個原因:調(diào)度延遲和可移植性假設(shè),。 (1) 調(diào)度延遲 Hadoop采用的是動態(tài)調(diào)度算法,即:當(dāng)某個tasktracker上出現(xiàn)空slot時,,它會通過HEARBEAT(默認(rèn)時間間隔為3s,,當(dāng)集群變大時,會適當(dāng)調(diào)大)告訴jobtracker,,之后jobtracker采用某種調(diào)度策略從待選task中選擇一個,,再通過HEARBEAT告訴tasktracker。從整個過程看,,HDFS在獲取下一個task之前,,一直處于等待狀態(tài),這造成了資源利用率不高,。此外,,由于tasktracker獲取新task后,,其數(shù)據(jù)讀取過程是完全串行化的,即:tasktracker獲取task后,,依次連接namenode,,連接datanode并讀取數(shù)據(jù),處理數(shù)據(jù),。在此過程中,,當(dāng)tasktracker連接namenode和datanode時,HDFS仍在處于等待狀態(tài),。 為了解決調(diào)度延遲問題,可以考慮的解決方案有:重疊I/O和CPU階段(pipelining),,task預(yù)?。╰ask prefetching),數(shù)據(jù)預(yù)?。╠ata prefetching)等 (2)可移植性假設(shè) 為了增加Hadoop的可移植性,,它采用java語言編寫,這實(shí)際上也潛在的造成了HDFS低效,。Java盡管可以讓Hadoop的可移植性增強(qiáng),,但是它屏蔽了底層文件系統(tǒng),這使它沒法利用一些底層的API對數(shù)據(jù)存儲和讀寫進(jìn)行優(yōu)化,。首先,,在共享集群環(huán)境下,大量并發(fā)讀寫會增加隨機(jī)尋道,,這大大降低讀寫效率,;另外,并發(fā)寫會增加磁盤碎片,,這將增加讀取代價(HDFS適合文件順序讀?。?/p> 為了解決該問題,,可以考慮的解決方案有:修改tasktracker上的線程模型,,現(xiàn)在Hadoop上的采用的模型是one thread per client,即每個client連接由一個線程處理(包括接受請求,,處理請求,,返回結(jié)果);修改之后,,可將線程分成兩組,,一組用于處理client通信(Client Thread),一組用于存取數(shù)據(jù)(Disk Threads,,可采用one thread per disk),。 4.2 Prefetching與preshuffling 論文[7]提出了兩種優(yōu)化策略,,分別為Prefetching和preshuffling。 (1) PreFetching preFetching包括Block-intra prefetching和Block-inter prefetching: Block-intra Prefetching對block內(nèi)部數(shù)據(jù)處理方式進(jìn)行優(yōu)化,。采用的策略是以雙向處理(bi-directional processing)方式提升效率,,即一端進(jìn)行計(jì)算,一端預(yù)取將要用到的數(shù)據(jù)(同步機(jī)制),。 需解決兩個問題,,一是計(jì)算和預(yù)取同步。借用進(jìn)度條(processing bar)的概念,,進(jìn)度條監(jiān)控兩端的進(jìn)度,,當(dāng)同步將被打破時,調(diào)用一個信號,。二是確定合適的預(yù)取率,。通過實(shí)驗(yàn)發(fā)現(xiàn),預(yù)取數(shù)據(jù)量并不是越多越好,。采用重復(fù)實(shí)驗(yàn)的方法確定預(yù)取數(shù)據(jù)率,。 Block-inter Prefetching在block層面預(yù)取數(shù)據(jù)。當(dāng)某個task正在處理數(shù)據(jù)塊A1時,,預(yù)測器預(yù)測它接下來要處理的數(shù)據(jù)塊,,假設(shè)是A2,A3,,A4,則將這幾個數(shù)據(jù)塊讀到task所在的rack上,,這樣加快了task接下來數(shù)據(jù)讀取速度。 (2) PreShuffling 數(shù)據(jù)被map task處理之前,,由預(yù)測器判斷每條記錄將要被哪個reduce task處理,,將這些數(shù)據(jù)交由靠近該reduce task的節(jié)點(diǎn)上的map task處理。 主頁:http://incubator./projects/hama.html 4.3 Five Factors 論文[8]分析了5個影響Hadoop性能的因素,,分別為計(jì)算模型,,I/O模型,數(shù)據(jù)解析,,索引和調(diào)度,,同時針對這5個因素提高了相應(yīng)的提高性能的方法,最后實(shí)驗(yàn)證明,,通過這些方法可以將Hadoop性能提高2.5到3.5倍,。 (1) 計(jì)算模型 在Hadoop中,map task產(chǎn)生的中間結(jié)果經(jīng)過sort-merge策略處理后交給reduce task,。而這種處理策略(指sort-merge)不能夠定制,,這對于有些應(yīng)用而言(有些應(yīng)用程序可能不需要排序處理),性能不佳,。此外,,即使是需要排序歸并處理的,,sort-merge也并不是最好的策略。 本文實(shí)現(xiàn)了Fingerprinting Based Grouping(基于hash)策略,,該方法明顯提高了Hadoop性能,。 (2) I/O模型 Reader可以采用兩種方式從底層的存儲系統(tǒng)中讀取數(shù)據(jù):direct I/O和streaming I/O。direct I/O是指reader直接從本地文件中讀取數(shù)據(jù),;streaming I/O指使用某種進(jìn)程間通信方式(如TCP或者JDBC)從另外一個進(jìn)程中獲取數(shù)據(jù),。從性能角度考慮,direct I/O性能更高,,各種數(shù)據(jù)庫系統(tǒng)都是采用direct I/O模式,。但從存儲獨(dú)立性考慮,streaming I/O使Hadoop能夠從任何進(jìn)程獲取數(shù)據(jù),,如datanode或database,,此外,如果reader不得不從遠(yuǎn)程節(jié)點(diǎn)上讀取數(shù)據(jù),,streaming I/O是僅有的選擇,。 本文對hadoop的文件讀寫方式進(jìn)行了改進(jìn),,當(dāng)文件位于本地時,,采用direct I/O方式;當(dāng)文件位于其它節(jié)點(diǎn)上時,,采用streaming I/O方式,。(改進(jìn)之前,hadoop全是采用streaming I/O方式),。改進(jìn)后,,效率約提高10%。 (3) 數(shù)據(jù)解析 在hadoop中,,原始數(shù)據(jù)要被轉(zhuǎn)換成key/value的形式以便進(jìn)一步處理,,這就是數(shù)據(jù)解析。現(xiàn)在有兩種數(shù)據(jù)解析方法:immutable decoding and mutable decoding,。Hadoop是采用java語言編寫的,,java中很多對象是immutable,如String,。當(dāng)用戶試圖修改一個String內(nèi)容時,,原始對象會被丟棄而新對象會被創(chuàng)建以存儲新內(nèi)容。在Hadoop中,,采用了immutable對象存儲字符串,,這樣每解析一個record就會創(chuàng)建一個新的對象,這就導(dǎo)致了性能低下,。 本文比較了immutable實(shí)現(xiàn)和mutable實(shí)現(xiàn),,immutable性能遠(yuǎn)高于mutable(join是10倍,,select是2倍)。 (4) 索引 HDFS設(shè)計(jì)初衷是處理無結(jié)構(gòu)化數(shù)據(jù),,既然這樣,,怎么可能為數(shù)據(jù)添加索引。實(shí)際上,,考慮到以下幾個因素,,仍可以給數(shù)據(jù)添加索引: A、 hadoop提供了結(jié)構(gòu)將數(shù)據(jù)記錄解析成key/value對,,這樣也許可以給key添加索引,。 B、 如果作業(yè)的輸入是一系列索引文件,,可以實(shí)現(xiàn)一個新的reader高效處理這些文件,。 本文設(shè)計(jì)了一個range 索引,與原系統(tǒng)比較,,連接操作提高了大約10倍,,選擇操作大約提高了2.5倍。 (5) 調(diào)度 Hadoop采用的是動態(tài)調(diào)度策略,,即每次調(diào)度一個task運(yùn)行,,這樣會帶來部分開銷。而database采用的靜態(tài)調(diào)度的策略,,即在編譯的時候就確定了調(diào)度方案,。當(dāng)用戶提交一個sql時,優(yōu)化器會生成一個分布式查詢計(jì)劃交給每一個節(jié)點(diǎn)進(jìn)行處理,。 本文使用一個benchmark評估運(yùn)行時調(diào)度的代價,,最終發(fā)現(xiàn)運(yùn)行時調(diào)度策略從兩個角度影響性能:需要調(diào)度的task數(shù);調(diào)度算法,。對于第一個因素,,可以調(diào)整block的大小減少task數(shù),對于第二個因素,,需要做更多研究,,設(shè)計(jì)新的算法。 本文調(diào)整block大小(從64增大到5G),,發(fā)現(xiàn)block越大,,效率越高,提升性能約20%~30%,。 總結(jié) 這只是一篇研究性的論文,,它只是用實(shí)驗(yàn)驗(yàn)證了這5個因素會影響hadoop性能,具體實(shí)現(xiàn)不具有通用性,如果想將這5個方面在hadoop中實(shí)現(xiàn),,并能夠?qū)嶋H的使用,,也會還有比較長的距離。 4.4 Hadoop++ 論文[9]提出了Hadoop++系統(tǒng),,它為處理結(jié)構(gòu)化或者半結(jié)構(gòu)化數(shù)據(jù)而設(shè)計(jì)的,,它在Hadoop基礎(chǔ)上做了兩點(diǎn)改進(jìn),一是為HDFS設(shè)計(jì)了一種索引—Trojan Index,。思路是:當(dāng)數(shù)據(jù)被加載到HDFS時,,自動為每個split建立索引,這樣雖然會增加數(shù)據(jù)加載時的代價,,但不影響數(shù)據(jù)處理過程,;二是設(shè)計(jì)了一種新的join算法—Trojan join。該join算法在數(shù)據(jù)加載時,,將需要join的數(shù)據(jù)表按照join屬性的hash值存放到相同split中,,這樣只要在map階段進(jìn)行局部join便可以得到最終結(jié)果,該算法跳過了mapreduce的shuffle和reduce階段,,避免了數(shù)據(jù)傳輸?shù)膸淼耐ㄐ糯鷥r,,因而大大提高了效率。 Hadoop++系統(tǒng)最大的優(yōu)點(diǎn)是沒有直接修改hadoop代碼,,只是在Hadoop之上提供了供應(yīng)用程序訪問的API,。 官方主頁:http://infosys.cs./hadoop++.php 5. Hadoop其它問題 5.1 單點(diǎn)故障問題 Hadoop采用的是C/S架構(gòu),因而存在明顯的namenode/jobtracker單點(diǎn)故障問題,。相比于jobtracker,,namenode的單點(diǎn)故障問題更為急迫,,因?yàn)閚amenode的故障恢復(fù)時間很長,,其時間主要花在fsimage加載和blockReport上,下面是一組測試數(shù)據(jù): 當(dāng)前主要的解決思路有: (1) Zookeeper,。利用分布式系統(tǒng)的可靠協(xié)調(diào)系統(tǒng)zookeeper維護(hù)主從namenode之間的一致性,。 (2) 熱備。添加熱備從namenode,,主從namenode之間通過分布式協(xié)議維護(hù)數(shù)據(jù)一致性,。 (3) 分布式namespace。多個namenode共同管理底層的datanode,。 5.2 小文件問題 小文件是指文件size小于HDFS上block大小的文件,。這樣的文件會給hadoop的擴(kuò)展性和性能帶來嚴(yán)重問題。首先,,在HDFS中,,任何block,文件或者目錄在內(nèi)存中均以對象的形式存儲,每個對象約占150byte,,如果有1000 0000個小文件,,每個文件占用一個block,則namenode需要2G空間(存兩份),。如果存儲1億個文件,,則namenode需要20G空間。這樣namenode內(nèi)存容量嚴(yán)重制約了集群的擴(kuò)展,。 其次,,訪問大量小文件速度遠(yuǎn)遠(yuǎn)小于訪問幾個大文件。HDFS最初是為流式訪問大文件開發(fā)的,,如果訪問大量小文件,,需要不斷的從一個datanode跳到另一個datanode,嚴(yán)重影響性能,。最后,,處理大量小文件速度遠(yuǎn)遠(yuǎn)小于處理同等大小的大文件的速度。每一個小文件要占用一個slot,,而task啟動將耗費(fèi)大量時間甚至大部分時間都耗費(fèi)在啟動task和釋放task上,。 對于Hadoop小文件問題,當(dāng)前主要有兩種解決方案,,(1)設(shè)計(jì)一種工具(比如mapreduce作業(yè))交給用戶,,讓用戶自己每隔一段時間將小文件打包成大文件,當(dāng)前Hadoop本身提供了幾個這樣的工具,,包括Hadoop Archive(Hadoop提供了shell命令),,Sequence file(需自己寫程序?qū)崿F(xiàn))和CombineFileInputFormat(需自己寫程序?qū)崿F(xiàn))。(2)從系統(tǒng)層面解決HDFS小文件,,論文[10][11]介紹了它們思路,,大體上說思路基本一致:在原有HDFS基礎(chǔ)上添加一個小文件處理模塊,當(dāng)用戶上傳一個文件時,,判斷該文件是否屬于小文件,,如果是,則交給小文件處理模塊處理,,否則,,交給通用文件處理模塊處理。小文件處理模塊的設(shè)計(jì)思想是,,先將很多小文件合并成一個大文件,,然后為這些小文件建立索引,以便進(jìn)行快速存取和訪問,。 6. 總結(jié) 本文檔介紹Hadoop現(xiàn)有的優(yōu)化點(diǎn),,總體來說,,對于Hadoop平臺,現(xiàn)在主要有三種優(yōu)化思路,,分別為:從應(yīng)用程序角度角度進(jìn)行優(yōu)化,;從參數(shù)配置角度進(jìn)行優(yōu)化;從系統(tǒng)實(shí)現(xiàn)角度進(jìn)行優(yōu)化,。對于第一種思路,,需要根據(jù)具體應(yīng)用需求而定,同時也需要在長期實(shí)踐中積累和總結(jié),;對于第二種思路,,大部分采用的方法是根據(jù)自己集群硬件和具體應(yīng)用調(diào)整參數(shù),找到一個最優(yōu)的,。對于第三種思路,,難度較大,但效果往往非常明顯,,總結(jié)這方面的優(yōu)化思路,,主要有以下幾個: (1) 對namenode進(jìn)行優(yōu)化,包括增加其吞吐率和解決其單點(diǎn)故障問題,。當(dāng)前主要解決方案有3種:分布式namenode,,namenode熱備和zookeeper。 (2) HDFS小文件問題,。當(dāng)Hadoop中存儲大量小文件時,,namenode擴(kuò)展性和性能受到極大制約。現(xiàn)在Hadoop中已有的解決方案包括:Hadoop Archive,,Sequence file和CombineFileInputFormat,。 (3) 調(diào)度框架優(yōu)化。在Hadoop中,,每當(dāng)出現(xiàn)一個空閑slot后,,tasktracker都需要通過HEARBEAT向jobtracker所要task,這個過程的延遲比較大,??梢杂胻ask預(yù)調(diào)度的策略解決該問題,。 (4) 共享環(huán)境下的文件并發(fā)存取,。在共享環(huán)境下,HDFS的隨機(jī)尋道次數(shù)增加,,這大大降低了文件存取效率,。可以通過優(yōu)化磁盤調(diào)度策略的方法改進(jìn),。 (5) 索引,。索引可以大大提高數(shù)據(jù)讀取效率,如果能根據(jù)實(shí)際應(yīng)用需求,為HDFS上的數(shù)據(jù)添加索引,,將大大提高效率,。 7. 參考資料 1、 http://developer.yahoo.com/blogs/hadoop/posts/2011/02/mapreduce-nextgen/ 2,、http://www./2011/01/18/handoop_job_tuning.html 3,、 Optimizing Hadoop Deployments 4、 Baidu Hadoop Extension:https://issues./jira/browse/MAPREDUCE-1270 5,、 淘寶數(shù)據(jù)平臺與產(chǎn)品部官方博客:http://www./archives/1423 6,、 Shivnath Babu: Towards automatic optimization of MapReduce programs. SoCC 2010: 137-142 7、 Sangwon Seo et al., HPMR: Prefetching and Pre-shuffling SharedMapReduce Computation Environment. In the Proceedings of 11th IEEEInternational Conference on Cluster Computing, Sep. 2009 8,、 D. Jiang, B. C. Ooi, L. Shi, S. Wu: The Performance of MapReduce: An In-depth Study. Int’l Conference onVery Large Data Bases (VLDB), 2010 9,、 Jens Dittrich, Jorge-Arnulfo Quiane-Ruiz, Alekh Jindal, Yagiz Kargin, Vinay Setty, and Jörg Schad Hadoop++: Making a Yellow Elephant Run Like a Cheetah (Without It Even Noticing)VLDB 2010/PVLDB, Singapore 10、Xuhui Liu, Jizhong Han, Yunqin Zhong, Chengde Han, Xubin He: Implementing WebGIS on Hadoop: A case study of improving small file I/O performance on HDFS. CLUSTER 2009: 1-8 11,、Bo Dong, Jie Qiu, Qinghua Zheng, Xiao Zhong, Jingwei Li, Ying Li. A Novel Approach to Improving the Efficiency of Storing and Accessing Small Files on Hadoop: A Case Study by PowerPoint Files. In Proceedings of IEEE SCC’2010. pp.65~72 12,、https://issues./jira/browse/HDFS-1052 13、Feng Wang, Jie Qiu, Jie Yang, Bo Dong, Xin Hui Li, Ying Li. Hadoop high availability through metadata replication. In Proceedings of CloudDB’2009. pp.37~44 14,、 Rini T. Kaushik, Milind A. Bhandarkar, Klara Nahrstedt. Evaluation and Analysis of GreenHDFS: A Self-Adaptive, Energy-Conserving Variant of the Hadoop Distributed File System. In Proceedings of CloudCom’2010. pp.274~287 15,、 Willis Lang, Jignesh M. Patel. Energy Management for MapReduce Clusters. PVLDB, 2010: 129~139 16、Jeffrey Shafer, Scott Rixner, Alan L. Cox: The Hadoop distributed filesystem: Balancing portability and performance. ISPASS 2010: 122-1 |
|