| <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> |
| <html> |
| <head> |
| <META http-equiv="Content-Type" content="text/html; charset=UTF-8"> |
| <meta content="Apache Forrest" name="Generator"> |
| <meta name="Forrest-version" content="0.8"> |
| <meta name="Forrest-skin-name" content="pelt"> |
| <title>DistCp</title> |
| <link type="text/css" href="skin/basic.css" rel="stylesheet"> |
| <link media="screen" type="text/css" href="skin/screen.css" rel="stylesheet"> |
| <link media="print" type="text/css" href="skin/print.css" rel="stylesheet"> |
| <link type="text/css" href="skin/profile.css" rel="stylesheet"> |
| <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> |
| <link rel="shortcut icon" href="images/favicon.ico"> |
| </head> |
| <body onload="init()"> |
| <script type="text/javascript">ndeSetTextSize();</script> |
| <div id="top"> |
| <!--+ |
| |breadtrail |
| +--> |
| <div class="breadtrail"> |
| <a href="http://www.apache.org/">Apache</a> > <a href="http://hadoop.apache.org/">Hadoop</a> > <a href="http://hadoop.apache.org/core/">Core</a><script src="skin/breadcrumbs.js" language="JavaScript" type="text/javascript"></script> |
| </div> |
| <!--+ |
| |header |
| +--> |
| <div class="header"> |
| <!--+ |
| |start group logo |
| +--> |
| <div class="grouplogo"> |
| <a href="http://hadoop.apache.org/"><img class="logoImage" alt="Hadoop" src="images/hadoop-logo.jpg" title="Apache Hadoop"></a> |
| </div> |
| <!--+ |
| |end group logo |
| +--> |
| <!--+ |
| |start Project Logo |
| +--> |
| <div class="projectlogo"> |
| <a href="http://hadoop.apache.org/core/"><img class="logoImage" alt="Hadoop" src="images/core-logo.gif" title="Scalable Computing Platform"></a> |
| </div> |
| <!--+ |
| |end Project Logo |
| +--> |
| <!--+ |
| |start Search |
| +--> |
| <div class="searchbox"> |
| <form action="http://www.google.com/search" method="get" class="roundtopsmall"> |
| <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"> |
| <input name="Search" value="Search" type="submit"> |
| </form> |
| </div> |
| <!--+ |
| |end search |
| +--> |
| <!--+ |
| |start Tabs |
| +--> |
| <ul id="tabs"> |
| <li> |
| <a class="unselected" href="http://hadoop.apache.org/core/">项目</a> |
| </li> |
| <li> |
| <a class="unselected" href="http://wiki.apache.org/hadoop">维基</a> |
| </li> |
| <li class="current"> |
| <a class="selected" href="index.html">Hadoop 0.18文档</a> |
| </li> |
| </ul> |
| <!--+ |
| |end Tabs |
| +--> |
| </div> |
| </div> |
| <div id="main"> |
| <div id="publishedStrip"> |
| <!--+ |
| |start Subtabs |
| +--> |
| <div id="level2tabs"></div> |
| <!--+ |
| |end Endtabs |
| +--> |
| <script type="text/javascript"><!-- |
| document.write("Last Published: " + document.lastModified); |
| // --></script> |
| </div> |
| <!--+ |
| |breadtrail |
| +--> |
| <div class="breadtrail"> |
| |
| |
| </div> |
| <!--+ |
| |start Menu, mainarea |
| +--> |
| <!--+ |
| |start Menu |
| +--> |
| <div id="menu"> |
| <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> |
| <div id="menu_selected_1.1" class="selectedmenuitemgroup" style="display: block;"> |
| <div class="menuitem"> |
| <a href="index.html">概述</a> |
| </div> |
| <div class="menuitem"> |
| <a href="quickstart.html">快速入门</a> |
| </div> |
| <div class="menuitem"> |
| <a href="cluster_setup.html">集群搭建</a> |
| </div> |
| <div class="menuitem"> |
| <a href="hdfs_design.html">HDFS构架设计</a> |
| </div> |
| <div class="menuitem"> |
| <a href="hdfs_user_guide.html">HDFS使用指南</a> |
| </div> |
| <div class="menuitem"> |
| <a href="hdfs_permissions_guide.html">HDFS权限指南</a> |
| </div> |
| <div class="menuitem"> |
| <a href="hdfs_quota_admin_guide.html">HDFS配额管理指南</a> |
| </div> |
| <div class="menuitem"> |
| <a href="commands_manual.html">命令手册</a> |
| </div> |
| <div class="menuitem"> |
| <a href="hdfs_shell.html">FS Shell使用指南</a> |
| </div> |
| <div class="menupage"> |
| <div class="menupagetitle">DistCp使用指南</div> |
| </div> |
| <div class="menuitem"> |
| <a href="mapred_tutorial.html">Map-Reduce教程</a> |
| </div> |
| <div class="menuitem"> |
| <a href="native_libraries.html">Hadoop本地库</a> |
| </div> |
| <div class="menuitem"> |
| <a href="streaming.html">Streaming</a> |
| </div> |
| <div class="menuitem"> |
| <a href="hadoop_archives.html">Hadoop Archives</a> |
| </div> |
| <div class="menuitem"> |
| <a href="hod.html">Hadoop On Demand</a> |
| </div> |
| <div class="menuitem"> |
| <a href="http://hadoop.apache.org/core/docs/r0.18.2/api/index.html">API参考</a> |
| </div> |
| <div class="menuitem"> |
| <a href="http://hadoop.apache.org/core/docs/r0.18.2/jdiff/changes.html">API Changes</a> |
| </div> |
| <div class="menuitem"> |
| <a href="http://wiki.apache.org/hadoop/">维基</a> |
| </div> |
| <div class="menuitem"> |
| <a href="http://wiki.apache.org/hadoop/FAQ">常见问题</a> |
| </div> |
| <div class="menuitem"> |
| <a href="http://hadoop.apache.org/core/mailing_lists.html">邮件列表</a> |
| </div> |
| <div class="menuitem"> |
| <a href="http://hadoop.apache.org/core/docs/r0.18.2/releasenotes.html">发行说明</a> |
| </div> |
| <div class="menuitem"> |
| <a href="http://hadoop.apache.org/core/docs/r0.18.2/changes.html">变更日志</a> |
| </div> |
| </div> |
| <div id="credit"></div> |
| <div id="roundbottom"> |
| <img style="display: none" class="corner" height="15" width="15" alt="" src="skin/images/rc-b-l-15-1body-2menu-3menu.png"></div> |
| <!--+ |
| |alternative credits |
| +--> |
| <div id="credit2"></div> |
| </div> |
| <!--+ |
| |end Menu |
| +--> |
| <!--+ |
| |start content |
| +--> |
| <div id="content"> |
| <div title="Portable Document Format" class="pdflink"> |
| <a class="dida" href="distcp.pdf"><img alt="PDF -icon" src="skin/images/pdfdoc.gif" class="skin"><br> |
| PDF</a> |
| </div> |
| <h1>DistCp</h1> |
| <div id="minitoc-area"> |
| <ul class="minitoc"> |
| <li> |
| <a href="#%E6%A6%82%E8%BF%B0">概述</a> |
| </li> |
| <li> |
| <a href="#%E4%BD%BF%E7%94%A8%E6%96%B9%E6%B3%95">使用方法</a> |
| <ul class="minitoc"> |
| <li> |
| <a href="#%E5%9F%BA%E6%9C%AC%E4%BD%BF%E7%94%A8%E6%96%B9%E6%B3%95">基本使用方法</a> |
| </li> |
| <li> |
| <a href="#options">选项</a> |
| <ul class="minitoc"> |
| <li> |
| <a href="#%E9%80%89%E9%A1%B9%E7%B4%A2%E5%BC%95">选项索引</a> |
| </li> |
| <li> |
| <a href="#uo">更新和覆盖</a> |
| </li> |
| </ul> |
| </li> |
| </ul> |
| </li> |
| <li> |
| <a href="#etc">附录</a> |
| <ul class="minitoc"> |
| <li> |
| <a href="#Map%E6%95%B0%E7%9B%AE">Map数目</a> |
| </li> |
| <li> |
| <a href="#cpver">不同HDFS版本间的拷贝</a> |
| </li> |
| <li> |
| <a href="#Map%2FReduce%E5%92%8C%E5%89%AF%E6%95%88%E5%BA%94">Map/Reduce和副效应</a> |
| </li> |
| </ul> |
| </li> |
| </ul> |
| </div> |
| |
| |
| <a name="N1000D"></a><a name="%E6%A6%82%E8%BF%B0"></a> |
| <h2 class="h3">概述</h2> |
| <div class="section"> |
| <p>DistCp(分布式拷贝)是用于大规模集群内部和集群之间拷贝的工具。 |
| 它使用Map/Reduce实现文件分发,错误处理和恢复,以及报告生成。 |
| 它把文件和目录的列表作为map任务的输入,每个任务会完成源列表中部分文件的拷贝。 |
| 由于使用了Map/Reduce方法,这个工具在语义和执行上都会有特殊的地方。 |
| 这篇文档会为常用DistCp操作提供指南并阐述它的工作模型。 |
| </p> |
| </div> |
| |
| |
| <a name="N10017"></a><a name="%E4%BD%BF%E7%94%A8%E6%96%B9%E6%B3%95"></a> |
| <h2 class="h3">使用方法</h2> |
| <div class="section"> |
| <a name="N1001D"></a><a name="%E5%9F%BA%E6%9C%AC%E4%BD%BF%E7%94%A8%E6%96%B9%E6%B3%95"></a> |
| <h3 class="h4">基本使用方法</h3> |
| <p>DistCp最常用在集群之间的拷贝:</p> |
| <p> |
| <span class="codefrag">bash$ hadoop distcp hdfs://nn1:8020/foo/bar \</span> |
| <br> |
| |
| <span class="codefrag"> |
| |
| hdfs://nn2:8020/bar/foo</span> |
| </p> |
| <p>这条命令会把nn1集群的<span class="codefrag">/foo/bar</span>目录下的所有文件或目录名展开并存储到一个临时文件中,这些文件内容的拷贝工作被分配给多个map任务, |
| 然后每个TaskTracker分别执行从nn1到nn2的拷贝操作。注意DistCp使用绝对路径进行操作。 |
| </p> |
| <p>命令行中可以指定多个源目录:</p> |
| <p> |
| <span class="codefrag">bash$ hadoop distcp hdfs://nn1:8020/foo/a \</span> |
| <br> |
| |
| <span class="codefrag"> |
| |
| hdfs://nn1:8020/foo/b \</span> |
| <br> |
| |
| <span class="codefrag"> |
| |
| hdfs://nn2:8020/bar/foo</span> |
| </p> |
| <p>或者使用<span class="codefrag">-f</span>选项,从文件里获得多个源:<br> |
| |
| <span class="codefrag">bash$ hadoop distcp -f hdfs://nn1:8020/srclist \</span> |
| <br> |
| |
| <span class="codefrag"> |
| |
| hdfs://nn2:8020/bar/foo</span> |
| <br> |
| </p> |
| <p>其中<span class="codefrag">srclist</span> 的内容是<br> |
| |
| <span class="codefrag"> hdfs://nn1:8020/foo/a</span> |
| <br> |
| |
| <span class="codefrag"> hdfs://nn1:8020/foo/b</span> |
| </p> |
| <p>当从多个源拷贝时,如果两个源冲突,DistCp会停止拷贝并提示出错信息, |
| 如果在目的位置发生冲突,会根据<a href="#options">选项设置</a>解决。 |
| 默认情况会跳过已经存在的目标文件(比如不用源文件做替换操作)。每次操作结束时 |
| 都会报告跳过的文件数目,但是如果某些拷贝操作失败了,但在之后的尝试成功了, |
| 那么报告的信息可能不够精确(请参考<a href="#etc">附录</a>)。 |
| </p> |
| <p>每个TaskTracker必须都能够与源端和目的端文件系统进行访问和交互。 |
| 对于HDFS来说,源和目的端要运行相同版本的协议或者使用向下兼容的协议。 |
| (请参考<a href="#cpver">不同版本间的拷贝</a> )。 |
| </p> |
| <p>拷贝完成后,建议生成源端和目的端文件的列表,并交叉检查,来确认拷贝真正成功。 |
| 因为DistCp使用Map/Reduce和文件系统API进行操作,所以这三者或它们之间有任何问题 |
| 都会影响拷贝操作。一些Distcp命令的成功执行可以通过再次执行带-update参数的该命令来完成, |
| 但用户在如此操作之前应该对该命令的语法很熟悉。 |
| </p> |
| <p>值得注意的是,当另一个客户端同时在向源文件写入时,拷贝很有可能会失败。 |
| 尝试覆盖HDFS上正在被写入的文件的操作也会失败。 |
| 如果一个源文件在拷贝之前被移动或删除了,拷贝失败同时输出异常 |
| FileNotFoundException。</p> |
| <a name="N1007B"></a><a name="options"></a> |
| <h3 class="h4">选项</h3> |
| <a name="N10081"></a><a name="%E9%80%89%E9%A1%B9%E7%B4%A2%E5%BC%95"></a> |
| <h4>选项索引</h4> |
| <table class="ForrestTable" cellspacing="1" cellpadding="4"> |
| |
| <tr> |
| <th colspan="1" rowspan="1"> 标识 </th><th colspan="1" rowspan="1"> 描述 </th><th colspan="1" rowspan="1"> 备注 </th> |
| </tr> |
| |
| |
| <tr> |
| <td colspan="1" rowspan="1"><span class="codefrag">-p[rbugp]</span></td> |
| <td colspan="1" rowspan="1">Preserve<br> |
| r: replication number<br> |
| b: block size<br> |
| u: user<br> |
| g: group<br> |
| p: permission<br> |
| </td> |
| <td colspan="1" rowspan="1">修改次数不会被保留。并且当指定 |
| <span class="codefrag">-update</span> 时,更新的状态<strong>不</strong>会 |
| 被同步,除非文件大小不同(比如文件被重新创建)。 |
| </td> |
| </tr> |
| |
| <tr> |
| <td colspan="1" rowspan="1"><span class="codefrag">-i</span></td> |
| <td colspan="1" rowspan="1">忽略失败</td> |
| <td colspan="1" rowspan="1">就像在 <a href="#etc">附录</a>中提到的,这个选项会比默认情况提供关于拷贝的更精确的统计, 同时它还将保留失败拷贝操作的日志,这些日志信息可以用于调试。最后,如果一个map失败了,但并没完成所有分块任务的尝试,这不会导致整个作业的失败。 |
| </td> |
| </tr> |
| |
| <tr> |
| <td colspan="1" rowspan="1"><span class="codefrag">-log <logdir></span></td> |
| <td colspan="1" rowspan="1">记录日志到 <logdir></td> |
| <td colspan="1" rowspan="1">DistCp为每个文件的每次尝试拷贝操作都记录日志,并把日志作为map的输出。 |
| 如果一个map失败了,当重新执行时这个日志不会被保留。 |
| </td> |
| </tr> |
| |
| <tr> |
| <td colspan="1" rowspan="1"><span class="codefrag">-m <num_maps></span></td> |
| <td colspan="1" rowspan="1">同时拷贝的最大数目</td> |
| <td colspan="1" rowspan="1">指定了拷贝数据时map的数目。请注意并不是map数越多吞吐量越大。 |
| </td> |
| </tr> |
| |
| <tr> |
| <td colspan="1" rowspan="1"><span class="codefrag">-overwrite</span></td> |
| <td colspan="1" rowspan="1">覆盖目标</td> |
| <td colspan="1" rowspan="1">如果一个map失败并且没有使用<span class="codefrag">-i</span>选项,不仅仅那些拷贝失败的文件,这个分块任务中的所有文件都会被重新拷贝。 |
| 就像<a href="#uo">下面</a>提到的,它会改变生成目标路径的语义,所以 |
| 用户要小心使用这个选项。 |
| </td> |
| </tr> |
| |
| <tr> |
| <td colspan="1" rowspan="1"><span class="codefrag">-update</span></td> |
| <td colspan="1" rowspan="1">如果源和目标的大小不一样则进行覆盖</td> |
| <td colspan="1" rowspan="1">像之前提到的,这不是"同步"操作。 |
| 执行覆盖的唯一标准是源文件和目标文件大小是否相同;如果不同,则源文件替换目标文件。 |
| 像 <a href="#uo">下面</a>提到的,它也改变生成目标路径的语义, |
| 用户使用要小心。 |
| </td> |
| </tr> |
| |
| <tr> |
| <td colspan="1" rowspan="1"><span class="codefrag">-f <urilist_uri></span></td> |
| <td colspan="1" rowspan="1">使用<urilist_uri> 作为源文件列表</td> |
| <td colspan="1" rowspan="1">这等价于把所有文件名列在命令行中。 |
| <span class="codefrag">urilist_uri</span> 列表应该是完整合法的URI。 |
| </td> |
| </tr> |
| |
| |
| </table> |
| <a name="N10133"></a><a name="uo"></a> |
| <h4>更新和覆盖</h4> |
| <p>这里给出一些 <span class="codefrag">-update</span>和 <span class="codefrag">-overwrite</span>的例子。 |
| 考虑一个从<span class="codefrag">/foo/a</span> 和 |
| <span class="codefrag">/foo/b</span> 到 <span class="codefrag">/bar/foo</span>的拷贝,源路径包括: |
| </p> |
| <p> |
| <span class="codefrag"> hdfs://nn1:8020/foo/a</span> |
| <br> |
| |
| <span class="codefrag"> hdfs://nn1:8020/foo/a/aa</span> |
| <br> |
| |
| <span class="codefrag"> hdfs://nn1:8020/foo/a/ab</span> |
| <br> |
| |
| <span class="codefrag"> hdfs://nn1:8020/foo/b</span> |
| <br> |
| |
| <span class="codefrag"> hdfs://nn1:8020/foo/b/ba</span> |
| <br> |
| |
| <span class="codefrag"> hdfs://nn1:8020/foo/b/ab</span> |
| </p> |
| <p>如果没设置<span class="codefrag">-update</span>或 <span class="codefrag">-overwrite</span>选项, |
| 那么两个源都会映射到目标端的 |
| <span class="codefrag">/bar/foo/ab</span>。 |
| 如果设置了这两个选项,每个源目录的内容都会和目标目录的 |
| <strong>内容</strong> 做比较。DistCp碰到这类冲突的情况会终止操作并退出。</p> |
| <p>默认情况下,<span class="codefrag">/bar/foo/a</span> 和 |
| <span class="codefrag">/bar/foo/b</span> 目录都会被创建,所以并不会有冲突。</p> |
| <p>现在考虑一个使用<span class="codefrag">-update</span>合法的操作:<br> |
| |
| <span class="codefrag">distcp -update hdfs://nn1:8020/foo/a \</span> |
| <br> |
| |
| <span class="codefrag"> |
| |
| hdfs://nn1:8020/foo/b \</span> |
| <br> |
| |
| <span class="codefrag"> |
| |
| hdfs://nn2:8020/bar</span> |
| </p> |
| <p>其中源路径/大小:</p> |
| <p> |
| <span class="codefrag"> hdfs://nn1:8020/foo/a</span> |
| <br> |
| |
| <span class="codefrag"> hdfs://nn1:8020/foo/a/aa 32</span> |
| <br> |
| |
| <span class="codefrag"> hdfs://nn1:8020/foo/a/ab 32</span> |
| <br> |
| |
| <span class="codefrag"> hdfs://nn1:8020/foo/b</span> |
| <br> |
| |
| <span class="codefrag"> hdfs://nn1:8020/foo/b/ba 64</span> |
| <br> |
| |
| <span class="codefrag"> hdfs://nn1:8020/foo/b/bb 32</span> |
| </p> |
| <p>和目的路径/大小:</p> |
| <p> |
| <span class="codefrag"> hdfs://nn2:8020/bar</span> |
| <br> |
| |
| <span class="codefrag"> hdfs://nn2:8020/bar/aa 32</span> |
| <br> |
| |
| <span class="codefrag"> hdfs://nn2:8020/bar/ba 32</span> |
| <br> |
| |
| <span class="codefrag"> hdfs://nn2:8020/bar/bb 64</span> |
| </p> |
| <p>会产生:</p> |
| <p> |
| <span class="codefrag"> hdfs://nn2:8020/bar</span> |
| <br> |
| |
| <span class="codefrag"> hdfs://nn2:8020/bar/aa 32</span> |
| <br> |
| |
| <span class="codefrag"> hdfs://nn2:8020/bar/ab 32</span> |
| <br> |
| |
| <span class="codefrag"> hdfs://nn2:8020/bar/ba 64</span> |
| <br> |
| |
| <span class="codefrag"> hdfs://nn2:8020/bar/bb 32</span> |
| </p> |
| <p>只有nn2的<span class="codefrag">aa</span>文件没有被覆盖。如果指定了 |
| <span class="codefrag">-overwrite</span>选项,所有文件都会被覆盖。 |
| </p> |
| </div> <!-- Usage --> |
| |
| |
| <a name="N101E4"></a><a name="etc"></a> |
| <h2 class="h3">附录</h2> |
| <div class="section"> |
| <a name="N101EA"></a><a name="Map%E6%95%B0%E7%9B%AE"></a> |
| <h3 class="h4">Map数目</h3> |
| <p>DistCp会尝试着均分需要拷贝的内容,这样每个map拷贝差不多相等大小的内容。 |
| 但因为文件是最小的拷贝粒度,所以配置增加同时拷贝(如map)的数目不一定会增加实际同时拷贝的数目以及总吞吐量。 |
| </p> |
| <p>如果没使用<span class="codefrag">-m</span>选项,DistCp会尝试在调度工作时指定map的数目 |
| 为 <span class="codefrag">min (total_bytes / bytes.per.map, 20 * num_task_trackers)</span>, |
| 其中<span class="codefrag">bytes.per.map</span>默认是256MB。</p> |
| <p>建议对于长时间运行或定期运行的作业,根据源和目标集群大小、拷贝数量大小以及带宽调整map的数目。 |
| </p> |
| <a name="N10203"></a><a name="cpver"></a> |
| <h3 class="h4">不同HDFS版本间的拷贝</h3> |
| <p>对于不同Hadoop版本间的拷贝,用户应该使用HftpFileSystem。 |
| 这是一个只读文件系统,所以DistCp必须运行在目标端集群上(更确切的说是在能够写入目标集群的TaskTracker上)。 |
| 源的格式是 |
| <span class="codefrag">hftp://<dfs.http.address>/<path></span> |
| (默认情况<span class="codefrag">dfs.http.address</span>是 |
| <namenode>:50070)。</p> |
| <a name="N10213"></a><a name="Map%2FReduce%E5%92%8C%E5%89%AF%E6%95%88%E5%BA%94"></a> |
| <h3 class="h4">Map/Reduce和副效应</h3> |
| <p>像前面提到的,map拷贝输入文件失败时,会带来一些副效应。 |
| </p> |
| <ul> |
| |
| |
| <li>除非使用了<span class="codefrag">-i</span>,任务产生的日志会被新的尝试替换掉。 |
| </li> |
| |
| |
| <li>除非使用了<span class="codefrag">-overwrite</span>,文件被之前的map成功拷贝后当又一次执行拷贝时会被标记为 |
| "被忽略"。</li> |
| |
| |
| <li>如果map失败了<span class="codefrag">mapred.map.max.attempts</span>次,剩下的map任务会被终止(除非使用了<span class="codefrag">-i</span>)。 |
| </li> |
| |
| |
| <li>如果<span class="codefrag">mapred.speculative.execution</span>被设置为 |
| <span class="codefrag">final</span>和<span class="codefrag">true</span>,则拷贝的结果是未定义的。</li> |
| |
| |
| </ul> |
| </div> <!-- Appendix --> |
| |
| |
| </div> |
| <!--+ |
| |end content |
| +--> |
| <div class="clearboth"> </div> |
| </div> |
| <div id="footer"> |
| <!--+ |
| |start bottomstrip |
| +--> |
| <div class="lastmodified"> |
| <script type="text/javascript"><!-- |
| document.write("Last Published: " + document.lastModified); |
| // --></script> |
| </div> |
| <div class="copyright"> |
| Copyright © |
| 2007 <a href="http://www.apache.org/licenses/">The Apache Software Foundation.</a> |
| </div> |
| <!--+ |
| |end bottomstrip |
| +--> |
| </div> |
| </body> |
| </html> |