MapReduce : simplified data processing on large clusters abstract ...

645 views
593 views

Published on

0 Comments
0 Likes
Statistics
Notes
  • Be the first to comment

  • Be the first to like this

No Downloads
Views
Total views
645
On SlideShare
0
From Embeds
0
Number of Embeds
2
Actions
Shares
0
Downloads
14
Comments
0
Likes
0
Embeds 0
No embeds

No notes for slide

MapReduce : simplified data processing on large clusters abstract ...

  1. 1. MapReduce : simplified data processing on large clusters<br />abstract: mapreduce是一種programming的model 且是一種對於處理或是產生大量資料聯合的implementation<br />introduction:<br />在google的系統中有很多種服務,而要提供這些服務的時候我們必須處理大量的raw data,但這raw data常常數量是非常大的,所以要怎麼樣在可以接受的時間內透過成百上千分散的machine處理就變成很重要得一個issue。<br />而這issue要解決的包涵怎麼平行化計算、分散資料….<br />面對這複雜的東西,我們就設計了一個新的概念讓我們可以表達出我們想要試著做到的simple computation(而把那複雜的平行化、資料分散、平衡負載等東西包到一個library裡頭)而這簡單的概念就是先利用一個”map”的operation把邏輯上在我們input中record的那部份處理出中間的key/value。然後在用”reduce”把所有在intermediate中屬於同一個key的value combine起來<br />“這件事最主要的貢獻是我們建立了一個簡單且有力的interface,使得自動化的平行運算、分散大範圍的計算…..”<br />每個section的簡介!<br />programming model:<br />這個計算的過程的input為 a set of key/value pairs而會產生另一組的key/value pairs當作output,在mapreduce的library中要做到這樣的事利用的就是Map和Reduce兩個function<br />#Map:將input轉成intermediate key I然後將相同I的key value group在一起<br />pass 到Reduce function<br />#Reduce: 接受I且接受 a set of values for that key,然後把這些values merge together形成一個比較小的set of values<br />example:在一大堆document中 計算每個字出現幾次(一個字在一個document中出現就算一次這樣)<br />more example: distributed grep: supplied pattern 記錄下來count of URL Access Frequency: 處理log檔 把count加起來<br />reverse web-link graph: reduce出某些URL(target)出現在哪些page<br />term-vector per host: summarize the most important words in a doc<br />inverted index: reduce出哪些字出現在哪些doc裡<br />distributed sort: extract出key from record 然後利用別的fachility去sort<br />Implementation<br />mapreduce的implement基本上都可以成立,只是根據run的機器不同有不同的implement方式,這篇paper裡用的是google用來計算的environment(一堆PC經由switch Ethernet連結在一起)<br />dual-processor x86 run linux with 2~4GB memory<br />100M || 1G bps at machine level 不過通常只有half bandwidth<br />machine failure是很常發生的<br />每台machine provide 不貴的IDE disk ??????<br />submit job to scheduling system(job當中有a set of task)然後經由scheduler丟到cluster裡可用的machine<br />EXEC OVERVIEW:<br />Map再一開始的時候會自動把input data 分成M份<br />Reduce會把intermediate key切成R份<br />切成M份 一份大概16~64M start many copies of program<br />master會assign work 給worker<br />each worker read input spilt 然後用user-defined 的Map function parses ,產生出intermediate key/value後buffered in memory<br />這buffered的東西會被寫到local disk裡然後切成R份,回報給master知道<br />reduce worker在被master告知資料在哪之後,他會用remote procedure call去讀在local disk的data,讀完之後會sort把相同key的group在一起(why 這個sorting是必須的呢?)<br />經過Reduce function完 會把結果append to a final output file(幾個reduce task就會有幾個output file)<br />#通常我們不會把這些output file 結合起來,通常我們會把他在丟到另外一個MapReduce function裡,或是一個可以處理input是被分散在多個file裡的application。<br />master data structure<br />master需要很多種data structure,像是對每個map、reduce task master都需要儲存worker的狀態(idle,in-progress or complete)並且知道這個worker是在哪個machine上。master是intermediate file從map task到reduce task的導管,所以對每個complete 的map task master需要儲存location以及R個intermediate file,在 map task complete<br />fault tolerance<br />--worker failure<br />master會每隔一段時間ping worker,如果worker在一段時間內沒有回master就會當作這個worker已經failed,這個時候這個task會被reset成idle,同樣的要是map(reduce)task完成了,他會回到idle state,當他們變成idle state他們就會變成合格的for rescheduling<br />當錯誤發生時completed map task會需要被重新執行(因為他的output是放在local machine上 錯誤發生的時後會讓他變成inaccessible) 而completed reduce task就不需要重新被執行因為他的output已經被放到global file system了。<br />當一個map task先被A執行(然後A failed)接著由B執行,reduce worker會被提醒說要重新執行,使得他們知道要去worker B所locate的地方讀input<br />--master failure<br />如果有多個master task那每隔一段時間就可以加個check point,當一個master task dies新的那一份就從最新的那個check point重新開始;如果很不幸的只有一個master task 那這個MapReduce operation會因為這個master 死掉了所以終止,這時候交給client決定要要重新執行。<br />--semantics in the presence of failure<br />Locality<br />因為bandwidth是相對稀少的resource,所以我們想辦法保留network bandwidth經由input data是存在local disk(manage by GFS)GFS會把每個file都切成64MB並且在不一樣的machine儲存copy(通常是三份)MapReduce master會把location的information加入考慮,盡量排成map task所要的input剛好就在他那台machine上有replica(退而求其次就是在同一個network switch上)<br />Task Granularity(粒度)<br />?having each worker perform many different tasks improves dynamic load balancing, and also speeds up recovery when a worker fails?<br />實際上M跟R不能無限制的擴張,因為scheduling有O(M+R)個decisions然後需要keep(M*R)個state,此外R的的大小決定於user看他要output多少個file; M就用16~64MB去切。<br />(we often perform MapReduce computations with M=2000000 and R=5000 using 2000 workers on machines)<br />Backup Tasks<br />常常會造成total time增加的原因是因為在MapReduce的operation中會有straggler(落伍者)的存在,為什麼會有straggler呢?<br />1.machine上有bad disk 所以要常常correct error <br />2.scheduling system可能schedule其他的task在machine上(這樣需要和其他的東西搶cpu memory network bandwidth 之類的東西)<br />3.在machine的initialization code有 bug使得processor caches不能用<br />我們有一個general mechanism 去減輕straggler的問題,當MapReduce快要完成的時候,master schedule會把in progress的task backup,然後調整什麼東西嗎????<br />Refinement<br />partitioning function<br />default的partition function是用hash(key)mod R,這個方法看起來well-partition的分割方法,但有時候或許別的partition function會比較好,舉例來說,output key是URL,然後我們希望同一個host會在同一個outfile那樣這時候的partition function就會變成hash(hostname(urlkey))mod R比較好(就不用在output file中切割了!)<br />ordering guarantees<br />保證within a given key intermediate key會 increasing order<br />好處:sort方便、找key方便<br />combiner function<br />考慮word count,因為會送出很多<key,1>的records,所以有combiner function 再把record送到network前執行partial merging。其實combiner function跟reduce function的code是一樣的,不同的是怎麼處理output,一個是寫到outfile另外一個是送到intermediate。<br />input and out types<br />user 可以support新的input type藉由新增一個interface(reader)reader不一定要read from file,要define他read record從database或是mapped in memory都是可以的同樣的方法也可以拿來新增output file<br />side-effect<br />skipping bad records<br />有些bug可能會讓MapReduce,通常的處理方式是去改掉這個bug,但是bug我們不一定能碰得到。所以我們有時候是可以允許忽略一些record paper提供了一個選擇可以偵測哪些record會導致crash然後就跳過他繼續處理別的。每個worker process都有一個signal handler負責segmentation violation 還有bus error,在開始Map or Reduce operation前,會儲存一個sequence number在global variable,然後如果user code產生了signal,那在crash之前會送出這個sequence number給master知道,如果某一個record讓master知道他crash超過一次,那下一次執行他的時候就會skip他。<br />local execution<br />要在Map or Reduce debug有tricky的方法(不然實際的computation發生在distributed system,可能會有好幾千台machine且work assignment是 master動態決定的)所以為了幫助debug 蒐集資料 還有small scale的測試,我們發展了另外一種implement MapReduce的方法,就是sequential的執行所有的work在一台local machine上。用這種方法可以把computation限制在一個特定的map task,所以我們就可以輕鬆的debug<br />status information<br />master會run 一個internal HTTP server然後輸出各個狀態的頁面,status page show出進行中的計算(比如說有多少個task已經完成了,有多少個還在進行、input data、intermediate data、 output file的大小,這個page也會記錄link of standard error還有output file由哪個task所產生 )user可藉由這些page去預測computation還要多久,還有是否這個computation還需要更多的resource,這些page當然也可以幫忙我們去找出為什麼computation比我們想像中的慢這麼多<br />此外top-level的status page 會show出哪些worker failed 還有哪些map and reduce task讓他們failed的,這些information將會對診斷user code 的bug時相當有幫助。<br />counters<br />MapReduce的library 提供了一個counter來幫忙計算不同的event發生了多少次。舉例來說,user code想要計算有多少word被處理,或是有多少德文的文件被index<br />user code創造了一個叫counter的object然後在map or reduce functiong適當的增加這個counter的值。而這從每個worker 來的counter value會定期的傳送給master(當master ping worker的時候 回覆的時候順便回傳counter value)然後master會把這些value aggregate起來,然後在MapReduce operation完成後回傳到user code裡。而在computation當下的counter value我們可以在master status page裡看得到。master在把counter value aggregate起來的時候會把同一個map/reduce task重複執行導致有duplicate 的值消除掉。<br />有些counter value會自動被MapReduce maintain,像是有多少pair的input被處理以及有多少的output產生。<br />user會發現counter可以清楚的瞭解MapReduce operation的行為,舉例來說,在某些MapReduce operation裡,user code會想要保證input的數量跟output的數量一樣多<br />(或是處理某文件的數量在總共處理的數量是可以容忍的?)<br />Performance<br />在這個部份我們用兩種computation (running on a large cluster of machine)去測量performance。第一種是在大約1T 的地方search 某個特定的pattern,第二種是sort大約1T的data<br />cluster configuration<br />所有的program都是在一個cluster上執行(這個cluster大約有1800台machine)每台machine有兩個2GHz Intel Xeon processor 4GB的memory 兩個160GB IDE disk還有1Gbps的網路,這些machine被arrange成two level的tree-shape,switch network大約100~200Gps,所有的machine都在同一個地方,所以round-trip time比1ms還要少。<br />在這4GB的memory中,大約1~1.5GB是被保留來跑其他的task,除此之外 測試的時候其他東西mostly idle。<br />grep<br />grep program要scan大約10的10次方* 個100-byte的record,為了找一個相對稀少的3-character pattern(這個pattern發生了92337次)我們把input file切成15000份(每份64MB) output file就只有一個(R=1)<br />圖二show出了隨著時間處理的情形,速率漸漸的隨著越來越多的machine被assign而成長,最快可以超過30GB/s(這個時候有1764個worker被assign)當map task結束速率就會開始下降,大約在80s的時後會接近0,不過整個結束是大約在150秒的時候,這包涵了啟動時所需要的overhead,這overhead是因為我們要把user program傳送到每個worker machine上,以及GFS要開啟input file還要get information為了locality optimization。<br />sort<br />sort program sort了10的10次方 個100byte的records(大約1T的資料)3行的Map function 去取出一行text當作sort key(10byte)然後發送出這個key以及原本的text line當作 intermediate。我們用一個內建的Identity function當作Reduce operator。這個function pass the intermediate key as output key,然後最後sort過的output file會多寫一份複製檔到GFS<br />在sort之前,input data一樣被切成64MB piece,sort過的output file被我們切成4000份。我們對於這個benchmark圖三show出了正常執行sort program的情況,左上角的是read input data所要的時間,最快13GB/s 很快的降低,大約在200秒完成,相較於grep速率比較慢,因為sort map task花了約一半的時間還有I/O的bandwidth 把intermediate 寫到local disk,而在grep裡,intermediate的大小是微不足道的。中左的圖是map task把data經由network送到reduce work 顯示出了map task經由network送data到reduce task的速率,這個shuffle(拖曳 搬運的意思嗎)當地一個map task完成時就開始,在圖中第一個hump是第一批的reduce task(),大約在300s的計算後,有些第一批的reduce task完成了然後我們就開始傳送data到剩下的reduce task,所有的搬移大約在600s的後完成。<br />左下角的圖顯示出了reduce task把sort好的data寫到final output的速率,在第一批的shuffle結束到開始寫到output中間有一個小小的delay,這個delay是因為machine在sort這些intermediate data。write持續以一個2~4GB的寫入速度一段時間,所有的write在850s的時候結束,所以整個sort的program包含了startup的overhead還有執行計算的所有時間為891s,這跟benchmark最佳的時間1057相去不遠。<br />有些事我們可以注意一下,input rate比shuffle rate還有 output rate還要快,因為我們有用了locality optimization(讓資料從local disk讀出來的時候不用受到network的限制)而shuffle rate 比output rate還要高因為output要多寫兩份複製品,這兩份複製品讓我們基本的file system可以提供reliability and availability,而這network bandwidth的需求可以因為我們用了erasure coding而降低。<br />effect of backup task<br />在圖三的b,我們show出了如果沒有back up task的執行結果,執行的情況其實跟a很像,但是在最後會拖得非常長,在960s後,只剩下5個task在執行,但這五個task要到300s後才會真正結束,總共要花了1283秒,比有back up task整整多了44%的執行時間。<br />machine failure<br />在圖三的c,我們show出了當執行sort program時故意的刪掉了200個worker process,而scheduler會馬上重新啟動新的worker process(因為我們只有刪除process machine沒有真的壞掉)<br />由於worker death我們可以看到input rate會出現負的速率,因為有些已經完成的map work消失了,所以剛剛那些他做的事就必須要重做,不過重新執行的速度非常的快,這個的結果也花了933s而已,比正常執行只多了5%的時間。<br />Experience<br />我們在2003年2月的時候寫了第一個版本的MapReduce library,然後在2003年8月的時候做了一個重大的加強,這邊包含了locality optimization, dynamic load balancing of task execution across worker machine。自從那之後就很驚訝原來mapreduce可以用在那麼多地方,在google裡我們就在以下的領域用了mapreduce:<br />大規模的machine learning problem<br />…………………………………..(略)<br />large-scale indexing<br />現在用mapreduce最重大的地方是完全重寫了production index的system,這system產生了某種資料結構是可以給google web search service,這個system的input大約有20T 那我們跑過五次的MapReduce後會有很多比原本用ad-hoc還要好的地方<br />indexing code比較簡單、小、而且更容易了解,因為在MapReduce的library中就已經處理好了錯誤容忍、分散資料、平行等東西<br />我們可以將概念上不相關的計算切開,並且避免在將他們混合在一起的時候需要額外的data pass,這個好處讓我們在更換index過程的時候方便許多<br />index process變得更容易去操作,因為大部分的問題是因為machine failure, slow machine, network hiccups所引起,而這些已經自動在MapReduce library裡頭處理好,此外,如果我們要藉著新增額外的機器去增進index process的performance也變得很簡單。<br />Related work<br />很多系統提供了限制性的programming model然後用這些限制自動去平行化計算,舉例來說,一個associative function可以計算N個element所有的prefix用N個處理器在logN的時間完成。MapReduce可以被認為在這些model中根據我們在現實生活中的經驗簡化的、去蕪存菁的結果。用更顯著的意義來說,我們提供了一個可以忍受錯誤的implementation。相對的,大部分平行處理的系統只能被實現在較小的規模還有把處理machine錯誤的詳細資訊留給programmer。<br />Bulk Synchronous Programming還有某些MPI primitives提供了higher level的概念讓programmer可以更簡單的去寫平行程式。在這些系統和MapReduce一個重大的差別是MapReduce開發了一個限制性的programming model自動地去平行化使用者的程式然後提供了顯而易見的fault-tolerance<br />我們的locality optimization…..<br />backup task mechianism……<br />Conclusions<br />MapReduce model已經成功的被用在很多google裡的用途,我們把這個成功歸功於很多原因。第一,這個model很容易被使用,即使對平行或是distributed沒有經驗的programmer,因為有很多東西隱藏在MapReduce library裡。第二,各式各樣的問題在MapReduce可以很簡單的被表達,舉例來說,MapReduce 被用來產生google web search service的data,這可以被拿來sort data mining,還有很多其他的system。第三,我們讓MapReduce可以實坐在一個群集裡面包含了上千台machine,這個實做讓我們更有效率的處理所面對到的問題。<br />我們從這個work中了解到了很多事情。第一,限制性的model讓我們可以簡單的去平行化且分散計算,必且讓這個computation可以忍受錯誤的發生。還有很多的optimization都是想辦法減少透過network來傳輸的量。第三,重複的執行可以用來減少那些慢機器所導致的影響,並且處理machine failure and data loss。<br />

×