streaming.html 40 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936
  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.8">
  7. <meta name="Forrest-skin-name" content="pelt">
  8. <meta name="http-equiv" content="Content-Type">
  9. <meta name="content" content="text/html;">
  10. <meta name="charset" content="utf-8">
  11. <title>Hadoop Streaming</title>
  12. <link type="text/css" href="skin/basic.css" rel="stylesheet">
  13. <link media="screen" type="text/css" href="skin/screen.css" rel="stylesheet">
  14. <link media="print" type="text/css" href="skin/print.css" rel="stylesheet">
  15. <link type="text/css" href="skin/profile.css" rel="stylesheet">
  16. <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>
  17. <link rel="shortcut icon" href="images/favicon.ico">
  18. </head>
  19. <body onload="init()">
  20. <script type="text/javascript">ndeSetTextSize();</script>
  21. <div id="top">
  22. <!--+
  23. |breadtrail
  24. +-->
  25. <div class="breadtrail">
  26. <a href="http://www.apache.org/">Apache</a> &gt; <a href="http://hadoop.apache.org/">Hadoop</a> &gt; <a href="http://hadoop.apache.org/core/">Core</a><script src="skin/breadcrumbs.js" language="JavaScript" type="text/javascript"></script>
  27. </div>
  28. <!--+
  29. |header
  30. +-->
  31. <div class="header">
  32. <!--+
  33. |start group logo
  34. +-->
  35. <div class="grouplogo">
  36. <a href="http://hadoop.apache.org/"><img class="logoImage" alt="Hadoop" src="images/hadoop-logo.jpg" title="Apache Hadoop"></a>
  37. </div>
  38. <!--+
  39. |end group logo
  40. +-->
  41. <!--+
  42. |start Project Logo
  43. +-->
  44. <div class="projectlogo">
  45. <a href="http://hadoop.apache.org/core/"><img class="logoImage" alt="Hadoop" src="images/core-logo.gif" title="Scalable Computing Platform"></a>
  46. </div>
  47. <!--+
  48. |end Project Logo
  49. +-->
  50. <!--+
  51. |start Search
  52. +-->
  53. <div class="searchbox">
  54. <form action="http://www.google.com/search" method="get" class="roundtopsmall">
  55. <input value="hadoop.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;
  56. <input name="Search" value="Search" type="submit">
  57. </form>
  58. </div>
  59. <!--+
  60. |end search
  61. +-->
  62. <!--+
  63. |start Tabs
  64. +-->
  65. <ul id="tabs">
  66. <li>
  67. <a class="unselected" href="http://hadoop.apache.org/core/">项目</a>
  68. </li>
  69. <li>
  70. <a class="unselected" href="http://wiki.apache.org/hadoop">维基</a>
  71. </li>
  72. <li class="current">
  73. <a class="selected" href="index.html">Hadoop 0.18文档</a>
  74. </li>
  75. </ul>
  76. <!--+
  77. |end Tabs
  78. +-->
  79. </div>
  80. </div>
  81. <div id="main">
  82. <div id="publishedStrip">
  83. <!--+
  84. |start Subtabs
  85. +-->
  86. <div id="level2tabs"></div>
  87. <!--+
  88. |end Endtabs
  89. +-->
  90. <script type="text/javascript"><!--
  91. document.write("Last Published: " + document.lastModified);
  92. // --></script>
  93. </div>
  94. <!--+
  95. |breadtrail
  96. +-->
  97. <div class="breadtrail">
  98. &nbsp;
  99. </div>
  100. <!--+
  101. |start Menu, mainarea
  102. +-->
  103. <!--+
  104. |start Menu
  105. +-->
  106. <div id="menu">
  107. <div onclick="SwitchMenu('menu_selected_1.1', 'skin/')" id="menu_selected_1.1Title" class="menutitle" style="background-image: url('skin/images/chapter_open.gif');">文档</div>
  108. <div id="menu_selected_1.1" class="selectedmenuitemgroup" style="display: block;">
  109. <div class="menuitem">
  110. <a href="index.html">概述</a>
  111. </div>
  112. <div class="menuitem">
  113. <a href="quickstart.html">快速入门</a>
  114. </div>
  115. <div class="menuitem">
  116. <a href="cluster_setup.html">集群搭建</a>
  117. </div>
  118. <div class="menuitem">
  119. <a href="hdfs_design.html">HDFS构架设计</a>
  120. </div>
  121. <div class="menuitem">
  122. <a href="hdfs_user_guide.html">HDFS使用指南</a>
  123. </div>
  124. <div class="menuitem">
  125. <a href="hdfs_permissions_guide.html">HDFS权限指南</a>
  126. </div>
  127. <div class="menuitem">
  128. <a href="hdfs_quota_admin_guide.html">HDFS配额管理指南</a>
  129. </div>
  130. <div class="menuitem">
  131. <a href="commands_manual.html">命令手册</a>
  132. </div>
  133. <div class="menuitem">
  134. <a href="hdfs_shell.html">FS Shell使用指南</a>
  135. </div>
  136. <div class="menuitem">
  137. <a href="distcp.html">DistCp使用指南</a>
  138. </div>
  139. <div class="menuitem">
  140. <a href="mapred_tutorial.html">Map-Reduce教程</a>
  141. </div>
  142. <div class="menuitem">
  143. <a href="native_libraries.html">Hadoop本地库</a>
  144. </div>
  145. <div class="menupage">
  146. <div class="menupagetitle">Streaming</div>
  147. </div>
  148. <div class="menuitem">
  149. <a href="hadoop_archives.html">Hadoop Archives</a>
  150. </div>
  151. <div class="menuitem">
  152. <a href="hod.html">Hadoop On Demand</a>
  153. </div>
  154. <div class="menuitem">
  155. <a href="http://hadoop.apache.org/core/docs/r0.18.2/api/index.html">API参考</a>
  156. </div>
  157. <div class="menuitem">
  158. <a href="http://hadoop.apache.org/core/docs/r0.18.2/jdiff/changes.html">API Changes</a>
  159. </div>
  160. <div class="menuitem">
  161. <a href="http://wiki.apache.org/hadoop/">维基</a>
  162. </div>
  163. <div class="menuitem">
  164. <a href="http://wiki.apache.org/hadoop/FAQ">常见问题</a>
  165. </div>
  166. <div class="menuitem">
  167. <a href="http://hadoop.apache.org/core/mailing_lists.html">邮件列表</a>
  168. </div>
  169. <div class="menuitem">
  170. <a href="http://hadoop.apache.org/core/docs/r0.18.2/releasenotes.html">发行说明</a>
  171. </div>
  172. <div class="menuitem">
  173. <a href="http://hadoop.apache.org/core/docs/r0.18.2/changes.html">变更日志</a>
  174. </div>
  175. </div>
  176. <div id="credit"></div>
  177. <div id="roundbottom">
  178. <img style="display: none" class="corner" height="15" width="15" alt="" src="skin/images/rc-b-l-15-1body-2menu-3menu.png"></div>
  179. <!--+
  180. |alternative credits
  181. +-->
  182. <div id="credit2"></div>
  183. </div>
  184. <!--+
  185. |end Menu
  186. +-->
  187. <!--+
  188. |start content
  189. +-->
  190. <div id="content">
  191. <div title="Portable Document Format" class="pdflink">
  192. <a class="dida" href="streaming.pdf"><img alt="PDF -icon" src="skin/images/pdfdoc.gif" class="skin"><br>
  193. PDF</a>
  194. </div>
  195. <h1>Hadoop Streaming</h1>
  196. <div id="minitoc-area">
  197. <ul class="minitoc">
  198. <li>
  199. <a href="#Hadoop+Streaming">Hadoop Streaming</a>
  200. </li>
  201. <li>
  202. <a href="#Streaming%E5%B7%A5%E4%BD%9C%E5%8E%9F%E7%90%86">Streaming工作原理</a>
  203. </li>
  204. <li>
  205. <a href="#%E5%B0%86%E6%96%87%E4%BB%B6%E6%89%93%E5%8C%85%E5%88%B0%E6%8F%90%E4%BA%A4%E7%9A%84%E4%BD%9C%E4%B8%9A%E4%B8%AD">将文件打包到提交的作业中</a>
  206. </li>
  207. <li>
  208. <a href="#Streaming%E9%80%89%E9%A1%B9%E4%B8%8E%E7%94%A8%E6%B3%95">Streaming选项与用法</a>
  209. <ul class="minitoc">
  210. <li>
  211. <a href="#%E5%8F%AA%E4%BD%BF%E7%94%A8Mapper%E7%9A%84%E4%BD%9C%E4%B8%9A">只使用Mapper的作业</a>
  212. </li>
  213. <li>
  214. <a href="#%E4%B8%BA%E4%BD%9C%E4%B8%9A%E6%8C%87%E5%AE%9A%E5%85%B6%E4%BB%96%E6%8F%92%E4%BB%B6">为作业指定其他插件</a>
  215. </li>
  216. <li>
  217. <a href="#Hadoop+Streaming%E4%B8%AD%E7%9A%84%E5%A4%A7%E6%96%87%E4%BB%B6%E5%92%8C%E6%A1%A3%E6%A1%88">Hadoop Streaming中的大文件和档案</a>
  218. </li>
  219. <li>
  220. <a href="#%E4%B8%BA%E4%BD%9C%E4%B8%9A%E6%8C%87%E5%AE%9A%E9%99%84%E5%8A%A0%E9%85%8D%E7%BD%AE%E5%8F%82%E6%95%B0">为作业指定附加配置参数</a>
  221. </li>
  222. <li>
  223. <a href="#%E5%85%B6%E4%BB%96%E9%80%89%E9%A1%B9">其他选项</a>
  224. </li>
  225. </ul>
  226. </li>
  227. <li>
  228. <a href="#%E5%85%B6%E4%BB%96%E4%BE%8B%E5%AD%90">其他例子</a>
  229. <ul class="minitoc">
  230. <li>
  231. <a href="#%E4%BD%BF%E7%94%A8%E8%87%AA%E5%AE%9A%E4%B9%89%E7%9A%84%E6%96%B9%E6%B3%95%E5%88%87%E5%88%86%E8%A1%8C%E6%9D%A5%E5%BD%A2%E6%88%90Key%2FValue%E5%AF%B9">使用自定义的方法切分行来形成Key/Value对</a>
  232. </li>
  233. <li>
  234. <a href="#%E4%B8%80%E4%B8%AA%E5%AE%9E%E7%94%A8%E7%9A%84Partitioner%E7%B1%BB">一个实用的Partitioner类 (二次排序,-partitioner org.apache.hadoop.mapred.lib.KeyFieldBasedPartitioner 选项) </a>
  235. </li>
  236. <li>
  237. <a href="#Hadoop%E8%81%9A%E5%90%88%E5%8A%9F%E8%83%BD%E5%8C%85%E7%9A%84%E4%BD%BF%E7%94%A8%EF%BC%88-reduce+aggregate+%E9%80%89%E9%A1%B9%EF%BC%89">Hadoop聚合功能包的使用(-reduce aggregate 选项)</a>
  238. </li>
  239. <li>
  240. <a href="#%E5%AD%97%E6%AE%B5%E7%9A%84%E9%80%89%E5%8F%96%EF%BC%88%E7%B1%BB%E4%BC%BC%E4%BA%8Eunix%E4%B8%AD%E7%9A%84+%27cut%27+%E5%91%BD%E4%BB%A4%EF%BC%89">字段的选取(类似于unix中的 'cut' 命令) </a>
  241. </li>
  242. </ul>
  243. </li>
  244. <li>
  245. <a href="#%E5%B8%B8%E8%A7%81%E9%97%AE%E9%A2%98">常见问题</a>
  246. <ul class="minitoc">
  247. <li>
  248. <a href="#%E6%88%91%E8%AF%A5%E6%80%8E%E6%A0%B7%E4%BD%BF%E7%94%A8Hadoop+Streaming%E8%BF%90%E8%A1%8C%E4%B8%80%E7%BB%84%E7%8B%AC%E7%AB%8B%EF%BC%88%E7%9B%B8%E5%85%B3%EF%BC%89%E7%9A%84%E4%BB%BB%E5%8A%A1%E5%91%A2%EF%BC%9F">我该怎样使用Hadoop Streaming运行一组独立(相关)的任务呢?</a>
  249. </li>
  250. <li>
  251. <a href="#%E5%A6%82%E4%BD%95%E5%A4%84%E7%90%86%E5%A4%9A%E4%B8%AA%E6%96%87%E4%BB%B6%EF%BC%8C%E5%85%B6%E4%B8%AD%E6%AF%8F%E4%B8%AA%E6%96%87%E4%BB%B6%E4%B8%80%E4%B8%AAmap%EF%BC%9F">如何处理多个文件,其中每个文件一个map?</a>
  252. </li>
  253. <li>
  254. <a href="#%E5%BA%94%E8%AF%A5%E4%BD%BF%E7%94%A8%E5%A4%9A%E5%B0%91%E4%B8%AAreducer%EF%BC%9F">应该使用多少个reducer?</a>
  255. </li>
  256. <li>
  257. <a href="#%E5%A6%82%E6%9E%9C%E5%9C%A8Shell%E8%84%9A%E6%9C%AC%E9%87%8C%E8%AE%BE%E7%BD%AE%E4%B8%80%E4%B8%AA%E5%88%AB%E5%90%8D%EF%BC%8C%E5%B9%B6%E6%94%BE%E5%9C%A8-mapper%E4%B9%8B%E5%90%8E%EF%BC%8CStreaming%E4%BC%9A%E6%AD%A3%E5%B8%B8%E8%BF%90%E8%A1%8C%E5%90%97%EF%BC%9F%0A%E4%BE%8B%E5%A6%82%EF%BC%8Calias+cl%3D%27cut+-fl%27%EF%BC%8C-mapper+%22cl%22%E4%BC%9A%E8%BF%90%E8%A1%8C%E6%AD%A3%E5%B8%B8%E5%90%97%EF%BC%9F">
  258. 如果在Shell脚本里设置一个别名,并放在-mapper之后,Streaming会正常运行吗?
  259. 例如,alias cl='cut -fl',-mapper "cl"会运行正常吗?
  260. </a>
  261. </li>
  262. <li>
  263. <a href="#%E6%88%91%E5%8F%AF%E4%BB%A5%E4%BD%BF%E7%94%A8UNIX+pipes%E5%90%97%EF%BC%9F%E4%BE%8B%E5%A6%82+%E2%80%93mapper+%22cut+%E2%80%93fl+%7C+set+s%2Ffoo%2Fbar%2Fg%22%E7%AE%A1%E7%94%A8%E4%B9%88%EF%BC%9F">
  264. 我可以使用UNIX pipes吗?例如 &ndash;mapper "cut &ndash;fl | set s/foo/bar/g"管用么?
  265. </a>
  266. </li>
  267. <li>
  268. <a href="#%E5%9C%A8streaming%E4%BD%9C%E4%B8%9A%E4%B8%AD%E7%94%A8-file%E9%80%89%E9%A1%B9%E8%BF%90%E8%A1%8C%E4%B8%80%E4%B8%AA">在streaming作业中用-file选项运行一个分布式的超大可执行文件(例如,3.6G)时,
  269. 我得到了一个错误信息&ldquo;No space left on device&rdquo;。如何解决?
  270. </a>
  271. </li>
  272. <li>
  273. <a href="#%E5%A6%82%E4%BD%95%E8%AE%BE%E7%BD%AE%E5%A4%9A%E4%B8%AA%E8%BE%93%E5%85%A5%E7%9B%AE%E5%BD%95%EF%BC%9F">如何设置多个输入目录?</a>
  274. </li>
  275. <li>
  276. <a href="#%E5%A6%82%E4%BD%95%E7%94%9F%E6%88%90gzip%E6%A0%BC%E5%BC%8F%E7%9A%84%E8%BE%93%E5%87%BA%E6%96%87%E4%BB%B6%EF%BC%9F">如何生成gzip格式的输出文件?</a>
  277. </li>
  278. <li>
  279. <a href="#Streaming%E4%B8%AD%E5%A6%82%E4%BD%95%E8%87%AA%E5%AE%9A%E4%B9%89input%2Foutput+format%EF%BC%9F">Streaming中如何自定义input/output format?</a>
  280. </li>
  281. <li>
  282. <a href="#Streaming%E5%A6%82%E4%BD%95%E8%A7%A3%E6%9E%90XML%E6%96%87%E6%A1%A3%EF%BC%9F">Streaming如何解析XML文档?</a>
  283. </li>
  284. <li>
  285. <a href="#%E5%9C%A8streaming%E5%BA%94%E7%94%A8%E7%A8%8B%E5%BA%8F%E4%B8%AD%E5%A6%82%E4%BD%95%E6%9B%B4%E6%96%B0%E8%AE%A1%E6%95%B0%E5%99%A8%EF%BC%9F">在streaming应用程序中如何更新计数器?</a>
  286. </li>
  287. <li>
  288. <a href="#%E5%A6%82%E4%BD%95%E6%9B%B4%E6%96%B0streaming%E5%BA%94%E7%94%A8%E7%A8%8B%E5%BA%8F%E7%9A%84%E7%8A%B6%E6%80%81%EF%BC%9F">如何更新streaming应用程序的状态?</a>
  289. </li>
  290. </ul>
  291. </li>
  292. </ul>
  293. </div>
  294. <a name="N10019"></a><a name="Hadoop+Streaming"></a>
  295. <h2 class="h3">Hadoop Streaming</h2>
  296. <div class="section">
  297. <p>
  298. Hadoop streaming是Hadoop的一个工具,
  299. 它帮助用户创建和运行一类特殊的map/reduce作业,
  300. 这些特殊的map/reduce作业是由一些可执行文件或脚本文件充当mapper或者reducer。例如:
  301. </p>
  302. <pre class="code">
  303. $HADOOP_HOME/bin/hadoop jar $HADOOP_HOME/hadoop-streaming.jar \
  304. -input myInputDirs \
  305. -output myOutputDir \
  306. -mapper /bin/cat \
  307. -reducer /bin/wc
  308. </pre>
  309. </div>
  310. <a name="N10027"></a><a name="Streaming%E5%B7%A5%E4%BD%9C%E5%8E%9F%E7%90%86"></a>
  311. <h2 class="h3">Streaming工作原理</h2>
  312. <div class="section">
  313. <p>
  314. 在上面的例子里,mapper和reducer都是可执行文件,它们从标准输入读入数据(一行一行读),
  315. 并把计算结果发给标准输出。Streaming工具会创建一个Map/Reduce作业,
  316. 并把它发送给合适的集群,同时监视这个作业的整个执行过程。
  317. </p>
  318. <p>
  319. 如果一个可执行文件被用于mapper,则在mapper初始化时,
  320. 每一个mapper任务会把这个可执行文件作为一个单独的进程启动。
  321. mapper任务运行时,它把输入切分成行并把每一行提供给可执行文件进程的标准输入。
  322. 同时,mapper收集可执行文件进程标准输出的内容,并把收到的每一行内容转化成key/value对,作为mapper的输出。
  323. 默认情况下,一行中第一个tab之前的部分作为<strong>key</strong>,之后的(不包括tab)作为<strong>value</strong>。
  324. 如果没有tab,整行作为key值,value值为null。不过,这可以定制,在下文中将会讨论如何自定义key和value的切分方式。
  325. </p>
  326. <p>如果一个可执行文件被用于reducer,每个reducer任务会把这个可执行文件作为一个单独的进程启动。
  327. Reducer任务运行时,它把输入切分成行并把每一行提供给可执行文件进程的标准输入。
  328. 同时,reducer收集可执行文件进程标准输出的内容,并把每一行内容转化成key/value对,作为reducer的输出。
  329. 默认情况下,一行中第一个tab之前的部分作为key,之后的(不包括tab)作为value。在下文中将会讨论如何自定义key和value的切分方式。
  330. </p>
  331. <p>
  332. 这是Map/Reduce框架和streaming mapper/reducer之间的基本通信协议。
  333. </p>
  334. <p>
  335. 用户也可以使用java类作为mapper或者reducer。上面的例子与这里的代码等价:
  336. </p>
  337. <pre class="code">
  338. $HADOOP_HOME/bin/hadoop jar $HADOOP_HOME/hadoop-streaming.jar \
  339. -input myInputDirs \
  340. -output myOutputDir \
  341. -mapper org.apache.hadoop.mapred.lib.IdentityMapper \
  342. -reducer /bin/wc
  343. </pre>
  344. <p>用户可以设定<span class="codefrag">stream.non.zero.exit.is.failure</span>
  345. <span class="codefrag">true</span> 或<span class="codefrag">false</span> 来表明streaming task的返回值非零时是
  346. <span class="codefrag">Failure</span>
  347. 还是<span class="codefrag">Success</span>。默认情况,streaming task返回非零时表示失败。
  348. </p>
  349. </div>
  350. <a name="N10056"></a><a name="%E5%B0%86%E6%96%87%E4%BB%B6%E6%89%93%E5%8C%85%E5%88%B0%E6%8F%90%E4%BA%A4%E7%9A%84%E4%BD%9C%E4%B8%9A%E4%B8%AD"></a>
  351. <h2 class="h3">将文件打包到提交的作业中</h2>
  352. <div class="section">
  353. <p>
  354. 任何可执行文件都可以被指定为mapper/reducer。这些可执行文件不需要事先存放在集群上;
  355. 如果在集群上还没有,则需要用-file选项让framework把可执行文件作为作业的一部分,一起打包提交。例如:
  356. </p>
  357. <pre class="code">
  358. $HADOOP_HOME/bin/hadoop jar $HADOOP_HOME/hadoop-streaming.jar \
  359. -input myInputDirs \
  360. -output myOutputDir \
  361. -mapper myPythonScript.py \
  362. -reducer /bin/wc \
  363. -file myPythonScript.py
  364. </pre>
  365. <p>
  366. 上面的例子描述了一个用户把可执行python文件作为mapper。
  367. 其中的选项&ldquo;-file myPythonScirpt.py&rdquo;使可执行python文件作为作业提交的一部分被上传到集群的机器上。
  368. </p>
  369. <p>
  370. 除了可执行文件外,其他mapper或reducer需要用到的辅助文件(比如字典,配置文件等)也可以用这种方式打包上传。例如:
  371. </p>
  372. <pre class="code">
  373. $HADOOP_HOME/bin/hadoop jar $HADOOP_HOME/hadoop-streaming.jar \
  374. -input myInputDirs \
  375. -output myOutputDir \
  376. -mapper myPythonScript.py \
  377. -reducer /bin/wc \
  378. -file myPythonScript.py \
  379. -file myDictionary.txt
  380. </pre>
  381. </div>
  382. <a name="N1006E"></a><a name="Streaming%E9%80%89%E9%A1%B9%E4%B8%8E%E7%94%A8%E6%B3%95"></a>
  383. <h2 class="h3">Streaming选项与用法</h2>
  384. <div class="section">
  385. <a name="N10074"></a><a name="%E5%8F%AA%E4%BD%BF%E7%94%A8Mapper%E7%9A%84%E4%BD%9C%E4%B8%9A"></a>
  386. <h3 class="h4">只使用Mapper的作业</h3>
  387. <p>
  388. 有时只需要map函数处理输入数据。这时只需把mapred.reduce.tasks设置为零,Map/reduce框架就不会创建reducer任务,mapper任务的输出就是整个作业的最终输出。
  389. </p>
  390. <p>
  391. 为了做到向下兼容,Hadoop Streaming也支持&ldquo;-reduce None&rdquo;选项,它与&ldquo;-jobconf mapred.reduce.tasks=0&rdquo;等价。
  392. </p>
  393. <a name="N10080"></a><a name="%E4%B8%BA%E4%BD%9C%E4%B8%9A%E6%8C%87%E5%AE%9A%E5%85%B6%E4%BB%96%E6%8F%92%E4%BB%B6"></a>
  394. <h3 class="h4">为作业指定其他插件</h3>
  395. <p>
  396. 和其他普通的Map/Reduce作业一样,用户可以为streaming作业指定其他插件:
  397. </p>
  398. <pre class="code">
  399. -inputformat JavaClassName
  400. -outputformat JavaClassName
  401. -partitioner JavaClassName
  402. -combiner JavaClassName
  403. </pre>
  404. <p>用于处理输入格式的类要能返回Text类型的key/value对。如果不指定输入格式,则默认会使用TextInputFormat。
  405. 因为TextInputFormat得到的key值是LongWritable类型的(其实key值并不是输入文件中的内容,而是value偏移量),
  406. 所以key会被丢弃,只把value用管道方式发给mapper。
  407. </p>
  408. <p>
  409. 用户提供的定义输出格式的类需要能够处理Text类型的key/value对。如果不指定输出格式,则默认会使用TextOutputFormat类。
  410. </p>
  411. <a name="N10093"></a><a name="Hadoop+Streaming%E4%B8%AD%E7%9A%84%E5%A4%A7%E6%96%87%E4%BB%B6%E5%92%8C%E6%A1%A3%E6%A1%88"></a>
  412. <h3 class="h4">Hadoop Streaming中的大文件和档案</h3>
  413. <p>任务使用-cacheFile和-cacheArchive选项在集群中分发文件和档案,选项的参数是用户已上传至HDFS的文件或档案的URI。这些文件和档案在不同的作业间缓存。用户可以通过fs.default.name.config配置参数的值得到文件所在的host和fs_port。
  414. </p>
  415. <p>
  416. 这个是使用-cacheFile选项的例子:
  417. </p>
  418. <pre class="code">
  419. -cacheFile hdfs://host:fs_port/user/testfile.txt#testlink
  420. </pre>
  421. <p>在上面的例子里,url中#后面的部分是建立在任务当前工作目录下的符号链接的名字。这里的任务的当前工作目录下有一个&ldquo;testlink&rdquo;符号链接,它指向testfile.txt文件在本地的拷贝。如果有多个文件,选项可以写成:
  422. </p>
  423. <pre class="code">
  424. -cacheFile hdfs://host:fs_port/user/testfile1.txt#testlink1 -cacheFile hdfs://host:fs_port/user/testfile2.txt#testlink2
  425. </pre>
  426. <p>
  427. -cacheArchive选项用于把jar文件拷贝到任务当前工作目录并自动把jar文件解压缩。例如:
  428. </p>
  429. <pre class="code">
  430. -cacheArchive hdfs://host:fs_port/user/testfile.jar#testlink3
  431. </pre>
  432. <p>
  433. 在上面的例子中,testlink3是当前工作目录下的符号链接,它指向testfile.jar解压后的目录。
  434. </p>
  435. <p>
  436. 下面是使用-cacheArchive选项的另一个例子。其中,input.txt文件有两行内容,分别是两个文件的名字:testlink/cache.txt和testlink/cache2.txt。&ldquo;testlink&rdquo;是指向档案目录(jar文件解压后的目录)的符号链接,这个目录下有&ldquo;cache.txt&rdquo;和&ldquo;cache2.txt&rdquo;两个文件。
  437. </p>
  438. <pre class="code">
  439. $HADOOP_HOME/bin/hadoop jar $HADOOP_HOME/hadoop-streaming.jar \
  440. -input "/user/me/samples/cachefile/input.txt" \
  441. -mapper "xargs cat" \
  442. -reducer "cat" \
  443. -output "/user/me/samples/cachefile/out" \
  444. -cacheArchive 'hdfs://hadoop-nn1.example.com/user/me/samples/cachefile/cachedir.jar#testlink' \
  445. -jobconf mapred.map.tasks=1 \
  446. -jobconf mapred.reduce.tasks=1 \
  447. -jobconf mapred.job.name="Experiment"
  448. $ ls test_jar/
  449. cache.txt cache2.txt
  450. $ jar cvf cachedir.jar -C test_jar/ .
  451. added manifest
  452. adding: cache.txt(in = 30) (out= 29)(deflated 3%)
  453. adding: cache2.txt(in = 37) (out= 35)(deflated 5%)
  454. $ hadoop dfs -put cachedir.jar samples/cachefile
  455. $ hadoop dfs -cat /user/me/samples/cachefile/input.txt
  456. testlink/cache.txt
  457. testlink/cache2.txt
  458. $ cat test_jar/cache.txt
  459. This is just the cache string
  460. $ cat test_jar/cache2.txt
  461. This is just the second cache string
  462. $ hadoop dfs -ls /user/me/samples/cachefile/out
  463. Found 1 items
  464. /user/me/samples/cachefile/out/part-00000 &lt;r 3&gt; 69
  465. $ hadoop dfs -cat /user/me/samples/cachefile/out/part-00000
  466. This is just the cache string
  467. This is just the second cache string
  468. </pre>
  469. <a name="N100BC"></a><a name="%E4%B8%BA%E4%BD%9C%E4%B8%9A%E6%8C%87%E5%AE%9A%E9%99%84%E5%8A%A0%E9%85%8D%E7%BD%AE%E5%8F%82%E6%95%B0"></a>
  470. <h3 class="h4">为作业指定附加配置参数</h3>
  471. <p>
  472. 用户可以使用&ldquo;-jobconf &lt;n&gt;=&lt;v&gt;&rdquo;增加一些配置变量。例如:
  473. </p>
  474. <pre class="code">
  475. $HADOOP_HOME/bin/hadoop jar $HADOOP_HOME/hadoop-streaming.jar \
  476. -input myInputDirs \
  477. -output myOutputDir \
  478. -mapper org.apache.hadoop.mapred.lib.IdentityMapper\
  479. -reducer /bin/wc \
  480. -jobconf mapred.reduce.tasks=2
  481. </pre>
  482. <p>
  483. 上面的例子中,-jobconf mapred.reduce.tasks=2表明用两个reducer完成作业。
  484. </p>
  485. <p>
  486. 关于jobconf参数的更多细节可以参考:<a href="http://hadoop.apache.org/core/docs/current/hadoop-default.html">hadoop-default.html</a>
  487. </p>
  488. <a name="N100D3"></a><a name="%E5%85%B6%E4%BB%96%E9%80%89%E9%A1%B9"></a>
  489. <h3 class="h4">其他选项</h3>
  490. <p>
  491. Streaming 作业的其他选项如下表:
  492. </p>
  493. <table class="ForrestTable" cellspacing="1" cellpadding="4">
  494. <tr>
  495. <th colspan="1" rowspan="1">选项</th><th colspan="1" rowspan="1">可选/必须</th><th colspan="1" rowspan="1">描述</th>
  496. </tr>
  497. <tr>
  498. <td colspan="1" rowspan="1"> -cluster name </td><td colspan="1" rowspan="1"> 可选 </td><td colspan="1" rowspan="1"> 在本地Hadoop集群与一个或多个远程集群间切换</td>
  499. </tr>
  500. <tr>
  501. <td colspan="1" rowspan="1"> -dfs host:port or local </td><td colspan="1" rowspan="1"> 可选 </td><td colspan="1" rowspan="1"> 覆盖作业的HDFS配置</td>
  502. </tr>
  503. <tr>
  504. <td colspan="1" rowspan="1"> -jt host:port or local </td><td colspan="1" rowspan="1"> 可选 </td><td colspan="1" rowspan="1"> 覆盖作业的JobTracker配置</td>
  505. </tr>
  506. <tr>
  507. <td colspan="1" rowspan="1"> -additionalconfspec specfile </td><td colspan="1" rowspan="1"> 可选 </td><td colspan="1" rowspan="1"> 用一个类似于hadoop-site.xml的XML文件保存所有配置,从而不需要用多个"-jobconf name=value"类型的选项单独为每个配置变量赋值</td>
  508. </tr>
  509. <tr>
  510. <td colspan="1" rowspan="1"> -cmdenv name=value </td><td colspan="1" rowspan="1"> 可选 </td><td colspan="1" rowspan="1"> 传递环境变量给streaming命令</td>
  511. </tr>
  512. <tr>
  513. <td colspan="1" rowspan="1"> -cacheFile fileNameURI </td><td colspan="1" rowspan="1"> 可选 </td><td colspan="1" rowspan="1"> 指定一个上传到HDFS的文件</td>
  514. </tr>
  515. <tr>
  516. <td colspan="1" rowspan="1"> -cacheArchive fileNameURI </td><td colspan="1" rowspan="1"> 可选 </td><td colspan="1" rowspan="1"> 指定一个上传到HDFS的jar文件,这个jar文件会被自动解压缩到当前工作目录下</td>
  517. </tr>
  518. <tr>
  519. <td colspan="1" rowspan="1"> -inputreader JavaClassName </td><td colspan="1" rowspan="1"> 可选 </td><td colspan="1" rowspan="1"> 为了向下兼容:指定一个record reader类(而不是input format类)</td>
  520. </tr>
  521. <tr>
  522. <td colspan="1" rowspan="1"> -verbose </td><td colspan="1" rowspan="1"> 可选 </td><td colspan="1" rowspan="1"> 详细输出 </td>
  523. </tr>
  524. </table>
  525. <p>
  526. 使用-cluster &lt;name&gt;实现&ldquo;本地&rdquo;Hadoop和一个或多个远程Hadoop集群间切换。默认情况下,使用hadoop-default.xml和hadoop-site.xml;当使用-cluster &lt;name&gt;选项时,会使用$HADOOP_HOME/conf/hadoop-&lt;name&gt;.xml。
  527. </p>
  528. <p>
  529. 下面的选项改变temp目录:
  530. </p>
  531. <pre class="code">
  532. -jobconf dfs.data.dir=/tmp
  533. </pre>
  534. <p>
  535. 下面的选项指定其他本地temp目录:
  536. </p>
  537. <pre class="code">
  538. -jobconf mapred.local.dir=/tmp/local
  539. -jobconf mapred.system.dir=/tmp/system
  540. -jobconf mapred.temp.dir=/tmp/temp
  541. </pre>
  542. <p>
  543. 更多有关jobconf的细节请参考:<a href="http://wiki.apache.org/hadoop/JobConfFile">http://wiki.apache.org/hadoop/JobConfFile</a>
  544. </p>
  545. <p>
  546. 在streaming命令中设置环境变量:
  547. </p>
  548. <pre class="code">
  549. -cmdenv EXAMPLE_DIR=/home/example/dictionaries/
  550. </pre>
  551. </div>
  552. <a name="N1018B"></a><a name="%E5%85%B6%E4%BB%96%E4%BE%8B%E5%AD%90"></a>
  553. <h2 class="h3">其他例子</h2>
  554. <div class="section">
  555. <a name="N10191"></a><a name="%E4%BD%BF%E7%94%A8%E8%87%AA%E5%AE%9A%E4%B9%89%E7%9A%84%E6%96%B9%E6%B3%95%E5%88%87%E5%88%86%E8%A1%8C%E6%9D%A5%E5%BD%A2%E6%88%90Key%2FValue%E5%AF%B9"></a>
  556. <h3 class="h4">使用自定义的方法切分行来形成Key/Value对</h3>
  557. <p>
  558. 之前已经提到,当Map/Reduce框架从mapper的标准输入读取一行时,它把这一行切分为key/value对。
  559. 在默认情况下,每行第一个tab符之前的部分作为key,之后的部分作为value(不包括tab符)。
  560. </p>
  561. <p>
  562. 但是,用户可以自定义,可以指定分隔符是其他字符而不是默认的tab符,或者指定在第n(n&gt;=1)个分割符处分割而不是默认的第一个。例如:
  563. </p>
  564. <pre class="code">
  565. $HADOOP_HOME/bin/hadoop jar $HADOOP_HOME/hadoop-streaming.jar \
  566. -input myInputDirs \
  567. -output myOutputDir \
  568. -mapper org.apache.hadoop.mapred.lib.IdentityMapper \
  569. -reducer org.apache.hadoop.mapred.lib.IdentityReducer \
  570. -jobconf stream.map.output.field.separator=. \
  571. -jobconf stream.num.map.output.key.fields=4
  572. </pre>
  573. <p>
  574. 在上面的例子,&ldquo;-jobconf stream.map.output.field.separator=.&rdquo;指定&ldquo;.&rdquo;作为map输出内容的分隔符,并且从在第四个&ldquo;.&rdquo;之前的部分作为key,之后的部分作为value(不包括这第四个&ldquo;.&rdquo;)。
  575. 如果一行中的&ldquo;.&rdquo;少于四个,则整行的内容作为key,value设为空的Text对象(就像这样创建了一个Text:new Text(""))。
  576. </p>
  577. <p>
  578. 同样,用户可以使用&ldquo;-jobconf stream.reduce.output.field.separator=SEP&rdquo;和&ldquo;-jobconf stream.num.reduce.output.fields=NUM&rdquo;来指定reduce输出的行中,第几个分隔符处分割key和value。
  579. </p>
  580. <a name="N101A7"></a><a name="%E4%B8%80%E4%B8%AA%E5%AE%9E%E7%94%A8%E7%9A%84Partitioner%E7%B1%BB"></a>
  581. <h3 class="h4">一个实用的Partitioner类 (二次排序,-partitioner org.apache.hadoop.mapred.lib.KeyFieldBasedPartitioner 选项) </h3>
  582. <p>
  583. Hadoop有一个工具类org.apache.hadoop.mapred.lib.KeyFieldBasedPartitioner,
  584. 它在应用程序中很有用。Map/reduce框架用这个类切分map的输出,
  585. 切分是基于key值的前缀,而不是整个key。例如:
  586. </p>
  587. <pre class="code">
  588. $HADOOP_HOME/bin/hadoop jar $HADOOP_HOME/hadoop-streaming.jar \
  589. -input myInputDirs \
  590. -output myOutputDir \
  591. -mapper org.apache.hadoop.mapred.lib.IdentityMapper \
  592. -reducer org.apache.hadoop.mapred.lib.IdentityReducer \
  593. -partitioner org.apache.hadoop.mapred.lib.KeyFieldBasedPartitioner \
  594. -jobconf stream.map.output.field.separator=. \
  595. -jobconf stream.num.map.output.key.fields=4 \
  596. -jobconf map.output.key.field.separator=. \
  597. -jobconf num.key.fields.for.partition=2 \
  598. -jobconf mapred.reduce.tasks=12
  599. </pre>
  600. <p>
  601. 其中,<em>-jobconf stream.map.output.field.separator=.</em> 和<em>-jobconf stream.num.map.output.key.fields=4</em>是前文中的例子。Streaming用这两个变量来得到mapper的key/value对。
  602. </p>
  603. <p>
  604. 上面的Map/Reduce 作业中map输出的key一般是由&ldquo;.&rdquo;分割成的四块。但是因为使用了
  605. <em>-jobconf num.key.fields.for.partition=2</em>
  606. 选项,所以Map/Reduce框架使用key的前两块来切分map的输出。其中,
  607. <em>-jobconf map.output.key.field.separator=.</em>
  608. 指定了这次切分使用的key的分隔符。这样可以保证在所有key/value对中,
  609. key值前两个块值相同的所有key被分到一组,分配给一个reducer。
  610. </p>
  611. <p>
  612. <em>这种高效的方法等价于指定前两块作为主键,后两块作为副键。
  613. 主键用于切分块,主键和副键的组合用于排序。</em>一个简单的示例如下:
  614. </p>
  615. <p>
  616. Map的输出(key)</p>
  617. <pre class="code">
  618. 11.12.1.2
  619. 11.14.2.3
  620. 11.11.4.1
  621. 11.12.1.1
  622. 11.14.2.2
  623. </pre>
  624. <p>
  625. 切分给3个reducer(前两块的值用于切分)</p>
  626. <pre class="code">
  627. 11.11.4.1
  628. -----------
  629. 11.12.1.2
  630. 11.12.1.1
  631. -----------
  632. 11.14.2.3
  633. 11.14.2.2
  634. </pre>
  635. <p>
  636. 在每个切分后的组内排序(四个块的值都用于排序)
  637. </p>
  638. <pre class="code">
  639. 11.11.4.1
  640. -----------
  641. 11.12.1.1
  642. 11.12.1.2
  643. -----------
  644. 11.14.2.2
  645. 11.14.2.3
  646. </pre>
  647. <a name="N101DF"></a><a name="Hadoop%E8%81%9A%E5%90%88%E5%8A%9F%E8%83%BD%E5%8C%85%E7%9A%84%E4%BD%BF%E7%94%A8%EF%BC%88-reduce+aggregate+%E9%80%89%E9%A1%B9%EF%BC%89"></a>
  648. <h3 class="h4">Hadoop聚合功能包的使用(-reduce aggregate 选项)</h3>
  649. <p>
  650. Hadoop有一个工具包&ldquo;Aggregate&rdquo;(
  651. <a href="https://svn.apache.org/repos/asf/hadoop/core/trunk/src/java/org/apache/hadoop/mapred/lib/aggregate">https://svn.apache.org/repos/asf/hadoop/core/trunk/src/java/org/apache/hadoop/mapred/lib/aggregate</a>)。
  652. &ldquo;Aggregate&rdquo;提供一个特殊的reducer类和一个特殊的combiner类,
  653. 并且有一系列的&ldquo;聚合器&rdquo;(&ldquo;aggregator&rdquo;)(例如&ldquo;sum&rdquo;,&ldquo;max&rdquo;,&ldquo;min&rdquo;等)用于聚合一组value的序列。
  654. 用户可以使用Aggregate定义一个mapper插件类,
  655. 这个类用于为mapper输入的每个key/value对产生&ldquo;可聚合项&rdquo;。
  656. combiner/reducer利用适当的聚合器聚合这些可聚合项。
  657. </p>
  658. <p>
  659. 要使用Aggregate,只需指定&ldquo;-reducer aggregate&rdquo;:</p>
  660. <pre class="code">
  661. $HADOOP_HOME/bin/hadoop jar $HADOOP_HOME/hadoop-streaming.jar \
  662. -input myInputDirs \
  663. -output myOutputDir \
  664. -mapper myAggregatorForKeyCount.py \
  665. -reducer aggregate \
  666. -file myAggregatorForKeyCount.py \
  667. -jobconf mapred.reduce.tasks=12
  668. </pre>
  669. <p>
  670. python程序myAggregatorForKeyCount.py例子:
  671. </p>
  672. <pre class="code">
  673. #!/usr/bin/python
  674. import sys;
  675. def generateLongCountToken(id):
  676. return "LongValueSum:" + id + "\t" + "1"
  677. def main(argv):
  678. line = sys.stdin.readline();
  679. try:
  680. while line:
  681. line = line[:-1];
  682. fields = line.split("\t");
  683. print generateLongCountToken(fields[0]);
  684. line = sys.stdin.readline();
  685. except "end of file":
  686. return None
  687. if __name__ == "__main__":
  688. main(sys.argv)
  689. </pre>
  690. <a name="N101FA"></a><a name="%E5%AD%97%E6%AE%B5%E7%9A%84%E9%80%89%E5%8F%96%EF%BC%88%E7%B1%BB%E4%BC%BC%E4%BA%8Eunix%E4%B8%AD%E7%9A%84+%27cut%27+%E5%91%BD%E4%BB%A4%EF%BC%89"></a>
  691. <h3 class="h4">字段的选取(类似于unix中的 'cut' 命令) </h3>
  692. <p>
  693. Hadoop的工具类org.apache.hadoop.mapred.lib.FieldSelectionMapReduce帮助用户高效处理文本数据,
  694. 就像unix中的&ldquo;cut&rdquo;工具。工具类中的map函数把输入的key/value对看作字段的列表。
  695. 用户可以指定字段的分隔符(默认是tab),
  696. 可以选择字段列表中任意一段(由列表中一个或多个字段组成)作为map输出的key或者value。
  697. 同样,工具类中的reduce函数也把输入的key/value对看作字段的列表,用户可以选取任意一段作为reduce输出的key或value。例如:
  698. </p>
  699. <pre class="code">
  700. $HADOOP_HOME/bin/hadoop jar $HADOOP_HOME/hadoop-streaming.jar \
  701. -input myInputDirs \
  702. -output myOutputDir \
  703. -mapper org.apache.hadoop.mapred.lib.FieldSelectionMapReduce\
  704. -reducer org.apache.hadoop.mapred.lib.FieldSelectionMapReduce\
  705. -partitioner org.apache.hadoop.mapred.lib.KeyFieldBasedPartitioner \
  706. -jobconf map.output.key.field.separa=. \
  707. -jobconf num.key.fields.for.partition=2 \
  708. -jobconf mapred.data.field.separator=. \
  709. -jobconf map.output.key.value.fields.spec=6,5,1-3:0- \
  710. -jobconf reduce.output.key.value.fields.spec=0-2:5- \
  711. -jobconf mapred.reduce.tasks=12
  712. </pre>
  713. <p>
  714. 选项&ldquo;-jobconf map.output.key.value.fields.spec=6,5,1-3:0-&rdquo;指定了如何为map的输出选取key和value。Key选取规则和value选取规则由&ldquo;:&rdquo;分割。
  715. 在这个例子中,map输出的key由字段6,5,1,2和3组成。输出的value由所有字段组成(&ldquo;0-&rdquo;指字段0以及之后所有字段)。
  716. </p>
  717. <p>
  718. 选项&ldquo;-jobconf reduce.output.key.value.fields.spec=0-2:0-&rdquo;(译者注:此处应为&rdquo;0-2:5-&ldquo;)指定如何为reduce的输出选取value。
  719. 本例中,reduce的输出的key将包含字段0,1,2(对应于原始的字段6,5,1)。
  720. reduce输出的value将包含起自字段5的所有字段(对应于所有的原始字段)。
  721. </p>
  722. </div>
  723. <a name="N1020F"></a><a name="%E5%B8%B8%E8%A7%81%E9%97%AE%E9%A2%98"></a>
  724. <h2 class="h3">常见问题</h2>
  725. <div class="section">
  726. <a name="N10215"></a><a name="%E6%88%91%E8%AF%A5%E6%80%8E%E6%A0%B7%E4%BD%BF%E7%94%A8Hadoop+Streaming%E8%BF%90%E8%A1%8C%E4%B8%80%E7%BB%84%E7%8B%AC%E7%AB%8B%EF%BC%88%E7%9B%B8%E5%85%B3%EF%BC%89%E7%9A%84%E4%BB%BB%E5%8A%A1%E5%91%A2%EF%BC%9F"></a>
  727. <h3 class="h4">我该怎样使用Hadoop Streaming运行一组独立(相关)的任务呢?</h3>
  728. <p>
  729. 多数情况下,你不需要Map Reduce的全部功能,
  730. 而只需要运行同一程序的多个实例,或者使用不同数据,或者在相同数据上使用不同的参数。
  731. 你可以通过Hadoop Streaming来实现。</p>
  732. <a name="N1021F"></a><a name="%E5%A6%82%E4%BD%95%E5%A4%84%E7%90%86%E5%A4%9A%E4%B8%AA%E6%96%87%E4%BB%B6%EF%BC%8C%E5%85%B6%E4%B8%AD%E6%AF%8F%E4%B8%AA%E6%96%87%E4%BB%B6%E4%B8%80%E4%B8%AAmap%EF%BC%9F"></a>
  733. <h3 class="h4">如何处理多个文件,其中每个文件一个map?</h3>
  734. <p>
  735. 例如这样一个问题,在集群上压缩(zipping)一些文件,你可以使用以下几种方法:</p>
  736. <ol>
  737. <li>使用Hadoop Streaming和用户编写的mapper脚本程序:<ul>
  738. <li> 生成一个文件,文件中包含所有要压缩的文件在HDFS上的完整路径。每个map 任务获得一个路径名作为输入。</li>
  739. <li> 创建一个mapper脚本程序,实现如下功能:获得文件名,把该文件拷贝到本地,压缩该文件并把它发到期望的输出目录。</li>
  740. </ul>
  741. </li>
  742. <li>使用现有的Hadoop框架:<ul>
  743. <li>在main函数中添加如下命令:
  744. <pre class="code">
  745. FileOutputFormat.setCompressOutput(conf, true);
  746. FileOutputFormat.setOutputCompressorClass(conf, org.apache.hadoop.io.compress.GzipCodec.class);
  747. conf.setOutputFormat(NonSplitableTextInputFormat.class);
  748. conf.setNumReduceTasks(0);
  749. </pre>
  750. </li>
  751. <li>编写map函数:
  752. <pre class="code">
  753. public void map(WritableComparable key, Writable value,
  754. OutputCollector output,
  755. Reporter reporter) throws IOException {
  756. output.collect((Text)value, null);
  757. }
  758. </pre>
  759. </li>
  760. <li>注意输出的文件名和原文件名不同</li>
  761. </ul>
  762. </li>
  763. </ol>
  764. <a name="N1024A"></a><a name="%E5%BA%94%E8%AF%A5%E4%BD%BF%E7%94%A8%E5%A4%9A%E5%B0%91%E4%B8%AAreducer%EF%BC%9F"></a>
  765. <h3 class="h4">应该使用多少个reducer?</h3>
  766. <p>
  767. 请参考Hadoop Wiki:<a href="mapred_tutorial.html#Reducer">Reducer</a>
  768. </p>
  769. <a name="N10258"></a><a name="%E5%A6%82%E6%9E%9C%E5%9C%A8Shell%E8%84%9A%E6%9C%AC%E9%87%8C%E8%AE%BE%E7%BD%AE%E4%B8%80%E4%B8%AA%E5%88%AB%E5%90%8D%EF%BC%8C%E5%B9%B6%E6%94%BE%E5%9C%A8-mapper%E4%B9%8B%E5%90%8E%EF%BC%8CStreaming%E4%BC%9A%E6%AD%A3%E5%B8%B8%E8%BF%90%E8%A1%8C%E5%90%97%EF%BC%9F%0A%E4%BE%8B%E5%A6%82%EF%BC%8Calias+cl%3D%27cut+-fl%27%EF%BC%8C-mapper+%22cl%22%E4%BC%9A%E8%BF%90%E8%A1%8C%E6%AD%A3%E5%B8%B8%E5%90%97%EF%BC%9F"></a>
  770. <h3 class="h4">
  771. 如果在Shell脚本里设置一个别名,并放在-mapper之后,Streaming会正常运行吗?
  772. 例如,alias cl='cut -fl',-mapper "cl"会运行正常吗?
  773. </h3>
  774. <p>
  775. 脚本里无法使用别名,但是允许变量替换,例如:
  776. </p>
  777. <pre class="code">
  778. $ hadoop dfs -cat samples/student_marks
  779. alice 50
  780. bruce 70
  781. charlie 80
  782. dan 75
  783. $ c2='cut -f2'; $HADOOP_HOME/bin/hadoop jar $HADOOP_HOME/hadoop-streaming.jar \
  784. -input /user/me/samples/student_marks
  785. -mapper \"$c2\" -reducer 'cat'
  786. -output /user/me/samples/student_out
  787. -jobconf mapred.job.name='Experiment'
  788. $ hadoop dfs -ls samples/student_out
  789. Found 1 items/user/me/samples/student_out/part-00000 &lt;r 3&gt; 16
  790. $ hadoop dfs -cat samples/student_out/part-00000
  791. 50
  792. 70
  793. 75
  794. 80
  795. </pre>
  796. <a name="N10266"></a><a name="%E6%88%91%E5%8F%AF%E4%BB%A5%E4%BD%BF%E7%94%A8UNIX+pipes%E5%90%97%EF%BC%9F%E4%BE%8B%E5%A6%82+%E2%80%93mapper+%22cut+%E2%80%93fl+%7C+set+s%2Ffoo%2Fbar%2Fg%22%E7%AE%A1%E7%94%A8%E4%B9%88%EF%BC%9F"></a>
  797. <h3 class="h4">
  798. 我可以使用UNIX pipes吗?例如 &ndash;mapper "cut &ndash;fl | set s/foo/bar/g"管用么?
  799. </h3>
  800. <p>
  801. 现在不支持,而且会给出错误信息&ldquo;java.io.IOException: Broken pipe&rdquo;。这或许是一个bug,需要进一步研究。
  802. </p>
  803. <a name="N10270"></a><a name="%E5%9C%A8streaming%E4%BD%9C%E4%B8%9A%E4%B8%AD%E7%94%A8-file%E9%80%89%E9%A1%B9%E8%BF%90%E8%A1%8C%E4%B8%80%E4%B8%AA"></a>
  804. <h3 class="h4">在streaming作业中用-file选项运行一个分布式的超大可执行文件(例如,3.6G)时,
  805. 我得到了一个错误信息&ldquo;No space left on device&rdquo;。如何解决?
  806. </h3>
  807. <p>
  808. 配置变量stream.tmpdir指定了一个目录,在这个目录下要进行打jar包的操作。stream.tmpdir的默认值是/tmp,你需要将这个值设置为一个有更大空间的目录:
  809. </p>
  810. <pre class="code">
  811. -jobconf stream.tmpdir=/export/bigspace/...
  812. </pre>
  813. <a name="N10281"></a><a name="%E5%A6%82%E4%BD%95%E8%AE%BE%E7%BD%AE%E5%A4%9A%E4%B8%AA%E8%BE%93%E5%85%A5%E7%9B%AE%E5%BD%95%EF%BC%9F"></a>
  814. <h3 class="h4">如何设置多个输入目录?</h3>
  815. <p>
  816. 可以使用多个-input选项设置多个输入目录:
  817. </p>
  818. <pre class="code">
  819. hadoop jar hadoop-streaming.jar -input '/user/foo/dir1' -input '/user/foo/dir2'
  820. </pre>
  821. <a name="N1028E"></a><a name="%E5%A6%82%E4%BD%95%E7%94%9F%E6%88%90gzip%E6%A0%BC%E5%BC%8F%E7%9A%84%E8%BE%93%E5%87%BA%E6%96%87%E4%BB%B6%EF%BC%9F"></a>
  822. <h3 class="h4">如何生成gzip格式的输出文件?</h3>
  823. <p>
  824. 除了纯文本格式的输出,你还可以生成gzip文件格式的输出,你只需设置streaming作业中的选项&lsquo;-jobconf mapred.output.compress=true -jobconf mapred.output.compression.codec=org.apache.hadoop.io.compress.GzipCode&rsquo;。
  825. </p>
  826. <a name="N10298"></a><a name="Streaming%E4%B8%AD%E5%A6%82%E4%BD%95%E8%87%AA%E5%AE%9A%E4%B9%89input%2Foutput+format%EF%BC%9F"></a>
  827. <h3 class="h4">Streaming中如何自定义input/output format?</h3>
  828. <p>
  829. 至少在Hadoop 0.14版本以前,不支持多个jar文件。所以当指定自定义的类时,你要把他们和原有的streaming jar打包在一起,并用这个自定义的jar包替换默认的hadoop streaming jar包。
  830. </p>
  831. <a name="N102A2"></a><a name="Streaming%E5%A6%82%E4%BD%95%E8%A7%A3%E6%9E%90XML%E6%96%87%E6%A1%A3%EF%BC%9F"></a>
  832. <h3 class="h4">Streaming如何解析XML文档?</h3>
  833. <p>
  834. 你可以使用StreamXmlRecordReader来解析XML文档。
  835. </p>
  836. <pre class="code">
  837. hadoop jar hadoop-streaming.jar -inputreader "StreamXmlRecord,begin=BEGIN_STRING,end=END_STRING" ..... (rest of the command)
  838. </pre>
  839. <p>
  840. Map任务会把BEGIN_STRING和END_STRING之间的部分看作一条记录。
  841. </p>
  842. <a name="N102B3"></a><a name="%E5%9C%A8streaming%E5%BA%94%E7%94%A8%E7%A8%8B%E5%BA%8F%E4%B8%AD%E5%A6%82%E4%BD%95%E6%9B%B4%E6%96%B0%E8%AE%A1%E6%95%B0%E5%99%A8%EF%BC%9F"></a>
  843. <h3 class="h4">在streaming应用程序中如何更新计数器?</h3>
  844. <p>
  845. streaming进程能够使用stderr发出计数器信息。
  846. <span class="codefrag">reporter:counter:&lt;group&gt;,&lt;counter&gt;,&lt;amount&gt;</span>
  847. 应该被发送到stderr来更新计数器。
  848. </p>
  849. <a name="N102C0"></a><a name="%E5%A6%82%E4%BD%95%E6%9B%B4%E6%96%B0streaming%E5%BA%94%E7%94%A8%E7%A8%8B%E5%BA%8F%E7%9A%84%E7%8A%B6%E6%80%81%EF%BC%9F"></a>
  850. <h3 class="h4">如何更新streaming应用程序的状态?</h3>
  851. <p>
  852. streaming进程能够使用stderr发出状态信息。
  853. <span class="codefrag">reporter:status:&lt;message&gt;</span> 要被发送到stderr来设置状态。
  854. </p>
  855. </div>
  856. </div>
  857. <!--+
  858. |end content
  859. +-->
  860. <div class="clearboth">&nbsp;</div>
  861. </div>
  862. <div id="footer">
  863. <!--+
  864. |start bottomstrip
  865. +-->
  866. <div class="lastmodified">
  867. <script type="text/javascript"><!--
  868. document.write("Last Published: " + document.lastModified);
  869. // --></script>
  870. </div>
  871. <div class="copyright">
  872. Copyright &copy;
  873. 2007 <a href="http://www.apache.org/licenses/">The Apache Software Foundation.</a>
  874. </div>
  875. <!--+
  876. |end bottomstrip
  877. +-->
  878. </div>
  879. </body>
  880. </html>