mapred_tutorial.html 100 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131
  1. <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
  2. <html>
  3. <head>
  4. <META http-equiv="Content-Type" content="text/html; charset=UTF-8">
  5. <meta content="Apache Forrest" name="Generator">
  6. <meta name="Forrest-version" content="0.7">
  7. <meta name="Forrest-skin-name" content="pelt">
  8. <title>Hadoop Map-Reduce Tutorial</title>
  9. <link type="text/css" href="skin/basic.css" rel="stylesheet">
  10. <link media="screen" type="text/css" href="skin/screen.css" rel="stylesheet">
  11. <link media="print" type="text/css" href="skin/print.css" rel="stylesheet">
  12. <link type="text/css" href="skin/profile.css" rel="stylesheet">
  13. <script src="skin/getBlank.js" language="javascript" type="text/javascript"></script><script src="skin/getMenu.js" language="javascript" type="text/javascript"></script><script src="skin/fontsize.js" language="javascript" type="text/javascript"></script>
  14. <link rel="shortcut icon" href="images/favicon.ico">
  15. </head>
  16. <body onload="init()">
  17. <script type="text/javascript">ndeSetTextSize();</script>
  18. <div id="top">
  19. <div class="breadtrail">
  20. <a href="http://www.apache.org/">Apache</a> &gt; <a href="http://lucene.apache.org/">Lucene</a> &gt; <a href="http://lucene.apache.org/hadoop/">Hadoop</a><script src="skin/breadcrumbs.js" language="JavaScript" type="text/javascript"></script>
  21. </div>
  22. <div class="header">
  23. <div class="grouplogo">
  24. <a href="http://lucene.apache.org/"><img class="logoImage" alt="Lucene" src="images/lucene_green_150.gif" title="Apache Lucene"></a>
  25. </div>
  26. <div class="projectlogo">
  27. <a href="http://lucene.apache.org/hadoop/"><img class="logoImage" alt="Hadoop" src="images/hadoop-logo.jpg" title="Scalable Computing Platform"></a>
  28. </div>
  29. <div class="searchbox">
  30. <form action="http://www.google.com/search" method="get" class="roundtopsmall">
  31. <input value="lucene.apache.org" name="sitesearch" type="hidden"><input onFocus="getBlank (this, 'Search the site with google');" size="25" name="q" id="query" type="text" value="Search the site with google">&nbsp;
  32. <input attr="value" name="Search" value="Search" type="submit">
  33. </form>
  34. </div>
  35. <ul id="tabs">
  36. <li>
  37. <a class="base-not-selected" href="http://lucene.apache.org/hadoop/">Project</a>
  38. </li>
  39. <li>
  40. <a class="base-not-selected" href="http://wiki.apache.org/lucene-hadoop">Wiki</a>
  41. </li>
  42. <li class="current">
  43. <a class="base-selected" href="index.html">Hadoop 0.16 Documentation</a>
  44. </li>
  45. </ul>
  46. </div>
  47. </div>
  48. <div id="main">
  49. <div id="publishedStrip">
  50. <div id="level2tabs"></div>
  51. <script type="text/javascript"><!--
  52. document.write("<text>Last Published:</text> " + document.lastModified);
  53. // --></script>
  54. </div>
  55. <div class="breadtrail">
  56. &nbsp;
  57. </div>
  58. <div id="menu">
  59. <div onclick="SwitchMenu('menu_selected_1.1', 'skin/')" id="menu_selected_1.1Title" class="menutitle" style="background-image: url('skin/images/chapter_open.gif');">Documentation</div>
  60. <div id="menu_selected_1.1" class="selectedmenuitemgroup" style="display: block;">
  61. <div class="menuitem">
  62. <a href="index.html">Overview</a>
  63. </div>
  64. <div class="menuitem">
  65. <a href="quickstart.html">Quickstart</a>
  66. </div>
  67. <div class="menuitem">
  68. <a href="cluster_setup.html">Cluster Setup</a>
  69. </div>
  70. <div class="menuitem">
  71. <a href="hdfs_design.html">HDFS Architecture</a>
  72. </div>
  73. <div class="menupage">
  74. <div class="menupagetitle">Map-Reduce Tutorial</div>
  75. </div>
  76. <div class="menuitem">
  77. <a href="streaming.html">Streaming</a>
  78. </div>
  79. <div class="menuitem">
  80. <a href="hod.html">Hadoop On Demand</a>
  81. </div>
  82. <div class="menuitem">
  83. <a href="api/index.html">API Docs</a>
  84. </div>
  85. <div class="menuitem">
  86. <a href="http://wiki.apache.org/lucene-hadoop/">Wiki</a>
  87. </div>
  88. <div class="menuitem">
  89. <a href="http://wiki.apache.org/lucene-hadoop/FAQ">FAQ</a>
  90. </div>
  91. <div class="menuitem">
  92. <a href="http://lucene.apache.org/hadoop/mailing_lists.html">Mailing Lists</a>
  93. </div>
  94. </div>
  95. <div id="credit"></div>
  96. <div id="roundbottom">
  97. <img style="display: none" class="corner" height="15" width="15" alt="" src="skin/images/rc-b-l-15-1body-2menu-3menu.png"></div>
  98. <div id="credit2"></div>
  99. </div>
  100. <div id="content">
  101. <div title="Portable Document Format" class="pdflink">
  102. <a class="dida" href="mapred_tutorial.pdf"><img alt="PDF -icon" src="skin/images/pdfdoc.gif" class="skin"><br>
  103. PDF</a>
  104. </div>
  105. <h1>Hadoop Map-Reduce Tutorial</h1>
  106. <div id="minitoc-area">
  107. <ul class="minitoc">
  108. <li>
  109. <a href="#Purpose">Purpose</a>
  110. </li>
  111. <li>
  112. <a href="#Pre-requisites">Pre-requisites</a>
  113. </li>
  114. <li>
  115. <a href="#Overview">Overview</a>
  116. </li>
  117. <li>
  118. <a href="#Inputs+and+Outputs">Inputs and Outputs</a>
  119. </li>
  120. <li>
  121. <a href="#Example%3A+WordCount+v1.0">Example: WordCount v1.0</a>
  122. <ul class="minitoc">
  123. <li>
  124. <a href="#Source+Code">Source Code</a>
  125. </li>
  126. <li>
  127. <a href="#Usage">Usage</a>
  128. </li>
  129. <li>
  130. <a href="#Walk-through">Walk-through</a>
  131. </li>
  132. </ul>
  133. </li>
  134. <li>
  135. <a href="#Map-Reduce+-+User+Interfaces">Map-Reduce - User Interfaces</a>
  136. <ul class="minitoc">
  137. <li>
  138. <a href="#Payload">Payload</a>
  139. <ul class="minitoc">
  140. <li>
  141. <a href="#Mapper">Mapper</a>
  142. </li>
  143. <li>
  144. <a href="#Reducer">Reducer</a>
  145. </li>
  146. <li>
  147. <a href="#Partitioner">Partitioner</a>
  148. </li>
  149. <li>
  150. <a href="#Reporter">Reporter</a>
  151. </li>
  152. <li>
  153. <a href="#OutputCollector">OutputCollector</a>
  154. </li>
  155. </ul>
  156. </li>
  157. <li>
  158. <a href="#Job+Configuration">Job Configuration</a>
  159. </li>
  160. <li>
  161. <a href="#Job+Submission+and+Monitoring">Job Submission and Monitoring</a>
  162. <ul class="minitoc">
  163. <li>
  164. <a href="#Job+Control">Job Control</a>
  165. </li>
  166. </ul>
  167. </li>
  168. <li>
  169. <a href="#Job+Input">Job Input</a>
  170. <ul class="minitoc">
  171. <li>
  172. <a href="#InputSplit">InputSplit</a>
  173. </li>
  174. <li>
  175. <a href="#RecordReader">RecordReader</a>
  176. </li>
  177. </ul>
  178. </li>
  179. <li>
  180. <a href="#Job+Output">Job Output</a>
  181. <ul class="minitoc">
  182. <li>
  183. <a href="#Task+Side-Effect+Files">Task Side-Effect Files</a>
  184. </li>
  185. <li>
  186. <a href="#RecordWriter">RecordWriter</a>
  187. </li>
  188. </ul>
  189. </li>
  190. <li>
  191. <a href="#Other+Useful+Features">Other Useful Features</a>
  192. <ul class="minitoc">
  193. <li>
  194. <a href="#Counters">Counters</a>
  195. </li>
  196. <li>
  197. <a href="#DistributedCache">DistributedCache</a>
  198. </li>
  199. <li>
  200. <a href="#Tool">Tool</a>
  201. </li>
  202. <li>
  203. <a href="#IsolationRunner">IsolationRunner</a>
  204. </li>
  205. <li>
  206. <a href="#JobControl">JobControl</a>
  207. </li>
  208. </ul>
  209. </li>
  210. </ul>
  211. </li>
  212. <li>
  213. <a href="#Example%3A+WordCount+v2.0">Example: WordCount v2.0</a>
  214. <ul class="minitoc">
  215. <li>
  216. <a href="#Source+Code-N10A91">Source Code</a>
  217. </li>
  218. <li>
  219. <a href="#Sample+Runs">Sample Runs</a>
  220. </li>
  221. <li>
  222. <a href="#Salient+Points">Salient Points</a>
  223. </li>
  224. </ul>
  225. </li>
  226. </ul>
  227. </div>
  228. <a name="N1000C"></a><a name="Purpose"></a>
  229. <h2 class="h3">Purpose</h2>
  230. <div class="section">
  231. <p>This document comprehensively describes all user-facing facets of the
  232. Hadoop Map-Reduce framework and serves as a tutorial.
  233. </p>
  234. </div>
  235. <a name="N10016"></a><a name="Pre-requisites"></a>
  236. <h2 class="h3">Pre-requisites</h2>
  237. <div class="section">
  238. <p>Ensure that Hadoop is installed, configured and is running. More
  239. details:</p>
  240. <ul>
  241. <li>
  242. Hadoop <a href="quickstart.html">Quickstart</a> for first-time users.
  243. </li>
  244. <li>
  245. Hadoop <a href="cluster_setup.html">Cluster Setup</a> for large,
  246. distributed clusters.
  247. </li>
  248. </ul>
  249. </div>
  250. <a name="N10031"></a><a name="Overview"></a>
  251. <h2 class="h3">Overview</h2>
  252. <div class="section">
  253. <p>Hadoop Map-Reduce is a software framework for easily writing
  254. applications which process vast amounts of data (multi-terabyte data-sets)
  255. in-parallel on large clusters (thousands of nodes) of commodity
  256. hardware in a reliable, fault-tolerant manner.</p>
  257. <p>A Map-Reduce <em>job</em> usually splits the input data-set into
  258. independent chunks which are processed by the <em>map tasks</em> in a
  259. completely parallel manner. The framework sorts the outputs of the maps,
  260. which are then input to the <em>reduce tasks</em>. Typically both the
  261. input and the output of the job are stored in a file-system. The framework
  262. takes care of scheduling tasks, monitoring them and re-executes the failed
  263. tasks.</p>
  264. <p>Typically the compute nodes and the storage nodes are the same, that is,
  265. the Map-Reduce framework and the <a href="hdfs_design.html">Distributed
  266. FileSystem</a> are running on the same set of nodes. This configuration
  267. allows the framework to effectively schedule tasks on the nodes where data
  268. is already present, resulting in very high aggregate bandwidth across the
  269. cluster.</p>
  270. <p>The Map-Reduce framework consists of a single master
  271. <span class="codefrag">JobTracker</span> and one slave <span class="codefrag">TaskTracker</span> per
  272. cluster-node. The master is responsible for scheduling the jobs' component
  273. tasks on the slaves, monitoring them and re-executing the failed tasks. The
  274. slaves execute the tasks as directed by the master.</p>
  275. <p>Minimally, applications specify the input/output locations and supply
  276. <em>map</em> and <em>reduce</em> functions via implementations of
  277. appropriate interfaces and/or abstract-classes. These, and other job
  278. parameters, comprise the <em>job configuration</em>. The Hadoop
  279. <em>job client</em> then submits the job (jar/executable etc.) and
  280. configuration to the <span class="codefrag">JobTracker</span> which then assumes the
  281. responsibility of distributing the software/configuration to the slaves,
  282. scheduling tasks and monitoring them, providing status and diagnostic
  283. information to the job-client.</p>
  284. <p>Although the Hadoop framework is implemented in Java<sup>TM</sup>,
  285. Map-Reduce applications need not be written in Java.</p>
  286. <ul>
  287. <li>
  288. <a href="api/org/apache/hadoop/streaming/package-summary.html">
  289. Hadoop Streaming</a> is a utility which allows users to create and run
  290. jobs with any executables (e.g. shell utilities) as the mapper and/or
  291. the reducer.
  292. </li>
  293. <li>
  294. <a href="api/org/apache/hadoop/mapred/pipes/package-summary.html">
  295. Hadoop Pipes</a> is a <a href="http://www.swig.org/">SWIG</a>-
  296. compatible <em>C++ API</em> to implement Map-Reduce applications (non
  297. JNI<sup>TM</sup> based).
  298. </li>
  299. </ul>
  300. </div>
  301. <a name="N1008A"></a><a name="Inputs+and+Outputs"></a>
  302. <h2 class="h3">Inputs and Outputs</h2>
  303. <div class="section">
  304. <p>The Map-Reduce framework operates exclusively on
  305. <span class="codefrag">&lt;key, value&gt;</span> pairs, that is, the framework views the
  306. input to the job as a set of <span class="codefrag">&lt;key, value&gt;</span> pairs and
  307. produces a set of <span class="codefrag">&lt;key, value&gt;</span> pairs as the output of
  308. the job, conceivably of different types.</p>
  309. <p>The <span class="codefrag">key</span> and <span class="codefrag">value</span> classes have to be
  310. serializable by the framework and hence need to implement the
  311. <a href="api/org/apache/hadoop/io/Writable.html">Writable</a>
  312. interface. Additionally, the <span class="codefrag">key</span> classes have to implement the
  313. <a href="api/org/apache/hadoop/io/WritableComparable.html">
  314. WritableComparable</a> interface to facilitate sorting by the framework.
  315. </p>
  316. <p>Input and Output types of a Map-Reduce job:</p>
  317. <p>
  318. (input) <span class="codefrag">&lt;k1, v1&gt;</span>
  319. -&gt;
  320. <strong>map</strong>
  321. -&gt;
  322. <span class="codefrag">&lt;k2, v2&gt;</span>
  323. -&gt;
  324. <strong>combine</strong>
  325. -&gt;
  326. <span class="codefrag">&lt;k2, v2&gt;</span>
  327. -&gt;
  328. <strong>reduce</strong>
  329. -&gt;
  330. <span class="codefrag">&lt;k3, v3&gt;</span> (output)
  331. </p>
  332. </div>
  333. <a name="N100CC"></a><a name="Example%3A+WordCount+v1.0"></a>
  334. <h2 class="h3">Example: WordCount v1.0</h2>
  335. <div class="section">
  336. <p>Before we jump into the details, lets walk through an example Map-Reduce
  337. application to get a flavour for how they work.</p>
  338. <p>
  339. <span class="codefrag">WordCount</span> is a simple application that counts the number of
  340. occurences of each word in a given input set.</p>
  341. <a name="N100DA"></a><a name="Source+Code"></a>
  342. <h3 class="h4">Source Code</h3>
  343. <table class="ForrestTable" cellspacing="1" cellpadding="4">
  344. <tr>
  345. <th colspan="1" rowspan="1"></th>
  346. <th colspan="1" rowspan="1">WordCount.java</th>
  347. </tr>
  348. <tr>
  349. <td colspan="1" rowspan="1">1.</td>
  350. <td colspan="1" rowspan="1">
  351. <span class="codefrag">package org.myorg;</span>
  352. </td>
  353. </tr>
  354. <tr>
  355. <td colspan="1" rowspan="1">2.</td>
  356. <td colspan="1" rowspan="1"></td>
  357. </tr>
  358. <tr>
  359. <td colspan="1" rowspan="1">3.</td>
  360. <td colspan="1" rowspan="1">
  361. <span class="codefrag">import java.io.Exception;</span>
  362. </td>
  363. </tr>
  364. <tr>
  365. <td colspan="1" rowspan="1">4.</td>
  366. <td colspan="1" rowspan="1">
  367. <span class="codefrag">import java.util.*;</span>
  368. </td>
  369. </tr>
  370. <tr>
  371. <td colspan="1" rowspan="1">5.</td>
  372. <td colspan="1" rowspan="1"></td>
  373. </tr>
  374. <tr>
  375. <td colspan="1" rowspan="1">6.</td>
  376. <td colspan="1" rowspan="1">
  377. <span class="codefrag">import org.apache.hadoop.fs.Path;</span>
  378. </td>
  379. </tr>
  380. <tr>
  381. <td colspan="1" rowspan="1">7.</td>
  382. <td colspan="1" rowspan="1">
  383. <span class="codefrag">import org.apache.hadoop.conf.*;</span>
  384. </td>
  385. </tr>
  386. <tr>
  387. <td colspan="1" rowspan="1">8.</td>
  388. <td colspan="1" rowspan="1">
  389. <span class="codefrag">import org.apache.hadoop.io.*;</span>
  390. </td>
  391. </tr>
  392. <tr>
  393. <td colspan="1" rowspan="1">9.</td>
  394. <td colspan="1" rowspan="1">
  395. <span class="codefrag">import org.apache.hadoop.mapred.*;</span>
  396. </td>
  397. </tr>
  398. <tr>
  399. <td colspan="1" rowspan="1">10.</td>
  400. <td colspan="1" rowspan="1">
  401. <span class="codefrag">import org.apache.hadoop.util.*;</span>
  402. </td>
  403. </tr>
  404. <tr>
  405. <td colspan="1" rowspan="1">11.</td>
  406. <td colspan="1" rowspan="1"></td>
  407. </tr>
  408. <tr>
  409. <td colspan="1" rowspan="1">12.</td>
  410. <td colspan="1" rowspan="1">
  411. <span class="codefrag">public class WordCount {</span>
  412. </td>
  413. </tr>
  414. <tr>
  415. <td colspan="1" rowspan="1">13.</td>
  416. <td colspan="1" rowspan="1"></td>
  417. </tr>
  418. <tr>
  419. <td colspan="1" rowspan="1">14.</td>
  420. <td colspan="1" rowspan="1">
  421. &nbsp;&nbsp;
  422. <span class="codefrag">
  423. public static class MapClass extends MapReduceBase
  424. implements Mapper&lt;LongWritable, Text, Text, IntWritable&gt; {
  425. </span>
  426. </td>
  427. </tr>
  428. <tr>
  429. <td colspan="1" rowspan="1">15.</td>
  430. <td colspan="1" rowspan="1">
  431. &nbsp;&nbsp;&nbsp;&nbsp;
  432. <span class="codefrag">
  433. private final static IntWritable one = new IntWritable(1);
  434. </span>
  435. </td>
  436. </tr>
  437. <tr>
  438. <td colspan="1" rowspan="1">16.</td>
  439. <td colspan="1" rowspan="1">
  440. &nbsp;&nbsp;&nbsp;&nbsp;
  441. <span class="codefrag">private Text word = new Text();</span>
  442. </td>
  443. </tr>
  444. <tr>
  445. <td colspan="1" rowspan="1">17.</td>
  446. <td colspan="1" rowspan="1"></td>
  447. </tr>
  448. <tr>
  449. <td colspan="1" rowspan="1">18.</td>
  450. <td colspan="1" rowspan="1">
  451. &nbsp;&nbsp;&nbsp;&nbsp;
  452. <span class="codefrag">
  453. public void map(LongWritable key, Text value,
  454. OutputCollector&lt;Text, IntWritable&gt; output,
  455. Reporter reporter) throws IOException {
  456. </span>
  457. </td>
  458. </tr>
  459. <tr>
  460. <td colspan="1" rowspan="1">19.</td>
  461. <td colspan="1" rowspan="1">
  462. &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
  463. <span class="codefrag">String line = value.toString();</span>
  464. </td>
  465. </tr>
  466. <tr>
  467. <td colspan="1" rowspan="1">20.</td>
  468. <td colspan="1" rowspan="1">
  469. &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
  470. <span class="codefrag">StringTokenizer tokenizer = new StringTokenizer(line);</span>
  471. </td>
  472. </tr>
  473. <tr>
  474. <td colspan="1" rowspan="1">21.</td>
  475. <td colspan="1" rowspan="1">
  476. &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
  477. <span class="codefrag">while (tokenizer.hasMoreTokens()) {</span>
  478. </td>
  479. </tr>
  480. <tr>
  481. <td colspan="1" rowspan="1">22.</td>
  482. <td colspan="1" rowspan="1">
  483. &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
  484. <span class="codefrag">word.set(tokenizer.nextToken());</span>
  485. </td>
  486. </tr>
  487. <tr>
  488. <td colspan="1" rowspan="1">23.</td>
  489. <td colspan="1" rowspan="1">
  490. &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
  491. <span class="codefrag">output.collect(word, one);</span>
  492. </td>
  493. </tr>
  494. <tr>
  495. <td colspan="1" rowspan="1">24.</td>
  496. <td colspan="1" rowspan="1">
  497. &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
  498. <span class="codefrag">}</span>
  499. </td>
  500. </tr>
  501. <tr>
  502. <td colspan="1" rowspan="1">25.</td>
  503. <td colspan="1" rowspan="1">
  504. &nbsp;&nbsp;&nbsp;&nbsp;
  505. <span class="codefrag">}</span>
  506. </td>
  507. </tr>
  508. <tr>
  509. <td colspan="1" rowspan="1">26.</td>
  510. <td colspan="1" rowspan="1">
  511. &nbsp;&nbsp;
  512. <span class="codefrag">}</span>
  513. </td>
  514. </tr>
  515. <tr>
  516. <td colspan="1" rowspan="1">27.</td>
  517. <td colspan="1" rowspan="1"></td>
  518. </tr>
  519. <tr>
  520. <td colspan="1" rowspan="1">28.</td>
  521. <td colspan="1" rowspan="1">
  522. &nbsp;&nbsp;
  523. <span class="codefrag">
  524. public static class Reduce extends MapReduceBase implements
  525. Reducer&lt;Text, IntWritable, Text, IntWritable&gt; {
  526. </span>
  527. </td>
  528. </tr>
  529. <tr>
  530. <td colspan="1" rowspan="1">29.</td>
  531. <td colspan="1" rowspan="1">
  532. &nbsp;&nbsp;&nbsp;&nbsp;
  533. <span class="codefrag">
  534. public void reduce(Text key, Iterator&lt;IntWritable&gt; values,
  535. OutputCollector&lt;Text, IntWritable&gt; output,
  536. Reporter reporter) throws IOException {
  537. </span>
  538. </td>
  539. </tr>
  540. <tr>
  541. <td colspan="1" rowspan="1">30.</td>
  542. <td colspan="1" rowspan="1">
  543. &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
  544. <span class="codefrag">int sum = 0;</span>
  545. </td>
  546. </tr>
  547. <tr>
  548. <td colspan="1" rowspan="1">31.</td>
  549. <td colspan="1" rowspan="1">
  550. &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
  551. <span class="codefrag">while (values.hasNext()) {</span>
  552. </td>
  553. </tr>
  554. <tr>
  555. <td colspan="1" rowspan="1">32.</td>
  556. <td colspan="1" rowspan="1">
  557. &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
  558. <span class="codefrag">sum += values.next().get();</span>
  559. </td>
  560. </tr>
  561. <tr>
  562. <td colspan="1" rowspan="1">33.</td>
  563. <td colspan="1" rowspan="1">
  564. &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
  565. <span class="codefrag">}</span>
  566. </td>
  567. </tr>
  568. <tr>
  569. <td colspan="1" rowspan="1">34.</td>
  570. <td colspan="1" rowspan="1">
  571. &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
  572. <span class="codefrag">output.collect(key, new IntWritable(sum));</span>
  573. </td>
  574. </tr>
  575. <tr>
  576. <td colspan="1" rowspan="1">35.</td>
  577. <td colspan="1" rowspan="1">
  578. &nbsp;&nbsp;&nbsp;&nbsp;
  579. <span class="codefrag">}</span>
  580. </td>
  581. </tr>
  582. <tr>
  583. <td colspan="1" rowspan="1">36.</td>
  584. <td colspan="1" rowspan="1">
  585. &nbsp;&nbsp;
  586. <span class="codefrag">}</span>
  587. </td>
  588. </tr>
  589. <tr>
  590. <td colspan="1" rowspan="1">37.</td>
  591. <td colspan="1" rowspan="1"></td>
  592. </tr>
  593. <tr>
  594. <td colspan="1" rowspan="1">38.</td>
  595. <td colspan="1" rowspan="1">
  596. &nbsp;&nbsp;
  597. <span class="codefrag">
  598. public static void main(String[] args) throws Exception {
  599. </span>
  600. </td>
  601. </tr>
  602. <tr>
  603. <td colspan="1" rowspan="1">39.</td>
  604. <td colspan="1" rowspan="1">
  605. &nbsp;&nbsp;&nbsp;&nbsp;
  606. <span class="codefrag">
  607. JobConf conf = new JobConf(WordCount.class);
  608. </span>
  609. </td>
  610. </tr>
  611. <tr>
  612. <td colspan="1" rowspan="1">40.</td>
  613. <td colspan="1" rowspan="1">
  614. &nbsp;&nbsp;&nbsp;&nbsp;
  615. <span class="codefrag">conf.setJobName("wordcount");</span>
  616. </td>
  617. </tr>
  618. <tr>
  619. <td colspan="1" rowspan="1">41.</td>
  620. <td colspan="1" rowspan="1"></td>
  621. </tr>
  622. <tr>
  623. <td colspan="1" rowspan="1">42.</td>
  624. <td colspan="1" rowspan="1">
  625. &nbsp;&nbsp;&nbsp;&nbsp;
  626. <span class="codefrag">conf.setOutputKeyClass(Text.class);</span>
  627. </td>
  628. </tr>
  629. <tr>
  630. <td colspan="1" rowspan="1">43.</td>
  631. <td colspan="1" rowspan="1">
  632. &nbsp;&nbsp;&nbsp;&nbsp;
  633. <span class="codefrag">conf.setOutputValueClass(IntWritable.class);</span>
  634. </td>
  635. </tr>
  636. <tr>
  637. <td colspan="1" rowspan="1">44.</td>
  638. <td colspan="1" rowspan="1"></td>
  639. </tr>
  640. <tr>
  641. <td colspan="1" rowspan="1">45.</td>
  642. <td colspan="1" rowspan="1">
  643. &nbsp;&nbsp;&nbsp;&nbsp;
  644. <span class="codefrag">conf.setMapperClass(MapClass.class);</span>
  645. </td>
  646. </tr>
  647. <tr>
  648. <td colspan="1" rowspan="1">46.</td>
  649. <td colspan="1" rowspan="1">
  650. &nbsp;&nbsp;&nbsp;&nbsp;
  651. <span class="codefrag">conf.setCombinerClass(Reduce.class);</span>
  652. </td>
  653. </tr>
  654. <tr>
  655. <td colspan="1" rowspan="1">47.</td>
  656. <td colspan="1" rowspan="1">
  657. &nbsp;&nbsp;&nbsp;&nbsp;
  658. <span class="codefrag">conf.setReducerClass(Reduce.class);</span>
  659. </td>
  660. </tr>
  661. <tr>
  662. <td colspan="1" rowspan="1">48.</td>
  663. <td colspan="1" rowspan="1"></td>
  664. </tr>
  665. <tr>
  666. <td colspan="1" rowspan="1">49.</td>
  667. <td colspan="1" rowspan="1">
  668. &nbsp;&nbsp;&nbsp;&nbsp;
  669. <span class="codefrag">conf.setInputFormat(TextInputFormat.class);</span>
  670. </td>
  671. </tr>
  672. <tr>
  673. <td colspan="1" rowspan="1">50.</td>
  674. <td colspan="1" rowspan="1">
  675. &nbsp;&nbsp;&nbsp;&nbsp;
  676. <span class="codefrag">conf.setOutputFormat(TextOutputFormat.class);</span>
  677. </td>
  678. </tr>
  679. <tr>
  680. <td colspan="1" rowspan="1">51.</td>
  681. <td colspan="1" rowspan="1"></td>
  682. </tr>
  683. <tr>
  684. <td colspan="1" rowspan="1">52.</td>
  685. <td colspan="1" rowspan="1">
  686. &nbsp;&nbsp;&nbsp;&nbsp;
  687. <span class="codefrag">conf.setInputPath(new Path(args[1]));</span>
  688. </td>
  689. </tr>
  690. <tr>
  691. <td colspan="1" rowspan="1">53.</td>
  692. <td colspan="1" rowspan="1">
  693. &nbsp;&nbsp;&nbsp;&nbsp;
  694. <span class="codefrag">conf.setOutputPath(new Path(args[2]));</span>
  695. </td>
  696. </tr>
  697. <tr>
  698. <td colspan="1" rowspan="1">54.</td>
  699. <td colspan="1" rowspan="1"></td>
  700. </tr>
  701. <tr>
  702. <td colspan="1" rowspan="1">55.</td>
  703. <td colspan="1" rowspan="1">
  704. &nbsp;&nbsp;&nbsp;&nbsp;
  705. <span class="codefrag">JobClient.runJob(conf);</span>
  706. </td>
  707. </tr>
  708. <tr>
  709. <td colspan="1" rowspan="1">57.</td>
  710. <td colspan="1" rowspan="1">
  711. &nbsp;&nbsp;
  712. <span class="codefrag">}</span>
  713. </td>
  714. </tr>
  715. <tr>
  716. <td colspan="1" rowspan="1">58.</td>
  717. <td colspan="1" rowspan="1">
  718. <span class="codefrag">}</span>
  719. </td>
  720. </tr>
  721. <tr>
  722. <td colspan="1" rowspan="1">59.</td>
  723. <td colspan="1" rowspan="1"></td>
  724. </tr>
  725. </table>
  726. <a name="N1045C"></a><a name="Usage"></a>
  727. <h3 class="h4">Usage</h3>
  728. <p>Assuming <span class="codefrag">HADOOP_HOME</span> is the root of the installation and
  729. <span class="codefrag">HADOOP_VERSION</span> is the Hadoop version installed, compile
  730. <span class="codefrag">WordCount.java</span> and create a jar:</p>
  731. <p>
  732. <span class="codefrag">
  733. $ javac -classpath ${HADOOP_HOME}/hadoop-${HADOOP_VERSION}-core.jar
  734. WordCount.java
  735. </span>
  736. <br>
  737. <span class="codefrag">$ jar -cvf /usr/joe/wordcount.jar WordCount.class</span>
  738. </p>
  739. <p>Assuming that:</p>
  740. <ul>
  741. <li>
  742. <span class="codefrag">/usr/joe/wordcount/input</span> - input directory in HDFS
  743. </li>
  744. <li>
  745. <span class="codefrag">/usr/joe/wordcount/output</span> - output directory in HDFS
  746. </li>
  747. </ul>
  748. <p>Sample text-files as input:</p>
  749. <p>
  750. <span class="codefrag">$ bin/hadoop dfs -ls /usr/joe/wordcount/input/</span>
  751. <br>
  752. <span class="codefrag">/usr/joe/wordcount/input/file01</span>
  753. <br>
  754. <span class="codefrag">/usr/joe/wordcount/input/file02</span>
  755. <br>
  756. <br>
  757. <span class="codefrag">$ bin/hadoop dfs -cat /usr/joe/wordcount/input/file01</span>
  758. <br>
  759. <span class="codefrag">Hello World Bye World</span>
  760. <br>
  761. <br>
  762. <span class="codefrag">$ bin/hadoop dfs -cat /usr/joe/wordcount/input/file02</span>
  763. <br>
  764. <span class="codefrag">Hello Hadoop Goodbye Hadoop</span>
  765. </p>
  766. <p>Run the application:</p>
  767. <p>
  768. <span class="codefrag">
  769. $ bin/hadoop jar /usr/joe/wordcount.jar org.myorg.WordCount
  770. /usr/joe/wordcount/input /usr/joe/wordcount/output
  771. </span>
  772. </p>
  773. <p>Output:</p>
  774. <p>
  775. <span class="codefrag">
  776. $ bin/hadoop dfs -cat /usr/joe/wordcount/output/part-00000
  777. </span>
  778. <br>
  779. <span class="codefrag">Bye 1</span>
  780. <br>
  781. <span class="codefrag">Goodbye 1</span>
  782. <br>
  783. <span class="codefrag">Hadoop 2</span>
  784. <br>
  785. <span class="codefrag">Hello 2</span>
  786. <br>
  787. <span class="codefrag">World 2</span>
  788. <br>
  789. </p>
  790. <a name="N104D8"></a><a name="Walk-through"></a>
  791. <h3 class="h4">Walk-through</h3>
  792. <p>The <span class="codefrag">WordCount</span> application is quite straight-forward.</p>
  793. <p>The <span class="codefrag">Mapper</span> implementation (lines 14-26), via the
  794. <span class="codefrag">map</span> method (lines 18-25), processes one line at a time,
  795. as provided by the specified <span class="codefrag">TextInputFormat</span> (line 49).
  796. It then splits the line into tokens separated by whitespaces, via the
  797. <span class="codefrag">StringTokenizer</span>, and emits a key-value pair of
  798. <span class="codefrag">&lt; &lt;word&gt;, 1&gt;</span>.</p>
  799. <p>
  800. For the given sample input the first map emits:<br>
  801. <span class="codefrag">&lt; Hello, 1&gt;</span>
  802. <br>
  803. <span class="codefrag">&lt; World, 1&gt;</span>
  804. <br>
  805. <span class="codefrag">&lt; Bye, 1&gt;</span>
  806. <br>
  807. <span class="codefrag">&lt; World, 1&gt;</span>
  808. <br>
  809. </p>
  810. <p>
  811. The second map emits:<br>
  812. <span class="codefrag">&lt; Hello, 1&gt;</span>
  813. <br>
  814. <span class="codefrag">&lt; Hadoop, 1&gt;</span>
  815. <br>
  816. <span class="codefrag">&lt; Goodbye, 1&gt;</span>
  817. <br>
  818. <span class="codefrag">&lt; Hadoop, 1&gt;</span>
  819. <br>
  820. </p>
  821. <p>We'll learn more about the number of maps spawned for a given job, and
  822. how to control them in a fine-grained manner, a bit later in the
  823. tutorial.</p>
  824. <p>
  825. <span class="codefrag">WordCount</span> also specifies a <span class="codefrag">combiner</span> (line
  826. 46). Hence, the output of each map is passed through the local combiner
  827. (which is same as the <span class="codefrag">Reducer</span> as per the job
  828. configuration) for local aggregation, after being sorted on the
  829. <em>key</em>s.</p>
  830. <p>
  831. The output of the first map:<br>
  832. <span class="codefrag">&lt; Bye, 1&gt;</span>
  833. <br>
  834. <span class="codefrag">&lt; Hello, 1&gt;</span>
  835. <br>
  836. <span class="codefrag">&lt; World, 2&gt;</span>
  837. <br>
  838. </p>
  839. <p>
  840. The output of the second map:<br>
  841. <span class="codefrag">&lt; Goodbye, 1&gt;</span>
  842. <br>
  843. <span class="codefrag">&lt; Hadoop, 2&gt;</span>
  844. <br>
  845. <span class="codefrag">&lt; Hello, 1&gt;</span>
  846. <br>
  847. </p>
  848. <p>The <span class="codefrag">Reducer</span> implementation (lines 28-36), via the
  849. <span class="codefrag">reduce</span> method (lines 29-35) just sums up the values,
  850. which are the occurence counts for each key (i.e. words in this example).
  851. </p>
  852. <p>
  853. Thus the output of the job is:<br>
  854. <span class="codefrag">&lt; Bye, 1&gt;</span>
  855. <br>
  856. <span class="codefrag">&lt; Goodbye, 1&gt;</span>
  857. <br>
  858. <span class="codefrag">&lt; Hadoop, 2&gt;</span>
  859. <br>
  860. <span class="codefrag">&lt; Hello, 2&gt;</span>
  861. <br>
  862. <span class="codefrag">&lt; World, 2&gt;</span>
  863. <br>
  864. </p>
  865. <p>The <span class="codefrag">run</span> method specifies various facets of the job, such
  866. as the input/output paths (passed via the command line), key/value
  867. types, input/output formats etc., in the <span class="codefrag">JobConf</span>.
  868. It then calls the <span class="codefrag">JobClient.runJob</span> (line 55) to submit the
  869. and monitor its progress.</p>
  870. <p>We'll learn more about <span class="codefrag">JobConf</span>, <span class="codefrag">JobClient</span>,
  871. <span class="codefrag">Tool</span> and other interfaces and classes a bit later in the
  872. tutorial.</p>
  873. </div>
  874. <a name="N1058F"></a><a name="Map-Reduce+-+User+Interfaces"></a>
  875. <h2 class="h3">Map-Reduce - User Interfaces</h2>
  876. <div class="section">
  877. <p>This section provides a reasonable amount of detail on every user-facing
  878. aspect of the Map-Reduce framwork. This should help users implement,
  879. configure and tune their jobs in a fine-grained manner. However, please
  880. note that the javadoc for each class/interface remains the most
  881. comprehensive documentation available; this is only meant to be a tutorial.
  882. </p>
  883. <p>Let us first take the <span class="codefrag">Mapper</span> and <span class="codefrag">Reducer</span>
  884. interfaces. Applications typically implement them to provide the
  885. <span class="codefrag">map</span> and <span class="codefrag">reduce</span> methods.</p>
  886. <p>We will then discuss other core interfaces including
  887. <span class="codefrag">JobConf</span>, <span class="codefrag">JobClient</span>, <span class="codefrag">Partitioner</span>,
  888. <span class="codefrag">OutputCollector</span>, <span class="codefrag">Reporter</span>,
  889. <span class="codefrag">InputFormat</span>, <span class="codefrag">OutputFormat</span> and others.</p>
  890. <p>Finally, we will wrap up by discussing some useful features of the
  891. framework such as the <span class="codefrag">DistributedCache</span>,
  892. <span class="codefrag">IsolationRunner</span> etc.</p>
  893. <a name="N105C8"></a><a name="Payload"></a>
  894. <h3 class="h4">Payload</h3>
  895. <p>Applications typically implement the <span class="codefrag">Mapper</span> and
  896. <span class="codefrag">Reducer</span> interfaces to provide the <span class="codefrag">map</span> and
  897. <span class="codefrag">reduce</span> methods. These form the core of the job.</p>
  898. <a name="N105DD"></a><a name="Mapper"></a>
  899. <h4>Mapper</h4>
  900. <p>
  901. <a href="api/org/apache/hadoop/mapred/Mapper.html">
  902. Mapper</a> maps input key/value pairs to a set of intermediate
  903. key/value pairs.</p>
  904. <p>Maps are the individual tasks that transform input records into
  905. intermediate records. The transformed intermediate records do not need
  906. to be of the same type as the input records. A given input pair may
  907. map to zero or many output pairs.</p>
  908. <p>The Hadoop Map-Reduce framework spawns one map task for each
  909. <span class="codefrag">InputSplit</span> generated by the <span class="codefrag">InputFormat</span> for
  910. the job.</p>
  911. <p>Overall, <span class="codefrag">Mapper</span> implementations are passed the
  912. <span class="codefrag">JobConf</span> for the job via the
  913. <a href="api/org/apache/hadoop/mapred/JobConfigurable.html#configure(org.apache.hadoop.mapred.JobConf)">
  914. JobConfigurable.configure(JobConf)</a> method and override it to
  915. initialize themselves. The framework then calls
  916. <a href="api/org/apache/hadoop/mapred/Mapper.html#map(K1, V1, org.apache.hadoop.mapred.OutputCollector, org.apache.hadoop.mapred.Reporter)">
  917. map(WritableComparable, Writable, OutputCollector, Reporter)</a> for
  918. each key/value pair in the <span class="codefrag">InputSplit</span> for that task.
  919. Applications can then override the
  920. <a href="api/org/apache/hadoop/io/Closeable.html#close()">
  921. Closeable.close()</a> method to perform any required cleanup.</p>
  922. <p>Output pairs do not need to be of the same types as input pairs. A
  923. given input pair may map to zero or many output pairs. Output pairs
  924. are collected with calls to
  925. <a href="api/org/apache/hadoop/mapred/OutputCollector.html#collect(K, V)">
  926. OutputCollector.collect(WritableComparable,Writable)</a>.</p>
  927. <p>Applications can use the <span class="codefrag">Reporter</span> to report
  928. progress, set application-level status messages and update
  929. <span class="codefrag">Counters</span>, or just indicate that they are alive.</p>
  930. <p>All intermediate values associated with a given output key are
  931. subsequently grouped by the framework, and passed to the
  932. <span class="codefrag">Reducer</span>(s) to determine the final output. Users can
  933. control the grouping by specifying a <span class="codefrag">Comparator</span> via
  934. <a href="api/org/apache/hadoop/mapred/JobConf.html#setOutputKeyComparatorClass(java.lang.Class)">
  935. JobConf.setOutputKeyComparatorClass(Class)</a>.</p>
  936. <p>The <span class="codefrag">Mapper</span> outputs are sorted and then
  937. partitioned per <span class="codefrag">Reducer</span>. The total number of partitions is
  938. the same as the number of reduce tasks for the job. Users can control
  939. which keys (and hence records) go to which <span class="codefrag">Reducer</span> by
  940. implementing a custom <span class="codefrag">Partitioner</span>.</p>
  941. <p>Users can optionally specify a <span class="codefrag">combiner</span>, via
  942. <a href="api/org/apache/hadoop/mapred/JobConf.html#setCombinerClass(java.lang.Class)">
  943. JobConf.setCombinerClass(Class)</a>, to perform local aggregation of
  944. the intermediate outputs, which helps to cut down the amount of data
  945. transferred from the <span class="codefrag">Mapper</span> to the <span class="codefrag">Reducer</span>.
  946. </p>
  947. <p>The intermediate, sorted outputs are always stored in files of
  948. <a href="api/org/apache/hadoop/io/SequenceFile.html">
  949. SequenceFile</a> format. Applications can control if, and how, the
  950. intermediate outputs are to be compressed and the
  951. <a href="api/org/apache/hadoop/io/compress/CompressionCodec.html">
  952. CompressionCodec</a> to be used via the <span class="codefrag">JobConf</span>.
  953. </p>
  954. <a name="N10657"></a><a name="How+Many+Maps%3F"></a>
  955. <h5>How Many Maps?</h5>
  956. <p>The number of maps is usually driven by the total size of the
  957. inputs, that is, the total number of blocks of the input files.</p>
  958. <p>The right level of parallelism for maps seems to be around 10-100
  959. maps per-node, although it has been set up to 300 maps for very
  960. cpu-light map tasks. Task setup takes awhile, so it is best if the
  961. maps take at least a minute to execute.</p>
  962. <p>Thus, if you expect 10TB of input data and have a blocksize of
  963. <span class="codefrag">128MB</span>, you'll end up with 82,000 maps, unless
  964. <a href="api/org/apache/hadoop/mapred/JobConf.html#setNumMapTasks(int)">
  965. setNumMapTasks(int)</a> (which only provides a hint to the framework)
  966. is used to set it even higher.</p>
  967. <a name="N1066F"></a><a name="Reducer"></a>
  968. <h4>Reducer</h4>
  969. <p>
  970. <a href="api/org/apache/hadoop/mapred/Reducer.html">
  971. Reducer</a> reduces a set of intermediate values which share a key to
  972. a smaller set of values.</p>
  973. <p>The number of reduces for the job is set by the user
  974. via <a href="api/org/apache/hadoop/mapred/JobConf.html#setNumReduceTasks(int)">
  975. JobConf.setNumReduceTasks(int)</a>.</p>
  976. <p>Overall, <span class="codefrag">Reducer</span> implementations are passed the
  977. <span class="codefrag">JobConf</span> for the job via the
  978. <a href="api/org/apache/hadoop/mapred/JobConfigurable.html#configure(org.apache.hadoop.mapred.JobConf)">
  979. JobConfigurable.configure(JobConf)</a> method and can override it to
  980. initialize themselves. The framework then calls
  981. <a href="api/org/apache/hadoop/mapred/Reducer.html#reduce(K2, java.util.Iterator, org.apache.hadoop.mapred.OutputCollector, org.apache.hadoop.mapred.Reporter)">
  982. reduce(WritableComparable, Iterator, OutputCollector, Reporter)</a>
  983. method for each <span class="codefrag">&lt;key, (list of values)&gt;</span>
  984. pair in the grouped inputs. Applications can then override the
  985. <a href="api/org/apache/hadoop/io/Closeable.html#close()">
  986. Closeable.close()</a> method to perform any required cleanup.</p>
  987. <p>
  988. <span class="codefrag">Reducer</span> has 3 primary phases: shuffle, sort and reduce.
  989. </p>
  990. <a name="N1069F"></a><a name="Shuffle"></a>
  991. <h5>Shuffle</h5>
  992. <p>Input to the <span class="codefrag">Reducer</span> is the sorted output of the
  993. mappers. In this phase the framework fetches the relevant partition
  994. of the output of all the mappers, via HTTP.</p>
  995. <a name="N106AC"></a><a name="Sort"></a>
  996. <h5>Sort</h5>
  997. <p>The framework groups <span class="codefrag">Reducer</span> inputs by keys (since
  998. different mappers may have output the same key) in this stage.</p>
  999. <p>The shuffle and sort phases occur simultaneously; while
  1000. map-outputs are being fetched they are merged.</p>
  1001. <a name="N106BB"></a><a name="Secondary+Sort"></a>
  1002. <h5>Secondary Sort</h5>
  1003. <p>If equivalence rules for grouping the intermediate keys are
  1004. required to be different from those for grouping keys before
  1005. reduction, then one may specify a <span class="codefrag">Comparator</span> via
  1006. <a href="api/org/apache/hadoop/mapred/JobConf.html#setOutputValueGroupingComparator(java.lang.Class)">
  1007. JobConf.setOutputValueGroupingComparator(Class)</a>. Since
  1008. <a href="api/org/apache/hadoop/mapred/JobConf.html#setOutputKeyComparatorClass(java.lang.Class)">
  1009. JobConf.setOutputKeyComparatorClass(Class)</a> can be used to
  1010. control how intermediate keys are grouped, these can be used in
  1011. conjunction to simulate <em>secondary sort on values</em>.</p>
  1012. <a name="N106D4"></a><a name="Reduce"></a>
  1013. <h5>Reduce</h5>
  1014. <p>In this phase the
  1015. <a href="api/org/apache/hadoop/mapred/Reducer.html#reduce(K2, java.util.Iterator, org.apache.hadoop.mapred.OutputCollector, org.apache.hadoop.mapred.Reporter)">
  1016. reduce(WritableComparable, Iterator, OutputCollector, Reporter)</a>
  1017. method is called for each <span class="codefrag">&lt;key, (list of values)&gt;</span>
  1018. pair in the grouped inputs.</p>
  1019. <p>The output of the reduce task is typically written to the
  1020. <a href="api/org/apache/hadoop/fs/FileSystem.html">
  1021. FileSystem</a> via
  1022. <a href="api/org/apache/hadoop/mapred/OutputCollector.html#collect(K, V)">
  1023. OutputCollector.collect(WritableComparable, Writable)</a>.</p>
  1024. <p>Applications can use the <span class="codefrag">Reporter</span> to report
  1025. progress, set application-level status messages and update
  1026. <span class="codefrag">Counters</span>, or just indicate that they are alive.</p>
  1027. <p>The output of the <span class="codefrag">Reducer</span> is <em>not sorted</em>.</p>
  1028. <a name="N10702"></a><a name="How+Many+Reduces%3F"></a>
  1029. <h5>How Many Reduces?</h5>
  1030. <p>The right number of reduces seems to be <span class="codefrag">0.95</span> or
  1031. <span class="codefrag">1.75</span> multiplied by (&lt;<em>no. of nodes</em>&gt; *
  1032. <span class="codefrag">mapred.tasktracker.reduce.tasks.maximum</span>).</p>
  1033. <p>With <span class="codefrag">0.95</span> all of the reduces can launch immediately
  1034. and start transfering map outputs as the maps finish. With
  1035. <span class="codefrag">1.75</span> the faster nodes will finish their first round of
  1036. reduces and launch a second wave of reduces doing a much better job
  1037. of load balancing.</p>
  1038. <p>Increasing the number of reduces increases the framework overhead,
  1039. but increases load balancing and lowers the cost of failures.</p>
  1040. <p>The scaling factors above are slightly less than whole numbers to
  1041. reserve a few reduce slots in the framework for speculative-tasks and
  1042. failed tasks.</p>
  1043. <a name="N10727"></a><a name="Reducer+NONE"></a>
  1044. <h5>Reducer NONE</h5>
  1045. <p>It is legal to set the number of reduce-tasks to <em>zero</em> if
  1046. no reduction is desired.</p>
  1047. <p>In this case the outputs of the map-tasks go directly to the
  1048. <span class="codefrag">FileSystem</span>, into the output path set by
  1049. <a href="api/org/apache/hadoop/mapred/JobConf.html#setOutputPath(org.apache.hadoop.fs.Path)">
  1050. setOutputPath(Path)</a>. The framework does not sort the
  1051. map-outputs before writing them out to the <span class="codefrag">FileSystem</span>.
  1052. </p>
  1053. <a name="N10742"></a><a name="Partitioner"></a>
  1054. <h4>Partitioner</h4>
  1055. <p>
  1056. <a href="api/org/apache/hadoop/mapred/Partitioner.html">
  1057. Partitioner</a> partitions the key space.</p>
  1058. <p>Partitioner controls the partitioning of the keys of the
  1059. intermediate map-outputs. The key (or a subset of the key) is used to
  1060. derive the partition, typically by a <em>hash function</em>. The total
  1061. number of partitions is the same as the number of reduce tasks for the
  1062. job. Hence this controls which of the <span class="codefrag">m</span> reduce tasks the
  1063. intermediate key (and hence the record) is sent to for reduction.</p>
  1064. <p>
  1065. <a href="api/org/apache/hadoop/mapred/lib/HashPartitioner.html">
  1066. HashPartitioner</a> is the default <span class="codefrag">Partitioner</span>.</p>
  1067. <a name="N10761"></a><a name="Reporter"></a>
  1068. <h4>Reporter</h4>
  1069. <p>
  1070. <a href="api/org/apache/hadoop/mapred/Reporter.html">
  1071. Reporter</a> is a facility for Map-Reduce applications to report
  1072. progress, set application-level status messages and update
  1073. <span class="codefrag">Counters</span>.</p>
  1074. <p>
  1075. <span class="codefrag">Mapper</span> and <span class="codefrag">Reducer</span> implementations can use
  1076. the <span class="codefrag">Reporter</span> to report progress or just indicate
  1077. that they are alive. In scenarios where the application takes a
  1078. significant amount of time to process individual key/value pairs,
  1079. this is crucial since the framework might assume that the task has
  1080. timed-out and kill that task. Another way to avoid this is to
  1081. set the configuration parameter <span class="codefrag">mapred.task.timeout</span> to a
  1082. high-enough value (or even set it to <em>zero</em> for no time-outs).
  1083. </p>
  1084. <p>Applications can also update <span class="codefrag">Counters</span> using the
  1085. <span class="codefrag">Reporter</span>.</p>
  1086. <a name="N1078B"></a><a name="OutputCollector"></a>
  1087. <h4>OutputCollector</h4>
  1088. <p>
  1089. <a href="api/org/apache/hadoop/mapred/OutputCollector.html">
  1090. OutputCollector</a> is a generalization of the facility provided by
  1091. the Map-Reduce framework to collect data output by the
  1092. <span class="codefrag">Mapper</span> or the <span class="codefrag">Reducer</span> (either the
  1093. intermediate outputs or the output of the job).</p>
  1094. <p>Hadoop Map-Reduce comes bundled with a
  1095. <a href="api/org/apache/hadoop/mapred/lib/package-summary.html">
  1096. library</a> of generally useful mappers, reducers, and partitioners.</p>
  1097. <a name="N107A6"></a><a name="Job+Configuration"></a>
  1098. <h3 class="h4">Job Configuration</h3>
  1099. <p>
  1100. <a href="api/org/apache/hadoop/mapred/JobConf.html">
  1101. JobConf</a> represents a Map-Reduce job configuration.</p>
  1102. <p>
  1103. <span class="codefrag">JobConf</span> is the primary interface for a user to describe
  1104. a map-reduce job to the Hadoop framework for execution. The framework
  1105. tries to faithfully execute the job as described by <span class="codefrag">JobConf</span>,
  1106. however:</p>
  1107. <ul>
  1108. <li>f
  1109. Some configuration parameters may have been marked as
  1110. <a href="api/org/apache/hadoop/conf/Configuration.html#FinalParams">
  1111. final</a> by administrators and hence cannot be altered.
  1112. </li>
  1113. <li>
  1114. While some job parameters are straight-forward to set (e.g.
  1115. <a href="api/org/apache/hadoop/mapred/JobConf.html#setNumReduceTasks(int)">
  1116. setNumReduceTasks(int)</a>), other parameters interact subtly with
  1117. the rest of the framework and/or job configuration and are
  1118. more complex to set (e.g.
  1119. <a href="api/org/apache/hadoop/mapred/JobConf.html#setNumMapTasks(int)">
  1120. setNumMapTasks(int)</a>).
  1121. </li>
  1122. </ul>
  1123. <p>
  1124. <span class="codefrag">JobConf</span> is typically used to specify the
  1125. <span class="codefrag">Mapper</span>, combiner (if any), <span class="codefrag">Partitioner</span>,
  1126. <span class="codefrag">Reducer</span>, <span class="codefrag">InputFormat</span> and
  1127. <span class="codefrag">OutputFormat</span> implementations. <span class="codefrag">JobConf</span> also
  1128. indicates the set of input files
  1129. (<a href="api/org/apache/hadoop/mapred/JobConf.html#setInputPath(org.apache.hadoop.fs.Path)">setInputPath(Path)</a>/<a href="api/org/apache/hadoop/mapred/JobConf.html#addInputPath(org.apache.hadoop.fs.Path)">addInputPath(Path)</a>)
  1130. and where the output files should be written
  1131. (<a href="api/org/apache/hadoop/mapred/JobConf.html#setOutputPath(org.apache.hadoop.fs.Path)">setOutputPath(Path)</a>).</p>
  1132. <p>Optionally, <span class="codefrag">JobConf</span> is used to specify other advanced
  1133. facets of the job such as the <span class="codefrag">Comparator</span> to be used, files
  1134. to be put in the <span class="codefrag">DistributedCache</span>, whether intermediate
  1135. and/or job outputs are to be compressed (and how), debugging via
  1136. user-provided scripts
  1137. (<a href="api/org/apache/hadoop/mapred/JobConf.html#setMapDebugScript(java.lang.String)">setMapDebugScript(String)</a>/<a href="api/org/apache/hadoop/mapred/JobConf.html#setReduceDebugScript(java.lang.String)">setReduceDebugScript(String)</a>)
  1138. , whether job tasks can be executed in a <em>speculative</em> manner
  1139. (<a href="api/org/apache/hadoop/mapred/JobConf.html#setSpeculativeExecution(boolean)">setSpeculativeExecution(boolean)</a>)
  1140. , maximum number of attempts per task
  1141. (<a href="api/org/apache/hadoop/mapred/JobConf.html#setMaxMapAttempts(int)">setMaxMapAttempts(int)</a>/<a href="api/org/apache/hadoop/mapred/JobConf.html#setMaxReduceAttempts(int)">setMaxReduceAttempts(int)</a>)
  1142. , percentage of tasks failure which can be tolerated by the job
  1143. (<a href="api/org/apache/hadoop/mapred/JobConf.html#setMaxMapTaskFailuresPercent(int)">setMaxMapTaskFailuresPercent(int)</a>/<a href="api/org/apache/hadoop/mapred/JobConf.html#setMaxReduceTaskFailuresPercent(int)">setMaxReduceTaskFailuresPercent(int)</a>)
  1144. etc.</p>
  1145. <p>Of course, users can use
  1146. <a href="api/org/apache/hadoop/conf/Configuration.html#set(java.lang.String, java.lang.String)">set(String, String)</a>/<a href="api/org/apache/hadoop/conf/Configuration.html#get(java.lang.String, java.lang.String)">get(String, String)</a>
  1147. to set/get arbitrary parameters needed by applications. However, use the
  1148. <span class="codefrag">DistributedCache</span> for large amounts of (read-only) data.</p>
  1149. <a name="N1082C"></a><a name="Job+Submission+and+Monitoring"></a>
  1150. <h3 class="h4">Job Submission and Monitoring</h3>
  1151. <p>
  1152. <a href="api/org/apache/hadoop/mapred/JobClient.html">
  1153. JobClient</a> is the primary interface by which user-job interacts
  1154. with the <span class="codefrag">JobTracker</span>.</p>
  1155. <p>
  1156. <span class="codefrag">JobClient</span> provides facilities to submit jobs, track their
  1157. progress, access component-tasks' reports/logs, get the Map-Reduce
  1158. cluster's status information and so on.</p>
  1159. <p>The job submission process involves:</p>
  1160. <ol>
  1161. <li>Checking the input and output specifications of the job.</li>
  1162. <li>Computing the <span class="codefrag">InputSplit</span> values for the job.</li>
  1163. <li>
  1164. Setting up the requisite accounting information for the
  1165. <span class="codefrag">DistributedCache</span> of the job, if necessary.
  1166. </li>
  1167. <li>
  1168. Copying the job's jar and configuration to the map-reduce system
  1169. directory on the <span class="codefrag">FileSystem</span>.
  1170. </li>
  1171. <li>
  1172. Submitting the job to the <span class="codefrag">JobTracker</span> and optionally
  1173. monitoring it's status.
  1174. </li>
  1175. </ol>
  1176. <p>Normally the user creates the application, describes various facets
  1177. of the job via <span class="codefrag">JobConf</span>, and then uses the
  1178. <span class="codefrag">JobClient</span> to submit the job and monitor its progress.</p>
  1179. <a name="N1086A"></a><a name="Job+Control"></a>
  1180. <h4>Job Control</h4>
  1181. <p>Users may need to chain map-reduce jobs to accomplish complex
  1182. tasks which cannot be done via a single map-reduce job. This is fairly
  1183. easy since the output of the job typically goes to distributed
  1184. file-system, and the output, in turn, can be used as the input for the
  1185. next job.</p>
  1186. <p>However, this also means that the onus on ensuring jobs are
  1187. complete (success/failure) lies squarely on the clients. In such
  1188. cases, the various job-control options are:</p>
  1189. <ul>
  1190. <li>
  1191. <a href="api/org/apache/hadoop/mapred/JobClient.html#runJob(org.apache.hadoop.mapred.JobConf)">
  1192. runJob(JobConf)</a> : Submits the job and returns only after the
  1193. job has completed.
  1194. </li>
  1195. <li>
  1196. <a href="api/org/apache/hadoop/mapred/JobClient.html#submitJob(org.apache.hadoop.mapred.JobConf)">
  1197. submitJob(JobConf)</a> : Only submits the job, then poll the
  1198. returned handle to the
  1199. <a href="api/org/apache/hadoop/mapred/RunningJob.html">
  1200. RunningJob</a> to query status and make scheduling decisions.
  1201. </li>
  1202. <li>
  1203. <a href="api/org/apache/hadoop/mapred/JobConf.html#setJobEndNotificationURI(java.lang.String)">
  1204. JobConf.setJobEndNotificationURI(String)</a> : Sets up a
  1205. notification upon job-completion, thus avoiding polling.
  1206. </li>
  1207. </ul>
  1208. <a name="N10894"></a><a name="Job+Input"></a>
  1209. <h3 class="h4">Job Input</h3>
  1210. <p>
  1211. <a href="api/org/apache/hadoop/mapred/InputFormat.html">
  1212. InputFormat</a> describes the input-specification for a Map-Reduce job.
  1213. </p>
  1214. <p>The Map-Reduce framework relies on the <span class="codefrag">InputFormat</span> of
  1215. the job to:</p>
  1216. <ol>
  1217. <li>Validate the input-specification of the job.</li>
  1218. <li>
  1219. Split-up the input file(s) into logical <span class="codefrag">InputSplit</span>
  1220. instances, each of which is then assigned to an individual
  1221. <span class="codefrag">Mapper</span>.
  1222. </li>
  1223. <li>
  1224. Provide the <span class="codefrag">RecordReader</span> implementation used to
  1225. glean input records from the logical <span class="codefrag">InputSplit</span> for
  1226. processing by the <span class="codefrag">Mapper</span>.
  1227. </li>
  1228. </ol>
  1229. <p>The default behavior of file-based <span class="codefrag">InputFormat</span>
  1230. implementations, typically sub-classes of
  1231. <a href="api/org/apache/hadoop/mapred/FileInputFormat.html">
  1232. FileInputFormat</a>, is to split the input into <em>logical</em>
  1233. <span class="codefrag">InputSplit</span> instances based on the total size, in bytes, of
  1234. the input files. However, the <span class="codefrag">FileSystem</span> blocksize of the
  1235. input files is treated as an upper bound for input splits. A lower bound
  1236. on the split size can be set via <span class="codefrag">mapred.min.split.size</span>.</p>
  1237. <p>Clearly, logical splits based on input-size is insufficient for many
  1238. applications since record boundaries must be respected. In such cases,
  1239. the application should implement a <span class="codefrag">RecordReader</span>, who is
  1240. responsible for respecting record-boundaries and presents a
  1241. record-oriented view of the logical <span class="codefrag">InputSplit</span> to the
  1242. individual task.</p>
  1243. <p>
  1244. <a href="api/org/apache/hadoop/mapred/TextInputFormat.html">
  1245. TextInputFormat</a> is the default <span class="codefrag">InputFormat</span>.
  1246. </p>
  1247. <a name="N108E9"></a><a name="InputSplit"></a>
  1248. <h4>InputSplit</h4>
  1249. <p>
  1250. <a href="api/org/apache/hadoop/mapred/InputSplit.html">
  1251. InputSplit</a> represents the data to be processed by an individual
  1252. <span class="codefrag">Mapper</span>.</p>
  1253. <p>Typically <span class="codefrag">InputSplit</span> presents a byte-oriented view of
  1254. the input, and it is the responsibility of <span class="codefrag">RecordReader</span>
  1255. to process and present a record-oriented view.</p>
  1256. <p>
  1257. <a href="api/org/apache/hadoop/mapred/FileSplit.html">
  1258. FileSplit</a> is the default <span class="codefrag">InputSplit</span>. It sets
  1259. <span class="codefrag">map.input.file</span> to the path of the input file for the
  1260. logical split.</p>
  1261. <a name="N1090E"></a><a name="RecordReader"></a>
  1262. <h4>RecordReader</h4>
  1263. <p>
  1264. <a href="api/org/apache/hadoop/mapred/RecordReader.html">
  1265. RecordReader</a> reads <span class="codefrag">&lt;key, value&gt;</span> pairs from an
  1266. <span class="codefrag">InputSplit</span>.</p>
  1267. <p>Typically the <span class="codefrag">RecordReader</span> converts the byte-oriented
  1268. view of the input, provided by the <span class="codefrag">InputSplit</span>, and
  1269. presents a record-oriented to the <span class="codefrag">Mapper</span> implementations
  1270. for processing. <span class="codefrag">RecordReader</span> thus assumes the
  1271. responsibility of processing record boundaries and presents the tasks
  1272. with keys and values.</p>
  1273. <a name="N10931"></a><a name="Job+Output"></a>
  1274. <h3 class="h4">Job Output</h3>
  1275. <p>
  1276. <a href="api/org/apache/hadoop/mapred/OutputFormat.html">
  1277. OutputFormat</a> describes the output-specification for a Map-Reduce
  1278. job.</p>
  1279. <p>The Map-Reduce framework relies on the <span class="codefrag">OutputFormat</span> of
  1280. the job to:</p>
  1281. <ol>
  1282. <li>
  1283. Validate the output-specification of the job; for example, check that
  1284. the output directory doesn't already exist.
  1285. </li>
  1286. <li>
  1287. Provide the <span class="codefrag">RecordWriter</span> implementation used to
  1288. write the output files of the job. Output files are stored in a
  1289. <span class="codefrag">FileSystem</span>.
  1290. </li>
  1291. </ol>
  1292. <p>
  1293. <span class="codefrag">TextOutputFormat</span> is the default
  1294. <span class="codefrag">OutputFormat</span>.</p>
  1295. <a name="N1095A"></a><a name="Task+Side-Effect+Files"></a>
  1296. <h4>Task Side-Effect Files</h4>
  1297. <p>In some applications, component tasks need to create and/or write to
  1298. side-files, which differ from the actual job-output files.</p>
  1299. <p>In such cases there could be issues with two instances of the same
  1300. <span class="codefrag">Mapper</span> or <span class="codefrag">Reducer</span> running simultaneously (for
  1301. example, speculative tasks) trying to open and/or write to the same
  1302. file (path) on the <span class="codefrag">FileSystem</span>. Hence the
  1303. application-writer will have to pick unique names per task-attempt
  1304. (using the taskid, say <span class="codefrag">task_200709221812_0001_m_000000_0</span>),
  1305. not just per task.</p>
  1306. <p>To avoid these issues the Map-Reduce framework maintains a special
  1307. <span class="codefrag">${mapred.output.dir}/_${taskid}</span> sub-directory for each
  1308. task-attempt on the <span class="codefrag">FileSystem</span> where the output of the
  1309. task-attempt is stored. On successful completion of the task-attempt,
  1310. the files in the <span class="codefrag">${mapred.output.dir}/_${taskid}</span> (only)
  1311. are <em>promoted</em> to <span class="codefrag">${mapred.output.dir}</span>. Of course,
  1312. the framework discards the sub-directory of unsuccessful task-attempts.
  1313. This process is completely transparent to the application.</p>
  1314. <p>The application-writer can take advantage of this feature by
  1315. creating any side-files required in <span class="codefrag">${mapred.output.dir}</span>
  1316. during execution of a task via
  1317. <a href="api/org/apache/hadoop/mapred/JobConf.html#getOutputPath()">
  1318. JobConf.getOutputPath()</a>, and the framework will promote them
  1319. similarly for succesful task-attempts, thus eliminating the need to
  1320. pick unique paths per task-attempt.</p>
  1321. <a name="N1098F"></a><a name="RecordWriter"></a>
  1322. <h4>RecordWriter</h4>
  1323. <p>
  1324. <a href="api/org/apache/hadoop/mapred/RecordWriter.html">
  1325. RecordWriter</a> writes the output <span class="codefrag">&lt;key, value&gt;</span>
  1326. pairs to an output file.</p>
  1327. <p>RecordWriter implementations write the job outputs to the
  1328. <span class="codefrag">FileSystem</span>.</p>
  1329. <a name="N109A6"></a><a name="Other+Useful+Features"></a>
  1330. <h3 class="h4">Other Useful Features</h3>
  1331. <a name="N109AC"></a><a name="Counters"></a>
  1332. <h4>Counters</h4>
  1333. <p>
  1334. <span class="codefrag">Counters</span> represent global counters, defined either by
  1335. the Map-Reduce framework or applications. Each <span class="codefrag">Counter</span> can
  1336. be of any <span class="codefrag">Enum</span> type. Counters of a particular
  1337. <span class="codefrag">Enum</span> are bunched into groups of type
  1338. <span class="codefrag">Counters.Group</span>.</p>
  1339. <p>Applications can define arbitrary <span class="codefrag">Counters</span> (of type
  1340. <span class="codefrag">Enum</span>) and update them via
  1341. <a href="api/org/apache/hadoop/mapred/Reporter.html#incrCounter(java.lang.Enum, long)">
  1342. Reporter.incrCounter(Enum, long)</a> in the <span class="codefrag">map</span> and/or
  1343. <span class="codefrag">reduce</span> methods. These counters are then globally
  1344. aggregated by the framework.</p>
  1345. <a name="N109D7"></a><a name="DistributedCache"></a>
  1346. <h4>DistributedCache</h4>
  1347. <p>
  1348. <a href="api/org/apache/hadoop/filecache/DistributedCache.html">
  1349. DistributedCache</a> distributes application-specific, large, read-only
  1350. files efficiently.</p>
  1351. <p>
  1352. <span class="codefrag">DistributedCache</span> is a facility provided by the
  1353. Map-Reduce framework to cache files (text, archives, jars and so on)
  1354. needed by applications.</p>
  1355. <p>Applications specify the files to be cached via urls (hdfs:// or
  1356. http://) in the <span class="codefrag">JobConf</span>. The <span class="codefrag">DistributedCache</span>
  1357. assumes that the files specified via hdfs:// urls are already present
  1358. on the <span class="codefrag">FileSystem</span>.</p>
  1359. <p>The framework will copy the necessary files to the slave node
  1360. before any tasks for the job are executed on that node. Its
  1361. efficiency stems from the fact that the files are only copied once
  1362. per job and the ability to cache archives which are un-archived on
  1363. the slaves.</p>
  1364. <p>
  1365. <span class="codefrag">DistributedCache</span> can be used to distribute simple,
  1366. read-only data/text files and more complex types such as archives and
  1367. jars. Archives (zip files) are <em>un-archived</em> at the slave nodes.
  1368. Jars maybe be optionally added to the classpath of the tasks, a
  1369. rudimentary <em>software distribution</em> mechanism. Files have
  1370. <em>execution permissions</em> set. Optionally users can also direct the
  1371. <span class="codefrag">DistributedCache</span> to <em>symlink</em> the cached file(s)
  1372. into the working directory of the task.</p>
  1373. <p>
  1374. <span class="codefrag">DistributedCache</span> tracks the modification timestamps of
  1375. the cached files. Clearly the cache files should not be modified by
  1376. the application or externally while the job is executing.</p>
  1377. <a name="N10A11"></a><a name="Tool"></a>
  1378. <h4>Tool</h4>
  1379. <p>The <a href="api/org/apache/hadoop/util/Tool.html">Tool</a>
  1380. interface supports the handling of generic Hadoop command-line options.
  1381. </p>
  1382. <p>
  1383. <span class="codefrag">Tool</span> is the standard for any Map-Reduce tool or
  1384. application. The application should delegate the handling of
  1385. standard command-line options to
  1386. <a href="api/org/apache/hadoop/util/GenericOptionsParser.html">
  1387. GenericOptionsParser</a> via
  1388. <a href="api/org/apache/hadoop/util/ToolRunner.html#run(org.apache.hadoop.util.Tool, java.lang.String[])">
  1389. ToolRunner.run(Tool, String[])</a> and only handle its custom
  1390. arguments.</p>
  1391. <p>
  1392. The generic Hadoop command-line options are:<br>
  1393. <span class="codefrag">
  1394. -conf &lt;configuration file&gt;
  1395. </span>
  1396. <br>
  1397. <span class="codefrag">
  1398. -D &lt;property=value&gt;
  1399. </span>
  1400. <br>
  1401. <span class="codefrag">
  1402. -fs &lt;local|namenode:port&gt;
  1403. </span>
  1404. <br>
  1405. <span class="codefrag">
  1406. -jt &lt;local|jobtracker:port&gt;
  1407. </span>
  1408. </p>
  1409. <a name="N10A43"></a><a name="IsolationRunner"></a>
  1410. <h4>IsolationRunner</h4>
  1411. <p>
  1412. <a href="api/org/apache/hadoop/mapred/IsolationRunner.html">
  1413. IsolationRunner</a> is a utility to help debug Map-Reduce programs.</p>
  1414. <p>To use the <span class="codefrag">IsolationRunner</span>, first set
  1415. <span class="codefrag">keep.failed.tasks.files</span> to <span class="codefrag">true</span>
  1416. (also see <span class="codefrag">keep.tasks.files.pattern</span>).</p>
  1417. <p>
  1418. Next, go to the node on which the failed task ran and go to the
  1419. <span class="codefrag">TaskTracker</span>'s local directory and run the
  1420. <span class="codefrag">IsolationRunner</span>:<br>
  1421. <span class="codefrag">$ cd &lt;local path&gt;/taskTracker/${taskid}/work</span>
  1422. <br>
  1423. <span class="codefrag">
  1424. $ bin/hadoop org.apache.hadoop.mapred.IsolationRunner ../job.xml
  1425. </span>
  1426. </p>
  1427. <p>
  1428. <span class="codefrag">IsolationRunner</span> will run the failed task in a single
  1429. jvm, which can be in the debugger, over precisely the same input.</p>
  1430. <a name="N10A76"></a><a name="JobControl"></a>
  1431. <h4>JobControl</h4>
  1432. <p>
  1433. <a href="api/org/apache/hadoop/mapred/jobcontrol/package-summary.html">
  1434. JobControl</a> is a utility which encapsulates a set of Map-Reduce jobs
  1435. and their dependencies.</p>
  1436. </div>
  1437. <a name="N10A85"></a><a name="Example%3A+WordCount+v2.0"></a>
  1438. <h2 class="h3">Example: WordCount v2.0</h2>
  1439. <div class="section">
  1440. <p>Here is a more complete <span class="codefrag">WordCount</span> which uses many of the
  1441. features provided by the Map-Reduce framework we discussed so far:</p>
  1442. <a name="N10A91"></a><a name="Source+Code-N10A91"></a>
  1443. <h3 class="h4">Source Code</h3>
  1444. <table class="ForrestTable" cellspacing="1" cellpadding="4">
  1445. <tr>
  1446. <th colspan="1" rowspan="1"></th>
  1447. <th colspan="1" rowspan="1">WordCount.java</th>
  1448. </tr>
  1449. <tr>
  1450. <td colspan="1" rowspan="1">1.</td>
  1451. <td colspan="1" rowspan="1">
  1452. <span class="codefrag">package org.myorg;</span>
  1453. </td>
  1454. </tr>
  1455. <tr>
  1456. <td colspan="1" rowspan="1">2.</td>
  1457. <td colspan="1" rowspan="1"></td>
  1458. </tr>
  1459. <tr>
  1460. <td colspan="1" rowspan="1">3.</td>
  1461. <td colspan="1" rowspan="1">
  1462. <span class="codefrag">import java.io.*;</span>
  1463. </td>
  1464. </tr>
  1465. <tr>
  1466. <td colspan="1" rowspan="1">4.</td>
  1467. <td colspan="1" rowspan="1">
  1468. <span class="codefrag">import java.util.*;</span>
  1469. </td>
  1470. </tr>
  1471. <tr>
  1472. <td colspan="1" rowspan="1">5.</td>
  1473. <td colspan="1" rowspan="1"></td>
  1474. </tr>
  1475. <tr>
  1476. <td colspan="1" rowspan="1">6.</td>
  1477. <td colspan="1" rowspan="1">
  1478. <span class="codefrag">import org.apache.hadoop.fs.Path;</span>
  1479. </td>
  1480. </tr>
  1481. <tr>
  1482. <td colspan="1" rowspan="1">7.</td>
  1483. <td colspan="1" rowspan="1">
  1484. <span class="codefrag">import org.apache.hadoop.filecache.DistributedCache;</span>
  1485. </td>
  1486. </tr>
  1487. <tr>
  1488. <td colspan="1" rowspan="1">8.</td>
  1489. <td colspan="1" rowspan="1">
  1490. <span class="codefrag">import org.apache.hadoop.conf.*;</span>
  1491. </td>
  1492. </tr>
  1493. <tr>
  1494. <td colspan="1" rowspan="1">9.</td>
  1495. <td colspan="1" rowspan="1">
  1496. <span class="codefrag">import org.apache.hadoop.io.*;</span>
  1497. </td>
  1498. </tr>
  1499. <tr>
  1500. <td colspan="1" rowspan="1">10.</td>
  1501. <td colspan="1" rowspan="1">
  1502. <span class="codefrag">import org.apache.hadoop.mapred.*;</span>
  1503. </td>
  1504. </tr>
  1505. <tr>
  1506. <td colspan="1" rowspan="1">11.</td>
  1507. <td colspan="1" rowspan="1">
  1508. <span class="codefrag">import org.apache.hadoop.util.*;</span>
  1509. </td>
  1510. </tr>
  1511. <tr>
  1512. <td colspan="1" rowspan="1">12.</td>
  1513. <td colspan="1" rowspan="1"></td>
  1514. </tr>
  1515. <tr>
  1516. <td colspan="1" rowspan="1">13.</td>
  1517. <td colspan="1" rowspan="1">
  1518. <span class="codefrag">public class WordCount extends Configured implements Tool {</span>
  1519. </td>
  1520. </tr>
  1521. <tr>
  1522. <td colspan="1" rowspan="1">14.</td>
  1523. <td colspan="1" rowspan="1"></td>
  1524. </tr>
  1525. <tr>
  1526. <td colspan="1" rowspan="1">15.</td>
  1527. <td colspan="1" rowspan="1">
  1528. &nbsp;&nbsp;
  1529. <span class="codefrag">
  1530. public static class MapClass extends MapReduceBase
  1531. implements Mapper&lt;LongWritable, Text, Text, IntWritable&gt; {
  1532. </span>
  1533. </td>
  1534. </tr>
  1535. <tr>
  1536. <td colspan="1" rowspan="1">16.</td>
  1537. <td colspan="1" rowspan="1"></td>
  1538. </tr>
  1539. <tr>
  1540. <td colspan="1" rowspan="1">17.</td>
  1541. <td colspan="1" rowspan="1">
  1542. &nbsp;&nbsp;&nbsp;&nbsp;
  1543. <span class="codefrag">
  1544. static enum Counters { INPUT_WORDS }
  1545. </span>
  1546. </td>
  1547. </tr>
  1548. <tr>
  1549. <td colspan="1" rowspan="1">18.</td>
  1550. <td colspan="1" rowspan="1"></td>
  1551. </tr>
  1552. <tr>
  1553. <td colspan="1" rowspan="1">19.</td>
  1554. <td colspan="1" rowspan="1">
  1555. &nbsp;&nbsp;&nbsp;&nbsp;
  1556. <span class="codefrag">
  1557. private final static IntWritable one = new IntWritable(1);
  1558. </span>
  1559. </td>
  1560. </tr>
  1561. <tr>
  1562. <td colspan="1" rowspan="1">20.</td>
  1563. <td colspan="1" rowspan="1">
  1564. &nbsp;&nbsp;&nbsp;&nbsp;
  1565. <span class="codefrag">private Text word = new Text();</span>
  1566. </td>
  1567. </tr>
  1568. <tr>
  1569. <td colspan="1" rowspan="1">21.</td>
  1570. <td colspan="1" rowspan="1"></td>
  1571. </tr>
  1572. <tr>
  1573. <td colspan="1" rowspan="1">22.</td>
  1574. <td colspan="1" rowspan="1">
  1575. &nbsp;&nbsp;&nbsp;&nbsp;
  1576. <span class="codefrag">private boolean caseSensitive = true;</span>
  1577. </td>
  1578. </tr>
  1579. <tr>
  1580. <td colspan="1" rowspan="1">23.</td>
  1581. <td colspan="1" rowspan="1">
  1582. &nbsp;&nbsp;&nbsp;&nbsp;
  1583. <span class="codefrag">private Set&lt;String&gt; patternsToSkip = new HashSet&lt;String&gt;();</span>
  1584. </td>
  1585. </tr>
  1586. <tr>
  1587. <td colspan="1" rowspan="1">24.</td>
  1588. <td colspan="1" rowspan="1"></td>
  1589. </tr>
  1590. <tr>
  1591. <td colspan="1" rowspan="1">25.</td>
  1592. <td colspan="1" rowspan="1">
  1593. &nbsp;&nbsp;&nbsp;&nbsp;
  1594. <span class="codefrag">private long numRecords = 0;</span>
  1595. </td>
  1596. </tr>
  1597. <tr>
  1598. <td colspan="1" rowspan="1">26.</td>
  1599. <td colspan="1" rowspan="1">
  1600. &nbsp;&nbsp;&nbsp;&nbsp;
  1601. <span class="codefrag">private String inputFile;</span>
  1602. </td>
  1603. </tr>
  1604. <tr>
  1605. <td colspan="1" rowspan="1">27.</td>
  1606. <td colspan="1" rowspan="1"></td>
  1607. </tr>
  1608. <tr>
  1609. <td colspan="1" rowspan="1">28.</td>
  1610. <td colspan="1" rowspan="1">
  1611. &nbsp;&nbsp;&nbsp;&nbsp;
  1612. <span class="codefrag">public void configure(JobConf job) {</span>
  1613. </td>
  1614. </tr>
  1615. <tr>
  1616. <td colspan="1" rowspan="1">29.</td>
  1617. <td colspan="1" rowspan="1">
  1618. &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
  1619. <span class="codefrag">
  1620. caseSensitive = job.getBoolean("wordcount.case.sensitive", true);
  1621. </span>
  1622. </td>
  1623. </tr>
  1624. <tr>
  1625. <td colspan="1" rowspan="1">30.</td>
  1626. <td colspan="1" rowspan="1">
  1627. &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
  1628. <span class="codefrag">inputFile = job.get("map.input.file");</span>
  1629. </td>
  1630. </tr>
  1631. <tr>
  1632. <td colspan="1" rowspan="1">31.</td>
  1633. <td colspan="1" rowspan="1"></td>
  1634. </tr>
  1635. <tr>
  1636. <td colspan="1" rowspan="1">32.</td>
  1637. <td colspan="1" rowspan="1">
  1638. &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
  1639. <span class="codefrag">Path[] patternsFiles = new Path[0];</span>
  1640. </td>
  1641. </tr>
  1642. <tr>
  1643. <td colspan="1" rowspan="1">33.</td>
  1644. <td colspan="1" rowspan="1">
  1645. &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
  1646. <span class="codefrag">try {</span>
  1647. </td>
  1648. </tr>
  1649. <tr>
  1650. <td colspan="1" rowspan="1">34.</td>
  1651. <td colspan="1" rowspan="1">
  1652. &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
  1653. <span class="codefrag">
  1654. patternsFiles = DistributedCache.getLocalCacheFiles(job);
  1655. </span>
  1656. </td>
  1657. </tr>
  1658. <tr>
  1659. <td colspan="1" rowspan="1">35.</td>
  1660. <td colspan="1" rowspan="1">
  1661. &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
  1662. <span class="codefrag">} catch (IOException ioe) {</span>
  1663. </td>
  1664. </tr>
  1665. <tr>
  1666. <td colspan="1" rowspan="1">36.</td>
  1667. <td colspan="1" rowspan="1">
  1668. &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
  1669. <span class="codefrag">
  1670. System.err.println("Caught exception while getting cached files: "
  1671. + StringUtils.stringifyException(ioe));
  1672. </span>
  1673. </td>
  1674. </tr>
  1675. <tr>
  1676. <td colspan="1" rowspan="1">37.</td>
  1677. <td colspan="1" rowspan="1">
  1678. &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
  1679. <span class="codefrag">}</span>
  1680. </td>
  1681. </tr>
  1682. <tr>
  1683. <td colspan="1" rowspan="1">38.</td>
  1684. <td colspan="1" rowspan="1">
  1685. &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
  1686. <span class="codefrag">for (Path patternsFile : patternsFiles) {</span>
  1687. </td>
  1688. </tr>
  1689. <tr>
  1690. <td colspan="1" rowspan="1">39.</td>
  1691. <td colspan="1" rowspan="1">
  1692. &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
  1693. <span class="codefrag">parseSkipFile(patternsFile);</span>
  1694. </td>
  1695. </tr>
  1696. <tr>
  1697. <td colspan="1" rowspan="1">40.</td>
  1698. <td colspan="1" rowspan="1">
  1699. &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
  1700. <span class="codefrag">}</span>
  1701. </td>
  1702. </tr>
  1703. <tr>
  1704. <td colspan="1" rowspan="1">41.</td>
  1705. <td colspan="1" rowspan="1">
  1706. &nbsp;&nbsp;&nbsp;&nbsp;
  1707. <span class="codefrag">}</span>
  1708. </td>
  1709. </tr>
  1710. <tr>
  1711. <td colspan="1" rowspan="1">42.</td>
  1712. <td colspan="1" rowspan="1"></td>
  1713. </tr>
  1714. <tr>
  1715. <td colspan="1" rowspan="1">43.</td>
  1716. <td colspan="1" rowspan="1">
  1717. &nbsp;&nbsp;&nbsp;&nbsp;
  1718. <span class="codefrag">private void parseSkipFile(Path patternsFile) {</span>
  1719. </td>
  1720. </tr>
  1721. <tr>
  1722. <td colspan="1" rowspan="1">44.</td>
  1723. <td colspan="1" rowspan="1">
  1724. &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
  1725. <span class="codefrag">try {</span>
  1726. </td>
  1727. </tr>
  1728. <tr>
  1729. <td colspan="1" rowspan="1">45.</td>
  1730. <td colspan="1" rowspan="1">
  1731. &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
  1732. <span class="codefrag">
  1733. BufferedReader fis =
  1734. new BufferedReader(new FileReader(patternsFile.toString()));
  1735. </span>
  1736. </td>
  1737. </tr>
  1738. <tr>
  1739. <td colspan="1" rowspan="1">46.</td>
  1740. <td colspan="1" rowspan="1">
  1741. &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
  1742. <span class="codefrag">String pattern = null;</span>
  1743. </td>
  1744. </tr>
  1745. <tr>
  1746. <td colspan="1" rowspan="1">47.</td>
  1747. <td colspan="1" rowspan="1">
  1748. &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
  1749. <span class="codefrag">while ((pattern = fis.readLine()) != null) {</span>
  1750. </td>
  1751. </tr>
  1752. <tr>
  1753. <td colspan="1" rowspan="1">48.</td>
  1754. <td colspan="1" rowspan="1">
  1755. &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
  1756. <span class="codefrag">patternsToSkip.add(pattern);</span>
  1757. </td>
  1758. </tr>
  1759. <tr>
  1760. <td colspan="1" rowspan="1">49.</td>
  1761. <td colspan="1" rowspan="1">
  1762. &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
  1763. <span class="codefrag">}</span>
  1764. </td>
  1765. </tr>
  1766. <tr>
  1767. <td colspan="1" rowspan="1">50.</td>
  1768. <td colspan="1" rowspan="1">
  1769. &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
  1770. <span class="codefrag">} catch (IOException ioe) {</span>
  1771. </td>
  1772. </tr>
  1773. <tr>
  1774. <td colspan="1" rowspan="1">51.</td>
  1775. <td colspan="1" rowspan="1">
  1776. &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
  1777. <span class="codefrag">
  1778. System.err.println("Caught exception while parsing the cached file '" +
  1779. patternsFile + "' : " +
  1780. StringUtils.stringifyException(ioe));
  1781. </span>
  1782. </td>
  1783. </tr>
  1784. <tr>
  1785. <td colspan="1" rowspan="1">52.</td>
  1786. <td colspan="1" rowspan="1">
  1787. &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
  1788. <span class="codefrag">}</span>
  1789. </td>
  1790. </tr>
  1791. <tr>
  1792. <td colspan="1" rowspan="1">53.</td>
  1793. <td colspan="1" rowspan="1">
  1794. &nbsp;&nbsp;&nbsp;&nbsp;
  1795. <span class="codefrag">}</span>
  1796. </td>
  1797. </tr>
  1798. <tr>
  1799. <td colspan="1" rowspan="1">54.</td>
  1800. <td colspan="1" rowspan="1"></td>
  1801. </tr>
  1802. <tr>
  1803. <td colspan="1" rowspan="1">55.</td>
  1804. <td colspan="1" rowspan="1">
  1805. &nbsp;&nbsp;&nbsp;&nbsp;
  1806. <span class="codefrag">
  1807. public void map(LongWritable key, Text value,
  1808. OutputCollector&lt;Text, IntWritable&gt; output,
  1809. Reporter reporter) throws IOException {
  1810. </span>
  1811. </td>
  1812. </tr>
  1813. <tr>
  1814. <td colspan="1" rowspan="1">56.</td>
  1815. <td colspan="1" rowspan="1">
  1816. &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
  1817. <span class="codefrag">
  1818. String line =
  1819. (caseSensitive) ? value.toString() :
  1820. value.toString().toLowerCase();
  1821. </span>
  1822. </td>
  1823. </tr>
  1824. <tr>
  1825. <td colspan="1" rowspan="1">57.</td>
  1826. <td colspan="1" rowspan="1"></td>
  1827. </tr>
  1828. <tr>
  1829. <td colspan="1" rowspan="1">58.</td>
  1830. <td colspan="1" rowspan="1">
  1831. &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
  1832. <span class="codefrag">for (String pattern : patternsToSkip) {</span>
  1833. </td>
  1834. </tr>
  1835. <tr>
  1836. <td colspan="1" rowspan="1">59.</td>
  1837. <td colspan="1" rowspan="1">
  1838. &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
  1839. <span class="codefrag">line = line.replaceAll(pattern, "");</span>
  1840. </td>
  1841. </tr>
  1842. <tr>
  1843. <td colspan="1" rowspan="1">60.</td>
  1844. <td colspan="1" rowspan="1">
  1845. &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
  1846. <span class="codefrag">}</span>
  1847. </td>
  1848. </tr>
  1849. <tr>
  1850. <td colspan="1" rowspan="1">61.</td>
  1851. <td colspan="1" rowspan="1"></td>
  1852. </tr>
  1853. <tr>
  1854. <td colspan="1" rowspan="1">62.</td>
  1855. <td colspan="1" rowspan="1">
  1856. &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
  1857. <span class="codefrag">StringTokenizer tokenizer = new StringTokenizer(line);</span>
  1858. </td>
  1859. </tr>
  1860. <tr>
  1861. <td colspan="1" rowspan="1">63.</td>
  1862. <td colspan="1" rowspan="1">
  1863. &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
  1864. <span class="codefrag">while (tokenizer.hasMoreTokens()) {</span>
  1865. </td>
  1866. </tr>
  1867. <tr>
  1868. <td colspan="1" rowspan="1">64.</td>
  1869. <td colspan="1" rowspan="1">
  1870. &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
  1871. <span class="codefrag">word.set(tokenizer.nextToken());</span>
  1872. </td>
  1873. </tr>
  1874. <tr>
  1875. <td colspan="1" rowspan="1">65.</td>
  1876. <td colspan="1" rowspan="1">
  1877. &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
  1878. <span class="codefrag">output.collect(word, one);</span>
  1879. </td>
  1880. </tr>
  1881. <tr>
  1882. <td colspan="1" rowspan="1">66.</td>
  1883. <td colspan="1" rowspan="1">
  1884. &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
  1885. <span class="codefrag">reporter.incrCounter(Counters.INPUT_WORDS, 1);</span>
  1886. </td>
  1887. </tr>
  1888. <tr>
  1889. <td colspan="1" rowspan="1">67.</td>
  1890. <td colspan="1" rowspan="1">
  1891. &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
  1892. <span class="codefrag">}</span>
  1893. </td>
  1894. </tr>
  1895. <tr>
  1896. <td colspan="1" rowspan="1">68.</td>
  1897. <td colspan="1" rowspan="1"></td>
  1898. </tr>
  1899. <tr>
  1900. <td colspan="1" rowspan="1">69.</td>
  1901. <td colspan="1" rowspan="1">
  1902. &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
  1903. <span class="codefrag">if ((++numRecords % 100) == 0) {</span>
  1904. </td>
  1905. </tr>
  1906. <tr>
  1907. <td colspan="1" rowspan="1">70.</td>
  1908. <td colspan="1" rowspan="1">
  1909. &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
  1910. <span class="codefrag">
  1911. reporter.setStatus("Finished processing " + numRecords +
  1912. " records " + "from the input file: " +
  1913. inputFile);
  1914. </span>
  1915. </td>
  1916. </tr>
  1917. <tr>
  1918. <td colspan="1" rowspan="1">71.</td>
  1919. <td colspan="1" rowspan="1">
  1920. &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
  1921. <span class="codefrag">}</span>
  1922. </td>
  1923. </tr>
  1924. <tr>
  1925. <td colspan="1" rowspan="1">72.</td>
  1926. <td colspan="1" rowspan="1">
  1927. &nbsp;&nbsp;&nbsp;&nbsp;
  1928. <span class="codefrag">}</span>
  1929. </td>
  1930. </tr>
  1931. <tr>
  1932. <td colspan="1" rowspan="1">73.</td>
  1933. <td colspan="1" rowspan="1">
  1934. &nbsp;&nbsp;
  1935. <span class="codefrag">}</span>
  1936. </td>
  1937. </tr>
  1938. <tr>
  1939. <td colspan="1" rowspan="1">74.</td>
  1940. <td colspan="1" rowspan="1"></td>
  1941. </tr>
  1942. <tr>
  1943. <td colspan="1" rowspan="1">75.</td>
  1944. <td colspan="1" rowspan="1">
  1945. &nbsp;&nbsp;
  1946. <span class="codefrag">
  1947. public static class Reduce extends MapReduceBase implements
  1948. Reducer&lt;Text, IntWritable, Text, IntWritable&gt; {
  1949. </span>
  1950. </td>
  1951. </tr>
  1952. <tr>
  1953. <td colspan="1" rowspan="1">76.</td>
  1954. <td colspan="1" rowspan="1">
  1955. &nbsp;&nbsp;&nbsp;&nbsp;
  1956. <span class="codefrag">
  1957. public void reduce(Text key, Iterator&lt;IntWritable&gt; values,
  1958. OutputCollector&lt;Text, IntWritable&gt; output,
  1959. Reporter reporter) throws IOException {
  1960. </span>
  1961. </td>
  1962. </tr>
  1963. <tr>
  1964. <td colspan="1" rowspan="1">77.</td>
  1965. <td colspan="1" rowspan="1">
  1966. &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
  1967. <span class="codefrag">int sum = 0;</span>
  1968. </td>
  1969. </tr>
  1970. <tr>
  1971. <td colspan="1" rowspan="1">78.</td>
  1972. <td colspan="1" rowspan="1">
  1973. &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
  1974. <span class="codefrag">while (values.hasNext()) {</span>
  1975. </td>
  1976. </tr>
  1977. <tr>
  1978. <td colspan="1" rowspan="1">79.</td>
  1979. <td colspan="1" rowspan="1">
  1980. &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
  1981. <span class="codefrag">sum += values.next().get();</span>
  1982. </td>
  1983. </tr>
  1984. <tr>
  1985. <td colspan="1" rowspan="1">80.</td>
  1986. <td colspan="1" rowspan="1">
  1987. &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
  1988. <span class="codefrag">}</span>
  1989. </td>
  1990. </tr>
  1991. <tr>
  1992. <td colspan="1" rowspan="1">81.</td>
  1993. <td colspan="1" rowspan="1">
  1994. &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
  1995. <span class="codefrag">output.collect(key, new IntWritable(sum));</span>
  1996. </td>
  1997. </tr>
  1998. <tr>
  1999. <td colspan="1" rowspan="1">82.</td>
  2000. <td colspan="1" rowspan="1">
  2001. &nbsp;&nbsp;&nbsp;&nbsp;
  2002. <span class="codefrag">}</span>
  2003. </td>
  2004. </tr>
  2005. <tr>
  2006. <td colspan="1" rowspan="1">83.</td>
  2007. <td colspan="1" rowspan="1">
  2008. &nbsp;&nbsp;
  2009. <span class="codefrag">}</span>
  2010. </td>
  2011. </tr>
  2012. <tr>
  2013. <td colspan="1" rowspan="1">84.</td>
  2014. <td colspan="1" rowspan="1"></td>
  2015. </tr>
  2016. <tr>
  2017. <td colspan="1" rowspan="1">85.</td>
  2018. <td colspan="1" rowspan="1">
  2019. &nbsp;&nbsp;
  2020. <span class="codefrag">public int run(String[] args) throws Exception {</span>
  2021. </td>
  2022. </tr>
  2023. <tr>
  2024. <td colspan="1" rowspan="1">86.</td>
  2025. <td colspan="1" rowspan="1">
  2026. &nbsp;&nbsp;&nbsp;&nbsp;
  2027. <span class="codefrag">
  2028. JobConf conf = new JobConf(getConf(), WordCount.class);
  2029. </span>
  2030. </td>
  2031. </tr>
  2032. <tr>
  2033. <td colspan="1" rowspan="1">87.</td>
  2034. <td colspan="1" rowspan="1">
  2035. &nbsp;&nbsp;&nbsp;&nbsp;
  2036. <span class="codefrag">conf.setJobName("wordcount");</span>
  2037. </td>
  2038. </tr>
  2039. <tr>
  2040. <td colspan="1" rowspan="1">88.</td>
  2041. <td colspan="1" rowspan="1"></td>
  2042. </tr>
  2043. <tr>
  2044. <td colspan="1" rowspan="1">89.</td>
  2045. <td colspan="1" rowspan="1">
  2046. &nbsp;&nbsp;&nbsp;&nbsp;
  2047. <span class="codefrag">conf.setOutputKeyClass(Text.class);</span>
  2048. </td>
  2049. </tr>
  2050. <tr>
  2051. <td colspan="1" rowspan="1">90.</td>
  2052. <td colspan="1" rowspan="1">
  2053. &nbsp;&nbsp;&nbsp;&nbsp;
  2054. <span class="codefrag">conf.setOutputValueClass(IntWritable.class);</span>
  2055. </td>
  2056. </tr>
  2057. <tr>
  2058. <td colspan="1" rowspan="1">91.</td>
  2059. <td colspan="1" rowspan="1"></td>
  2060. </tr>
  2061. <tr>
  2062. <td colspan="1" rowspan="1">92.</td>
  2063. <td colspan="1" rowspan="1">
  2064. &nbsp;&nbsp;&nbsp;&nbsp;
  2065. <span class="codefrag">conf.setMapperClass(MapClass.class);</span>
  2066. </td>
  2067. </tr>
  2068. <tr>
  2069. <td colspan="1" rowspan="1">93.</td>
  2070. <td colspan="1" rowspan="1">
  2071. &nbsp;&nbsp;&nbsp;&nbsp;
  2072. <span class="codefrag">conf.setCombinerClass(Reduce.class);</span>
  2073. </td>
  2074. </tr>
  2075. <tr>
  2076. <td colspan="1" rowspan="1">94.</td>
  2077. <td colspan="1" rowspan="1">
  2078. &nbsp;&nbsp;&nbsp;&nbsp;
  2079. <span class="codefrag">conf.setReducerClass(Reduce.class);</span>
  2080. </td>
  2081. </tr>
  2082. <tr>
  2083. <td colspan="1" rowspan="1">95.</td>
  2084. <td colspan="1" rowspan="1"></td>
  2085. </tr>
  2086. <tr>
  2087. <td colspan="1" rowspan="1">96.</td>
  2088. <td colspan="1" rowspan="1">
  2089. &nbsp;&nbsp;&nbsp;&nbsp;
  2090. <span class="codefrag">conf.setInputFormat(TextInputFormat.class);</span>
  2091. </td>
  2092. </tr>
  2093. <tr>
  2094. <td colspan="1" rowspan="1">97.</td>
  2095. <td colspan="1" rowspan="1">
  2096. &nbsp;&nbsp;&nbsp;&nbsp;
  2097. <span class="codefrag">conf.setOutputFormat(TextOutputFormat.class);</span>
  2098. </td>
  2099. </tr>
  2100. <tr>
  2101. <td colspan="1" rowspan="1">98.</td>
  2102. <td colspan="1" rowspan="1"></td>
  2103. </tr>
  2104. <tr>
  2105. <td colspan="1" rowspan="1">99.</td>
  2106. <td colspan="1" rowspan="1">
  2107. &nbsp;&nbsp;&nbsp;&nbsp;
  2108. <span class="codefrag">
  2109. List&lt;String&gt; other_args = new ArrayList&lt;String&gt;();
  2110. </span>
  2111. </td>
  2112. </tr>
  2113. <tr>
  2114. <td colspan="1" rowspan="1">100.</td>
  2115. <td colspan="1" rowspan="1">
  2116. &nbsp;&nbsp;&nbsp;&nbsp;
  2117. <span class="codefrag">for (int i=0; i &lt; args.length; ++i) {</span>
  2118. </td>
  2119. </tr>
  2120. <tr>
  2121. <td colspan="1" rowspan="1">101.</td>
  2122. <td colspan="1" rowspan="1">
  2123. &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
  2124. <span class="codefrag">if ("-skip".equals(args[i]) {</span>
  2125. </td>
  2126. </tr>
  2127. <tr>
  2128. <td colspan="1" rowspan="1">102.</td>
  2129. <td colspan="1" rowspan="1">
  2130. &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
  2131. <span class="codefrag">
  2132. DistributedCache.addCacheFile(new Path(args[++i]).toUri(), conf);
  2133. </span>
  2134. </td>
  2135. </tr>
  2136. <tr>
  2137. <td colspan="1" rowspan="1">103.</td>
  2138. <td colspan="1" rowspan="1">
  2139. &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
  2140. <span class="codefrag">} else {</span>
  2141. </td>
  2142. </tr>
  2143. <tr>
  2144. <td colspan="1" rowspan="1">104.</td>
  2145. <td colspan="1" rowspan="1">
  2146. &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
  2147. <span class="codefrag">other_args.add(args[i]);</span>
  2148. </td>
  2149. </tr>
  2150. <tr>
  2151. <td colspan="1" rowspan="1">105.</td>
  2152. <td colspan="1" rowspan="1">
  2153. &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
  2154. <span class="codefrag">}</span>
  2155. </td>
  2156. </tr>
  2157. <tr>
  2158. <td colspan="1" rowspan="1">106.</td>
  2159. <td colspan="1" rowspan="1">
  2160. &nbsp;&nbsp;&nbsp;&nbsp;
  2161. <span class="codefrag">}</span>
  2162. </td>
  2163. </tr>
  2164. <tr>
  2165. <td colspan="1" rowspan="1">107.</td>
  2166. <td colspan="1" rowspan="1"></td>
  2167. </tr>
  2168. <tr>
  2169. <td colspan="1" rowspan="1">108.</td>
  2170. <td colspan="1" rowspan="1">
  2171. &nbsp;&nbsp;&nbsp;&nbsp;
  2172. <span class="codefrag">conf.setInputPath(new Path(other_args[0]));</span>
  2173. </td>
  2174. </tr>
  2175. <tr>
  2176. <td colspan="1" rowspan="1">109.</td>
  2177. <td colspan="1" rowspan="1">
  2178. &nbsp;&nbsp;&nbsp;&nbsp;
  2179. <span class="codefrag">conf.setOutputPath(new Path(other_args[1]));</span>
  2180. </td>
  2181. </tr>
  2182. <tr>
  2183. <td colspan="1" rowspan="1">110.</td>
  2184. <td colspan="1" rowspan="1"></td>
  2185. </tr>
  2186. <tr>
  2187. <td colspan="1" rowspan="1">111.</td>
  2188. <td colspan="1" rowspan="1">
  2189. &nbsp;&nbsp;&nbsp;&nbsp;
  2190. <span class="codefrag">JobClient.runJob(conf);</span>
  2191. </td>
  2192. </tr>
  2193. <tr>
  2194. <td colspan="1" rowspan="1">112.</td>
  2195. <td colspan="1" rowspan="1">
  2196. &nbsp;&nbsp;&nbsp;&nbsp;
  2197. <span class="codefrag">return 0;</span>
  2198. </td>
  2199. </tr>
  2200. <tr>
  2201. <td colspan="1" rowspan="1">113.</td>
  2202. <td colspan="1" rowspan="1">
  2203. &nbsp;&nbsp;
  2204. <span class="codefrag">}</span>
  2205. </td>
  2206. </tr>
  2207. <tr>
  2208. <td colspan="1" rowspan="1">114.</td>
  2209. <td colspan="1" rowspan="1"></td>
  2210. </tr>
  2211. <tr>
  2212. <td colspan="1" rowspan="1">115.</td>
  2213. <td colspan="1" rowspan="1">
  2214. &nbsp;&nbsp;
  2215. <span class="codefrag">
  2216. public static void main(String[] args) throws Exception {
  2217. </span>
  2218. </td>
  2219. </tr>
  2220. <tr>
  2221. <td colspan="1" rowspan="1">116.</td>
  2222. <td colspan="1" rowspan="1">
  2223. &nbsp;&nbsp;&nbsp;&nbsp;
  2224. <span class="codefrag">
  2225. int res = ToolRunner.run(new Configuration(), new WordCount(),
  2226. args);
  2227. </span>
  2228. </td>
  2229. </tr>
  2230. <tr>
  2231. <td colspan="1" rowspan="1">117.</td>
  2232. <td colspan="1" rowspan="1">
  2233. &nbsp;&nbsp;&nbsp;&nbsp;
  2234. <span class="codefrag">System.exit(res);</span>
  2235. </td>
  2236. </tr>
  2237. <tr>
  2238. <td colspan="1" rowspan="1">118.</td>
  2239. <td colspan="1" rowspan="1">
  2240. &nbsp;&nbsp;
  2241. <span class="codefrag">}</span>
  2242. </td>
  2243. </tr>
  2244. <tr>
  2245. <td colspan="1" rowspan="1">119.</td>
  2246. <td colspan="1" rowspan="1">
  2247. <span class="codefrag">}</span>
  2248. </td>
  2249. </tr>
  2250. <tr>
  2251. <td colspan="1" rowspan="1">120.</td>
  2252. <td colspan="1" rowspan="1"></td>
  2253. </tr>
  2254. </table>
  2255. <a name="N111C3"></a><a name="Sample+Runs"></a>
  2256. <h3 class="h4">Sample Runs</h3>
  2257. <p>Sample text-files as input:</p>
  2258. <p>
  2259. <span class="codefrag">$ bin/hadoop dfs -ls /usr/joe/wordcount/input/</span>
  2260. <br>
  2261. <span class="codefrag">/usr/joe/wordcount/input/file01</span>
  2262. <br>
  2263. <span class="codefrag">/usr/joe/wordcount/input/file02</span>
  2264. <br>
  2265. <br>
  2266. <span class="codefrag">$ bin/hadoop dfs -cat /usr/joe/wordcount/input/file01</span>
  2267. <br>
  2268. <span class="codefrag">Hello World, Bye World!</span>
  2269. <br>
  2270. <br>
  2271. <span class="codefrag">$ bin/hadoop dfs -cat /usr/joe/wordcount/input/file02</span>
  2272. <br>
  2273. <span class="codefrag">Hello Hadoop, Goodbye the Hadoop.</span>
  2274. </p>
  2275. <p>Run the application:</p>
  2276. <p>
  2277. <span class="codefrag">
  2278. $ bin/hadoop jar /usr/joe/wordcount.jar org.myorg.WordCount
  2279. /usr/joe/wordcount/input /usr/joe/wordcount/output
  2280. </span>
  2281. </p>
  2282. <p>Output:</p>
  2283. <p>
  2284. <span class="codefrag">
  2285. $ bin/hadoop dfs -cat /usr/joe/wordcount/output/part-00000
  2286. </span>
  2287. <br>
  2288. <span class="codefrag">Bye 1</span>
  2289. <br>
  2290. <span class="codefrag">Goodbye 1</span>
  2291. <br>
  2292. <span class="codefrag">Hadoop, 1</span>
  2293. <br>
  2294. <span class="codefrag">Hadoop. 1</span>
  2295. <br>
  2296. <span class="codefrag">Hello 2</span>
  2297. <br>
  2298. <span class="codefrag">World! 1</span>
  2299. <br>
  2300. <span class="codefrag">World, 1</span>
  2301. <br>
  2302. <span class="codefrag">the 1</span>
  2303. <br>
  2304. </p>
  2305. <p>Notice that the inputs differ from the first version we looked at,
  2306. and how they affect the outputs.</p>
  2307. <p>Now, lets plug-in a pattern-file which lists the word-patterns to be
  2308. ignored, via the <span class="codefrag">DistributedCache</span>.</p>
  2309. <p>
  2310. <span class="codefrag">$ hadoop dfs -cat /user/joe/wordcount/patterns.txt</span>
  2311. <br>
  2312. <span class="codefrag">\.</span>
  2313. <br>
  2314. <span class="codefrag">\,</span>
  2315. <br>
  2316. <span class="codefrag">\!</span>
  2317. <br>
  2318. <span class="codefrag">the</span>
  2319. <br>
  2320. </p>
  2321. <p>Run it again, this time with more options:</p>
  2322. <p>
  2323. <span class="codefrag">
  2324. $ bin/hadoop jar /usr/joe/wordcount.jar org.myorg.WordCount
  2325. -Dwordcount.case.sensitive=true /usr/joe/wordcount/input
  2326. /usr/joe/wordcount/output -skip /user/joe/wordcount/patterns.txt
  2327. </span>
  2328. </p>
  2329. <p>As expected, the output:</p>
  2330. <p>
  2331. <span class="codefrag">
  2332. $ bin/hadoop dfs -cat /usr/joe/wordcount/output/part-00000
  2333. </span>
  2334. <br>
  2335. <span class="codefrag">Bye 1</span>
  2336. <br>
  2337. <span class="codefrag">Goodbye 1</span>
  2338. <br>
  2339. <span class="codefrag">Hadoop 2</span>
  2340. <br>
  2341. <span class="codefrag">Hello 2</span>
  2342. <br>
  2343. <span class="codefrag">World 2</span>
  2344. <br>
  2345. </p>
  2346. <p>Run it once more, this time switch-off case-sensitivity:</p>
  2347. <p>
  2348. <span class="codefrag">
  2349. $ bin/hadoop jar /usr/joe/wordcount.jar org.myorg.WordCount
  2350. -Dwordcount.case.sensitive=false /usr/joe/wordcount/input
  2351. /usr/joe/wordcount/output -skip /user/joe/wordcount/patterns.txt
  2352. </span>
  2353. </p>
  2354. <p>Sure enough, the output:</p>
  2355. <p>
  2356. <span class="codefrag">
  2357. $ bin/hadoop dfs -cat /usr/joe/wordcount/output/part-00000
  2358. </span>
  2359. <br>
  2360. <span class="codefrag">bye 1</span>
  2361. <br>
  2362. <span class="codefrag">goodbye 1</span>
  2363. <br>
  2364. <span class="codefrag">hadoop 2</span>
  2365. <br>
  2366. <span class="codefrag">hello 2</span>
  2367. <br>
  2368. <span class="codefrag">world 2</span>
  2369. <br>
  2370. </p>
  2371. <a name="N11293"></a><a name="Salient+Points"></a>
  2372. <h3 class="h4">Salient Points</h3>
  2373. <p>The second version of <span class="codefrag">WordCount</span> improves upon the
  2374. previous one by using some features offered by the Map-Reduce framework:
  2375. </p>
  2376. <ul>
  2377. <li>
  2378. Demonstrates how applications can access configuration parameters
  2379. in the <span class="codefrag">configure</span> method of the <span class="codefrag">Mapper</span> (and
  2380. <span class="codefrag">Reducer</span>) implementations (lines 28-41).
  2381. </li>
  2382. <li>
  2383. Demonstrates how the <span class="codefrag">DistributedCache</span> can be used to
  2384. distribute read-only data needed by the jobs. Here it allows the user
  2385. to specify word-patterns to skip while counting (line 102).
  2386. </li>
  2387. <li>
  2388. Demonstrates the utility of the <span class="codefrag">Tool</span> interface and the
  2389. <span class="codefrag">GenericOptionsParser</span> to handle generic Hadoop
  2390. command-line options (lines 85-86, 116).
  2391. </li>
  2392. <li>
  2393. Demonstrates how applications can use <span class="codefrag">Counters</span> (line 66)
  2394. and how they can set application-specific status information via
  2395. the <span class="codefrag">Reporter</span> instance passed to the <span class="codefrag">map</span> (and
  2396. <span class="codefrag">reduce</span>) method (line 70).
  2397. </li>
  2398. </ul>
  2399. </div>
  2400. <p>
  2401. <em>Java and JNI are trademarks or registered trademarks of
  2402. Sun Microsystems, Inc. in the United States and other countries.</em>
  2403. </p>
  2404. </div>
  2405. <div class="clearboth">&nbsp;</div>
  2406. </div>
  2407. <div id="footer">
  2408. <div class="lastmodified">
  2409. <script type="text/javascript"><!--
  2410. document.write("<text>Last Published:</text> " + document.lastModified);
  2411. // --></script>
  2412. </div>
  2413. <div class="copyright">
  2414. Copyright &copy;
  2415. 2007 <a href="http://www.apache.org/licenses/">The Apache Software Foundation.</a>
  2416. </div>
  2417. </div>
  2418. </body>
  2419. </html>