﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>BlogJava-云-随笔分类-Hadoop</title><link>http://www.blogjava.net/matuobasyouca/category/51245.html</link><description>敏捷、分布式、ALM过程自动化、企业应用架构</description><language>zh-cn</language><lastBuildDate>Wed, 08 Aug 2012 21:00:29 GMT</lastBuildDate><pubDate>Wed, 08 Aug 2012 21:00:29 GMT</pubDate><ttl>60</ttl><item><title>近期HADOOP（1.0.3）实施心得与总结</title><link>http://www.blogjava.net/matuobasyouca/archive/2012/08/08/385087.html</link><dc:creator>一酌散千忧</dc:creator><author>一酌散千忧</author><pubDate>Wed, 08 Aug 2012 12:21:00 GMT</pubDate><guid>http://www.blogjava.net/matuobasyouca/archive/2012/08/08/385087.html</guid><wfw:comment>http://www.blogjava.net/matuobasyouca/comments/385087.html</wfw:comment><comments>http://www.blogjava.net/matuobasyouca/archive/2012/08/08/385087.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/matuobasyouca/comments/commentRss/385087.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/matuobasyouca/services/trackbacks/385087.html</trackback:ping><description><![CDATA[<div>
<div>
<p style="margin-bottom:0pt; margin-top:0pt; "><span class="Apple-style-span" style="font-family: 宋体; ">Hadoop实施已经有快一个月了，对Hadoop的概念理解、使用，Linux与shell脚本，甚至mysql都有了更多的理解。<br /><br /><br /></span></p>
<p style="margin-bottom:0pt; margin-top:0pt; "></p>
<p style="margin-bottom:0pt; margin-top:0pt; "><span style="mso-spacerun:'yes'; font-weight:bold; font-size:10.5000pt; font-family:'宋体'; ">项目背景</span><span style="mso-spacerun:'yes'; font-size:10.5000pt; font-family:'宋体'; ">：用于互联网信息收集后的关键词匹配与内容提取。</span></p>
<p style="margin-bottom:0pt; margin-top:0pt; "><span style="mso-spacerun:'yes'; font-size:10.5000pt; font-family:'宋体'; ">主要系统架构分为互联网爬虫、分析、业务应用三块：</span></p>
<p style="margin-bottom:0pt; margin-top:0pt; text-align:center; "><img width="341" height="399" src="http://www.blogjava.net/images/blogjava_net/matuobasyouca/52361/r_%e5%9b%be%e7%89%872.jpg" alt="" /></p>
<p style="margin-bottom:0pt; margin-top:0pt; text-align:center; "><span style="mso-spacerun:'yes'; font-size:9.0000pt; font-family:'宋体'; ">简单架构描述</span></p>
<p style="margin-bottom:0pt; margin-top:0pt; "><span style="mso-spacerun:'yes'; font-size:10.5000pt; font-family:'宋体'; ">由于我在当中的角色主要负责分析架构的搭建，所以其他两块都画得简单，下面也不会过多的描述。<br /><br /><br /></span></p>
<p style="margin-bottom:0pt; margin-top:0pt; "></p>
<p style="margin-bottom:0pt; margin-top:0pt; "><span style="mso-spacerun:'yes'; font-weight:bold; font-size:10.5000pt; font-family:'宋体'; ">Hadoop理解</span><span style="mso-spacerun:'yes'; font-size:10.5000pt; font-family:'宋体'; ">：提到Hadoop都想到的是云、分布式计算，在一段时间的实施之后有了一些具体的理解。</span></p>
<p style="margin-bottom:0pt; margin-top:0pt; "><span style="mso-spacerun:'yes'; font-size:10.5000pt; font-family:'宋体'; ">Hadoop的优势：</span></p>
<p style="margin-bottom:0pt; margin-top:0pt; "><span style="mso-spacerun:'yes'; font-size:10.5000pt; font-family:'宋体'; ">针对</span><span style="mso-spacerun:'yes'; font-weight:bold; font-size:10.5000pt; font-family:'宋体'; ">性能指标</span><span style="mso-spacerun:'yes'; font-size:10.5000pt; font-family:'宋体'; ">，当业务数据量总量或增速上升到一定级别，依靠关系型数据库一定无法支持。对于非关系型数据库，包括Nosql和Solr一类存储方式，稍显复杂，对于机器集群性能要求偏高（相对于文件系统）。从</span><span style="mso-spacerun:'yes'; font-weight:bold; font-size:10.5000pt; font-family:'宋体'; ">数据使用模式</span><span style="mso-spacerun:'yes'; font-size:10.5000pt; font-family:'宋体'; ">上来讲，目前海量数据的常常是不包含复杂逻辑的简单统计整理（比如上述系统中的关键词匹配）。这时候文件系统的优势反而比较明显（结构简单，逻辑简单）。</span></p>
<p style="margin-bottom:0pt; margin-top:0pt; "><span style="mso-spacerun:'yes'; font-size:10.5000pt; font-family:'宋体'; ">如上述系统的应用场景是怎么样的呢，在一个强大的爬虫系统之下，每个小时的数据增量在G到10G的级别，需要搜索所有的文件，获取关键字的匹配，并且对匹配内容进行摘要。很类似我们windows里面的搜索功能，需要解决的就是如何在这样增幅的文件系统之下，如何满足业务系统的需求。<br /><br /></span></p>
<p style="margin-bottom:0pt; margin-top:0pt; "></p>
<p style="margin-bottom:0pt; margin-top:0pt; "><span style="mso-spacerun:'yes'; font-size:10.5000pt; font-family:'宋体'; ">对</span><span style="mso-spacerun:'yes'; font-weight:bold; font-size:10.5000pt; font-family:'宋体'; ">分析系统有什么要求</span><span style="mso-spacerun:'yes'; font-size:10.5000pt; font-family:'宋体'; ">呢？</span></p>
<p style="margin-left:21.0000pt; text-indent:-21.0000pt; margin-bottom:0pt; margin-top:0pt; "><span style="mso-spacerun:'yes'; font-size:10.5000pt; font-family:'Wingdings'; ">l&nbsp;</span><span style="mso-spacerun:'yes'; font-size:10.5000pt; font-family:'宋体'; ">能够建立集群，分布式的保存数据文件内容（统一控制，可配置）。</span></p>
<p style="margin-left:21.0000pt; text-indent:-21.0000pt; margin-bottom:0pt; margin-top:0pt; "><span style="mso-spacerun:'yes'; font-size:10.5000pt; font-family:'Wingdings'; ">l&nbsp;</span><span style="mso-spacerun:'yes'; font-size:10.5000pt; font-family:'宋体'; ">有一定的保护机制，保证数据或节点丢失不会影响系统使用。</span></p>
<p style="margin-left:21.0000pt; text-indent:-21.0000pt; margin-bottom:0pt; margin-top:0pt; "><span style="mso-spacerun:'yes'; font-size:10.5000pt; font-family:'Wingdings'; ">l&nbsp;</span><span style="mso-spacerun:'yes'; font-size:10.5000pt; font-family:'宋体'; ">如果有一个任务脚本执行框架机制就好了（用于并行计算）。</span></p>
<p style="margin-left:21.0000pt; text-indent:-21.0000pt; margin-bottom:0pt; margin-top:0pt; "><span style="mso-spacerun:'yes'; font-size:10.5000pt; font-family:'Wingdings'; ">l&nbsp;</span><span style="mso-spacerun:'yes'; font-size:10.5000pt; font-family:'宋体'; ">能够进行节点间的数据均衡。</span></p>
<p style="margin-left:21.0000pt; text-indent:-21.0000pt; margin-bottom:0pt; margin-top:0pt; "><span style="mso-spacerun:'yes'; font-size:10.5000pt; font-family:'Wingdings'; ">l&nbsp;</span><span style="mso-spacerun:'yes'; font-size:10.5000pt; font-family:'宋体'; ">能够简单的查看所有的状态与日志（web客户端）<br /><br /></span></p>
<p style="margin-bottom:0pt; margin-top:0pt; "></p>
<p style="margin-bottom:0pt; margin-top:0pt; "><span style="mso-spacerun:'yes'; font-size:10.5000pt; font-family:'宋体'; ">可能主要是这些了。若自己实现，确实是个复杂而庞大的工程，现在我们有了Hadoop。<br /><br /><br /></span></p>
<p style="margin-bottom:0pt; margin-top:0pt; "></p>
<p style="margin-bottom:0pt; margin-top:0pt; "></p>
<p style="margin-bottom:0pt; margin-top:0pt; "><span style="mso-spacerun:'yes'; font-weight:bold; font-size:10.5000pt; font-family:'宋体'; ">系统物理架构：</span></p>
<p style="margin-bottom:0pt; margin-top:0pt; "><span style="mso-spacerun:'yes'; font-size:10.5000pt; font-family:'宋体'; ">我们使用了一台服务器，利用虚拟化，安装了7套64x位的CentOS。一个Namenode，6个Datanode，复制数设置为3。每个系统分配到一个cpu，2G内存，Datanode挂载了500G的存储空间。</span></p>
<p style="margin-bottom:0pt; margin-top:0pt; "><span style="mso-spacerun:'yes'; font-size:10.5000pt; font-family:'宋体'; ">理想的Hadoop的搭建环境，参照《Best&nbsp;Practices&nbsp;for&nbsp;Selecting&nbsp;Apache&nbsp;Hadoop&nbsp;Hardware》（http://hortonworks.com/blog/best-practices-for-selecting-apache-hadoop-hardware/）一文，以及一些其他的文章。</span></p>
<p style="margin-bottom:0pt; margin-top:0pt; "><span style="mso-spacerun:'yes'; font-size:10.5000pt; font-family:'宋体'; ">CPU：最好是双CPU，8核左右。不用太高了。</span></p>
<p style="margin-bottom:0pt; margin-top:0pt; "><span style="mso-spacerun:'yes'; font-size:10.5000pt; font-family:'宋体'; ">内存：推荐48G，但是4G应该就可以运行Hadoop了。</span></p>
<p style="margin-bottom:0pt; margin-top:0pt; "><span style="mso-spacerun:'yes'; font-size:10.5000pt; font-family:'宋体'; ">硬盘：7200转的SATA硬盘即可，Hadoop很占空间，所以尽量加。</span></p>
<p style="margin-bottom:0pt; margin-top:0pt; "><span style="mso-spacerun:'yes'; font-size:10.5000pt; font-family:'宋体'; ">网络：内部的数据交换要求非常高，内网最好是千兆网卡，带宽为1GB。<br /><br /></span></p>
<p style="margin-bottom:0pt; margin-top:0pt; "></p>
<p style="margin-bottom:0pt; margin-top:0pt; "><span style="mso-spacerun:'yes'; font-size:10.5000pt; font-family:'宋体'; ">理想与现实，有钱与没钱，呵呵。<br /><br /><br /></span></p>
<p style="margin-bottom:0pt; margin-top:0pt; "></p>
<p style="margin-bottom:0pt; margin-top:0pt; "><span style="mso-spacerun:'yes'; font-weight:bold; font-size:10.5000pt; font-family:'宋体'; ">系统软件架构：</span></p>
<p style="margin-bottom:0pt; margin-top:0pt; "><span style="mso-spacerun:'yes'; font-size:10.5000pt; font-family:'宋体'; ">Hadoop：版本使用的是1.0.3，再下来就是2了，为了尽量简化应用，所以不考虑2的新特性。对Hadoop没有做太多的设置，基本基于默认。70为Namenode，71-76为Datanode。</span></p>
<p style="margin-bottom:0pt; margin-top:0pt; "><span style="mso-spacerun:'yes'; font-size:10.5000pt; font-family:'宋体'; ">JDK：1.6.0_33&nbsp;（64x）<br /><br /><br /></span></p>
<p style="margin-bottom:0pt; margin-top:0pt; "></p>
<p style="margin-bottom:0pt; margin-top:0pt; "><span style="mso-spacerun:'yes'; font-weight:bold; font-size:10.5000pt; font-family:'宋体'; ">系统实施过程：</span></p>
<p style="margin-bottom:0pt; margin-top:0pt; "><span style="mso-spacerun:'yes'; font-size:10.5000pt; font-family:'宋体'; ">HDFS部分：</span></p>
<p style="margin-bottom:0pt; margin-top:0pt; "><span style="mso-spacerun:'yes'; font-size:10.5000pt; font-family:'宋体'; ">爬虫抓取数据，整理后存放在50文件服务器，70以外部挂载的形式读取。网页文件比较小，假如直接写入Hadoop对Namenode负载过大，所以入库前合并，将每小时网页整合成为一个文件写入HDFS，由于区分类别，所以每小时基本写入10个文件左右，总量在5-8G，耗时在40-50分钟。（这个过程中，由于爬虫的IO过于频繁，导致文件读取困难，所以做了定时任务，每小时启动一次，将需要处理的文件先拷贝到临时区域，合并入库之后再删除。此处应该是受到单核cpu的限制，所有操作均是串行，包括拷贝（cp）和合并入库（java），所以Namenode严重建议配置稍高。）</span></p>
<p style="margin-bottom:0pt; margin-top:0pt; "><span style="mso-spacerun:'yes'; font-size:10.5000pt; font-family:'宋体'; ">此处没有太多问题。</span></p>
<p style="margin-bottom:0pt; margin-top:0pt; "><span style="mso-spacerun:'yes'; font-size:10.5000pt; font-family:'宋体'; ">MapReduce部分：</span></p>
<p style="margin-bottom:0pt; margin-top:0pt; "><span style="mso-spacerun:'yes'; font-size:10.5000pt; font-family:'宋体'; ">写入完成后，进行分析工作，MapReduce。此处的工作过程为：数据库定时生成关键词列表文件。Job执行时会读取列表文件，匹配指定范围内的HDFS文件（过去一小时），匹配出对应的表达式与HTML，Map过程结束。在Reduce阶段，会将Map的所有数据入数据库（Mysql）。</span></p>
<p style="margin-bottom:0pt; margin-top:0pt; "><span style="mso-spacerun:'yes'; font-size:10.5000pt; font-family:'宋体'; ">此处出现过一些问题，记录下来。</span></p>
<p style="margin-bottom:0pt; margin-top:0pt; "><span style="mso-spacerun:'yes'; font-size:10.5000pt; font-family:'宋体'; ">1.&nbsp;</span><span style="mso-spacerun:'yes'; font-size:10.5000pt; font-family:'宋体'; ">Reduce阶段需要加载Mysql的第三方驱动包。我在三个环境测试过（公司、家里、发布环境），使用&nbsp;-libjars&nbsp;一定可以，有的地方不需要也可以。不明确，怀疑与HADOOP_HOME环境变量有关。</span></p>
<p style="margin-bottom:0pt; margin-top:0pt; "><span style="mso-spacerun:'yes'; font-size:10.5000pt; font-family:'宋体'; ">2.&nbsp;</span><span style="mso-spacerun:'yes'; font-size:10.5000pt; font-family:'宋体'; ">MR过程中使用log4j打印日志，在Hadoop临时目录（如果你没有配置dfs.name.dir，dfs.data.dir,mapred.local.dir.mapred.system.dir等目录，这些都会在hadoop.tmp.dir当中，我就偷懒都没配置）mapred文件夹中查看一下。</span></p>
<p style="margin-bottom:0pt; margin-top:0pt; text-align:justify; "></p>
<p style="margin-bottom:0pt; margin-top:0pt; text-align:justify; "><span style="mso-spacerun:'yes'; font-size:10.5000pt; font-family:'宋体'; ">整个过程实际上还是比较简单的，基本编码量就在Job的部分，但是一个Java文件就够了。在目前初级阶段应该还是比较好用的。现在还没有测试Job的执行效率。完成后会继续记录下来。有什么问题可以提出。我想到什么也会在本文继续更新。</span></p>
</div>
</div><img src ="http://www.blogjava.net/matuobasyouca/aggbug/385087.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/matuobasyouca/" target="_blank">一酌散千忧</a> 2012-08-08 20:21 <a href="http://www.blogjava.net/matuobasyouca/archive/2012/08/08/385087.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Hadoop完整分布式配置方式(Fully distributed mode)</title><link>http://www.blogjava.net/matuobasyouca/archive/2012/07/04/382150.html</link><dc:creator>一酌散千忧</dc:creator><author>一酌散千忧</author><pubDate>Tue, 03 Jul 2012 23:38:00 GMT</pubDate><guid>http://www.blogjava.net/matuobasyouca/archive/2012/07/04/382150.html</guid><wfw:comment>http://www.blogjava.net/matuobasyouca/comments/382150.html</wfw:comment><comments>http://www.blogjava.net/matuobasyouca/archive/2012/07/04/382150.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/matuobasyouca/comments/commentRss/382150.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/matuobasyouca/services/trackbacks/382150.html</trackback:ping><description><![CDATA[<div><p align="left" style="text-align:left;line-height:15.75pt;"><span style="font-family: 宋体; "></span></p><p align="left" style="text-align:left;line-height:15.75pt;"><span style="font-family: 宋体; ">硬件资源：</span></p>  <p align="left" style="text-align:left;line-height:15.75pt;"><span style="font-family: 宋体; ">三台</span><span style="font-family: Verdana; ">CentOS5.6</span><span style="font-family: 宋体; ">虚拟机（</span><span style="font-family: Verdana; ">Vmware</span><span style="font-family: 宋体; ">）</span></p>  <p align="left" style="text-align:left;line-height:15.75pt;"><span style="font-family: 宋体; ">本机</span><span style="font-family: Verdana; "> windows7 64x</span></p>  <p align="left" style="text-align:left;line-height:15.75pt;">&nbsp;</p>  <p align="left" style="text-align:left;line-height:15.75pt;"><span style="font-family: 宋体; ">基本资源配置：</span></p>  <p align="left" style="text-align:left;line-height:15.75pt;"><span style="font-family: 宋体; ">三台虚拟机均是克隆自同一个镜像</span></p>  <p align="left" style="text-align:left;line-height:15.75pt;"><span style="font-family: 宋体; ">已经安装了</span><span style="font-family: Verdana; ">Java</span><span style="font-family: 宋体; ">环境（</span><span style="font-family: Verdana; ">jdk1.6.0_25</span><span style="font-family: 宋体; ">）</span></p>  <p align="left" style="text-align:left;line-height:15.75pt;"><span style="font-family: Verdana; ">Hadoop</span><span style="font-family: 宋体; ">路径在</span><span style="font-family: Verdana; ">/usr/hadoop/hadoop-0.20.205.0</span></p>  <p align="left" style="text-align:left;line-height:15.75pt;">&nbsp;</p>  <p align="left" style="text-align:left;line-height:15.75pt;"><strong><span style="font-family: 宋体; ">操作步骤：</span></strong><strong></strong></p>  <p align="left" style="text-align:left;line-height:15.75pt;"><span style="font-family: Verdana; ">1</span><span style="font-family: 宋体; ">、机器名称规范</span></p>  <p align="left" style="text-align:left;line-height:15.75pt;"><span style="font-family: Verdana; ">ip</span><span style="font-family: 宋体; ">分别为</span><span style="font-family: Verdana; ">128</span><span style="font-family: 宋体; ">、</span><span style="font-family: Verdana; ">129</span><span style="font-family: 宋体; ">、</span><span style="font-family: Verdana; ">130</span><span style="font-family: 宋体; ">，将</span><span style="font-family: Verdana; ">128</span><span style="font-family: 宋体; ">设置为</span><span style="font-family: Verdana; ">master</span><span style="font-family: 宋体; ">，其他设置为</span><span style="font-family: Verdana; ">slave</span></p>  <p align="left" style="text-align:left;line-height:15.75pt;"><span style="font-family: 宋体; ">修改</span></p>  <p align="left" style="text-align:left;line-height:15.75pt;"><span style="font-family: Verdana; ">/etc/sysconfig/network</span></p>  <p align="left" style="text-align:left;line-height:15.75pt;"><span style="font-family: Verdana; ">/etc/hosts</span></p>  <p align="left" style="text-align:left;line-height:15.75pt;"><span style="font-family: 宋体; ">两处配置，名称分别为</span><span style="font-family: Verdana; ">hadoop-master\hadoop-slave01\hadoop-slave02</span></p>  <p align="left" style="text-align:left;line-height:15.75pt;"><span style="font-family: 宋体;color:red;">注意</span><span style="font-family: 宋体; ">：此处名称最好不用使用下划线，有可能引发</span><span style="font-family: Verdana; ">namenode</span><span style="font-family: 宋体; ">的启动异常。</span></p>  <p align="left" style="text-align:left;line-height:15.75pt;">&nbsp;</p>  <p align="left" style="text-align:left;line-height:15.75pt;"><span style="font-family: Verdana; ">2</span><span style="font-family: 宋体; ">、修改</span><span style="font-family: Verdana; ">Hadoop</span><span style="font-family: 宋体; ">配置</span>&nbsp;</p>  <p align="left" style="text-align:left;line-height:15.75pt;"><span style="font-family: 宋体; ">在</span><span style="font-family: Verdana; ">master</span><span style="font-family: 宋体; ">节点的</span><span style="font-family: Verdana; ">conf</span><span style="font-family: 宋体; ">中修改</span><span style="font-family: Verdana; ">master</span><span style="font-family: 宋体; ">和</span><span style="font-family: Verdana; ">slave</span><span style="font-family: 宋体; ">文件，分别为机器的</span><span style="font-family: Verdana; ">ip</span><span style="font-family: 宋体; ">地址</span></p>  <p align="left" style="text-align:left;line-height:15.75pt;">&nbsp;</p>  <p align="left" style="text-align:left;line-height:15.75pt;"><span style="font-family: 宋体; ">修改</span><span style="font-family: Verdana; ">master</span><span style="font-family: 宋体; ">节点的</span><span style="font-family: Verdana; ">conf</span><span style="font-family: 宋体; ">中：</span></p>  <p align="left" style="text-align:left;line-height:15.75pt;"><span style="font-family: Verdana; ">core-site.xml</span></p>  <p align="left" style="text-align:left;line-height:15.75pt;"><span style="font-family: Verdana; ">&lt;property&gt;</span></p>  <p align="left" style="text-align:left;line-height:15.75pt;"><span style="font-family: Verdana; ">&lt;name&gt;fs.default.name&lt;/name&gt;</span></p>  <p align="left" style="text-align:left;line-height:15.75pt;"><span style="font-family: Verdana; ">&lt;value&gt;hdfs://ip-master:9000&lt;/value&gt;</span></p>  <p align="left" style="text-align:left;line-height:15.75pt;"><span style="font-family: Verdana; ">&lt;/property&gt;</span></p>  <p align="left" style="text-align:left;line-height:15.75pt;">&nbsp;</p>  <p align="left" style="text-align:left;line-height:15.75pt;"><span style="font-family: Verdana; ">mapred-site.xml</span></p>  <p align="left" style="text-align:left;line-height:15.75pt;"><span style="font-family: Verdana; ">&lt;property&gt;</span></p>  <p align="left" style="text-align:left;line-height:15.75pt;"><span style="font-family: Verdana; ">&lt;name&gt;mapred.job.tracker&lt;/name&gt; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;</span></p>  <p align="left" style="text-align:left;line-height:15.75pt;"><span style="font-family: Verdana; ">&lt;value&gt;master:9001&lt;/value&gt; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;</span></p>  <p align="left" style="text-align:left;line-height:15.75pt;"><span style="font-family: Verdana; ">&lt;/property&gt;</span></p>  <p align="left" style="text-align:left;line-height:15.75pt;">&nbsp;</p>  <p align="left" style="text-align:left;line-height:15.75pt;"><span style="font-family: Verdana; ">hdfs-site.xm</span></p>  <p align="left" style="text-align:left;line-height:15.75pt;"><span style="font-family: Verdana; ">&lt;property&gt;</span></p>  <p align="left" style="text-align:left;line-height:15.75pt;"><span style="font-family: Verdana; ">&lt;name&gt;dfs.replication&lt;/name&gt;</span></p>  <p align="left" style="text-align:left;line-height:15.75pt;"><span style="font-family: Verdana; ">&lt;value&gt;2&lt;/value&gt;</span></p>  <p align="left" style="text-align:left;line-height:15.75pt;"><span style="font-family: Verdana; ">&lt;/property&gt;</span></p>  <p align="left" style="text-align:left;line-height:15.75pt;"><span style="font-family: 宋体; ">注意此处的端口号均为默认。</span></p>  <p align="left" style="text-align:left;line-height:15.75pt;">&nbsp;</p>  <p align="left" style="text-align:left;line-height:15.75pt;">&nbsp;</p>  <p align="left" style="text-align:left;line-height:15.75pt;"><span style="font-family: Verdana; ">3</span><span style="font-family: 宋体; ">、建立</span><span style="font-family: Verdana; ">m-s</span><span style="font-family: 宋体; ">之间的</span><span style="font-family: Verdana; ">ssh</span><span style="font-family: 宋体; ">连接</span></p>  <p align="left" style="text-align:left;line-height:15.75pt;"><span style="font-family: 宋体; ">首先</span><span style="font-family: Verdana; ">master</span><span style="font-family: 宋体; ">与</span><span style="font-family: Verdana; ">slave</span><span style="font-family: 宋体; ">机器都需要进行</span><span style="font-family: Verdana; ">ssh</span><span style="font-family: 宋体; ">信任文件生成，执行如下命令：</span></p>  <p align="left" style="text-align:left;line-height:15.75pt;"><span style="font-family: Verdana; ">$ ssh-keygen -t rsa</span></p>  <p align="left" style="text-align:left;line-height:15.75pt;"><span style="font-family: 宋体; ">中间需要输入的地方直接回车，接受缺省值即可</span></p>  <p align="left" style="text-align:left;line-height:15.75pt;">&nbsp;</p>  <p align="left" style="text-align:left;line-height:15.75pt;"><span style="font-family: 宋体; ">由于使用</span><span style="font-family: Verdana; ">root</span><span style="font-family: 宋体; ">用户登录，所以密钥文件生成在</span><span style="font-family: Verdana; "> /root/.ssh/</span><span style="font-family: 宋体; ">文件夹下，存有一对密钥</span><span style="font-family: Verdana; ">id_dsa</span><span style="font-family: 宋体; ">和</span><span style="font-family: Verdana; ">id_dsa.pub</span><span style="font-family: 宋体; ">。</span></p>  <p align="left" style="text-align:left;line-height:15.75pt;"><span style="font-family: 宋体; ">此处</span><span style="font-family: Verdana; ">id_dsa</span><span style="font-family: 宋体; ">（私钥）必须为其他用户不可读，所以文件属性应当是</span><span style="font-family: Verdana; ">600</span></p>  <p align="left" style="text-align:left;line-height:15.75pt;">&nbsp;</p>  <p align="left" style="text-align:left;line-height:15.75pt;"><span style="font-family: 宋体; ">在</span><span style="font-family: Verdana; ">master</span><span style="font-family: 宋体; ">机器执行：</span></p>  <p align="left" style="text-align:left;line-height:15.75pt;"><span style="font-family: 宋体; ">将</span><span style="font-family: Verdana; ">id_dsa.pub</span><span style="font-family: 宋体; ">（公钥）复制为</span><span style="font-family: Verdana; "> authorized_keys</span></p>  <p align="left" style="text-align:left;line-height:15.75pt;"><span style="font-family: Verdana; ">$ cp id_dsa.pub authorized_keys</span></p>  <p align="left" style="text-align:left;line-height:15.75pt;"><span style="font-family: 宋体; ">如果是多台机器需要</span><span style="font-family: Verdana; ">,</span><span style="font-family: 宋体; ">无密码登陆</span><span style="font-family: Verdana; ">,</span><span style="font-family: 宋体; ">则各自机器产生公钥追加到</span><span style="font-family: Verdana; ">authorized_keys</span><span style="font-family: 宋体; ">即可</span><span style="font-family: Verdana; ">.</span></p>  <p align="left" style="text-align:left;line-height:15.75pt;">&nbsp;</p>  <p align="left" style="text-align:left;line-height:15.75pt;"><span style="font-family: 宋体; ">使用</span><span style="font-family: Verdana; ">scp</span><span style="font-family: 宋体; ">协议覆盖</span><span style="font-family: Verdana; ">slave</span><span style="font-family: 宋体; ">端的密钥文件夹，使得</span><span style="font-family: Verdana; ">slave</span><span style="font-family: 宋体; ">机器信任来自</span><span style="font-family: Verdana; ">master</span><span style="font-family: 宋体; ">的连接</span><span style="font-family: Verdana; ">:</span></p>  <p align="left" style="text-align:left;line-height:15.75pt;"><span style="font-family: Verdana; ">$ scp /root/.ssh/* ip-slave:/root/.ssh</span></p>  <p align="left" style="text-align:left;line-height:15.75pt;">&nbsp;</p>  <p align="left" style="text-align:left;line-height:15.75pt;">&nbsp;</p>  <p align="left" style="text-align:left;line-height:15.75pt;"><span style="font-family: Verdana; ">4</span><span style="font-family: 宋体; ">、启动服务</span>&nbsp;</p>  <p align="left" style="text-align:left;line-height:15.75pt;"><span style="font-family: 宋体; ">建议将</span><span style="font-family: Verdana; ">$HADOOP_HOME/bin</span><span style="font-family: 宋体; ">下的所有文件给与执行权限：</span></p>  <p align="left" style="text-align:left;line-height:15.75pt;"><span style="font-family: Verdana; ">$ chmod 777 bin</span></p>  <p align="left" style="text-align:left;line-height:15.75pt;">&nbsp;</p>  <p align="left" style="text-align:left;line-height:15.75pt;"><span style="font-family: Verdana; ">master</span><span style="font-family: 宋体; ">作为</span><span style="font-family: Verdana; ">namenod</span><span style="font-family: 宋体; ">需要执行如下脚本：</span></p>  <p align="left" style="text-align:left;line-height:15.75pt;"><span style="font-family: Verdana; ">$HADOOP_HOME/bin/hadoop namenode &#8211;format</span></p>  <p align="left" style="text-align:left;line-height:15.75pt;">&nbsp;</p>  <p align="left" style="text-align:left;line-height:15.75pt;"><span style="font-family: 宋体; ">完成后执行</span><span style="font-family: Verdana; "> $HADOOP_HOME/bin/start-all.sh</span></p>  <p align="left" style="text-align:left;line-height:15.75pt;">&nbsp;</p>  <p align="left" style="text-align:left;line-height:15.75pt;"><span style="font-family: Verdana; ">5</span><span style="font-family: 宋体; ">、问题检查</span></p>  <p align="left" style="text-align:left;line-height:15.75pt;"><span style="font-family: 宋体; ">在</span><span style="font-family: Verdana; ">Hadoop</span><span style="font-family: 宋体; ">根目录下的</span><span style="font-family: Verdana; ">logs</span><span style="font-family: 宋体; ">文件中，检查各个服务日志的启动情况</span></p>  <p align="left" style="text-align:left;line-height:15.75pt;">&nbsp;</p>  <p align="left" style="text-align:left;line-height:15.75pt;">&nbsp;</p>  <p align="left" style="text-align:left;line-height:15.75pt;"><span style="font-family: Verdana; ">6</span><span style="font-family: 宋体; ">、其他情况说明：</span></p>  <p align="left" style="text-align:left;line-height:15.75pt;"><span style="font-family: Verdana; ">Q: $HADOOP_HOME is deprecated</span></p>  <p align="left" style="margin-bottom:12.0pt;text-align:left; line-height:15.75pt;"><span style="font-family: Verdana; ">A: </span><span style="font-family: 宋体; ">基本不会产生任何影响。由于脚本启动时设置了该环境变量，就会提示用户原有环境变量失效。可以取消环境变量设置，或者直接去</span><span style="font-family: Verdana; ">bin/hadoop</span><span style="font-family: 宋体; ">中找到这句话，去掉即可</span></p>  <p align="left" style="margin-bottom:12.0pt;text-align:left; line-height:15.75pt;">&nbsp;</p>  <p align="left" style="text-align:left;line-height:15.75pt;"><span style="font-family: Verdana; ">Q: </span><span style="font-family: 宋体; ">无效的选项</span><span style="font-family: Verdana; "> -jvm / Unrecognized option: -jvm</span></p>  <p align="left" style="text-align:left;line-height:15.75pt;"><span style="font-family: Verdana; ">A: </span><span style="font-family: 宋体; ">在使用</span><span style="font-family: Verdana; ">root</span><span style="font-family: 宋体; ">用户登录时</span><span style="font-family: Verdana; "> bin/hadoop </span><span style="font-family: 宋体; ">脚本就会进行判断，加上</span><span style="font-family: Verdana; ">-jvm</span><span style="font-family: 宋体; ">参数。此处是为了进入</span><span style="font-family: Verdana; ">jsvc</span><span style="font-family: 宋体; ">（</span><span style="font-family: Verdana; ">http://commons.apache.org/daemon/jsvc.html</span><span style="font-family: 宋体; ">），此处并不确定是否</span><span style="font-family: Verdana; ">bug</span><span style="font-family: 宋体; ">，也不再进行详细的追溯，解决方法就是进入</span><span style="font-family: Verdana; "> bin/hadoop </span><span style="font-family: 宋体; ">脚本中</span> <span style="font-family: 宋体; ">找到</span><span style="font-family: Verdana; "> jvm </span><span style="font-family: 宋体; ">参数并去掉。</span></p>  <p align="left" style="text-align:left;line-height:15.75pt;">&nbsp;</p>  <p align="left" style="text-align:left;line-height:15.75pt;">&nbsp;</p>  <p align="left" style="text-align:left;line-height:15.75pt;">&nbsp;</p>  <p align="left" style="text-align:left;line-height:15.75pt;">&nbsp;</p>  <p align="left" style="text-align:left;line-height:15.75pt;">&nbsp;</p>  <p>&nbsp;</p><p>&nbsp;</p></div><div></div><img src ="http://www.blogjava.net/matuobasyouca/aggbug/382150.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/matuobasyouca/" target="_blank">一酌散千忧</a> 2012-07-04 07:38 <a href="http://www.blogjava.net/matuobasyouca/archive/2012/07/04/382150.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Zookeeper的学习总结</title><link>http://www.blogjava.net/matuobasyouca/archive/2012/05/15/378164.html</link><dc:creator>一酌散千忧</dc:creator><author>一酌散千忧</author><pubDate>Tue, 15 May 2012 03:02:00 GMT</pubDate><guid>http://www.blogjava.net/matuobasyouca/archive/2012/05/15/378164.html</guid><wfw:comment>http://www.blogjava.net/matuobasyouca/comments/378164.html</wfw:comment><comments>http://www.blogjava.net/matuobasyouca/archive/2012/05/15/378164.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/matuobasyouca/comments/commentRss/378164.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/matuobasyouca/services/trackbacks/378164.html</trackback:ping><description><![CDATA[<div><div><h3><span style="mso-spacerun:'yes'; font-weight:bold; font-size:16.0000pt; font-family:'宋体'; ">Zookeeper的核心概念：</span></h3><p style="margin-bottom:0pt; margin-top:0pt; "><span style="mso-spacerun:'yes'; font-weight:bold; font-size:10.5000pt; font-family:'宋体'; ">ZNode</span></p><p style="margin-bottom:0pt; margin-top:0pt; "><span style="mso-spacerun:'yes'; font-size:10.5000pt; font-family:'宋体'; ">Znode就是核心结构，Zookeeper服务中是由大量的Znode构成。Znode一般是由客户端建立和修改，作为信息或标志的载体，甚至本身就是标志。</span></p><p style="margin-bottom:0pt; margin-top:0pt; "><span style="mso-spacerun:'yes'; font-size:10.5000pt; font-family:'宋体'; ">Znode可以设置为持久（PERSISTENT）或临时（EPHEMERAL），区别在于临时的节点若断开连接后就自动删除。建立节点时可选择是否使用序列号命名（SEQUENTIAL），若启用则会自动在节点名后加入唯一序列编号。</span></p><p style="margin-bottom:0pt; margin-top:0pt; "><span style="mso-spacerun:'yes'; font-weight:bold; font-size:10.5000pt; font-family:'宋体'; ">Session</span></p><p style="margin-bottom:0pt; margin-top:0pt; "><span style="mso-spacerun:'yes'; font-size:10.5000pt; font-family:'宋体'; ">作为客户端和Zookeeper服务之间交互的凭证。</span></p><p style="margin-bottom:0pt; margin-top:0pt; "><span style="mso-spacerun:'yes'; font-weight:bold; font-size:10.5000pt; font-family:'宋体'; ">Watch</span></p><p style="margin-bottom:0pt; margin-top:0pt; "><span style="mso-spacerun:'yes'; font-size:10.5000pt; font-family:'宋体'; ">当客户端对节点信息进行查询操作之后，可以选择是否设置一个Watch。其作用就是当本次查询的数据在服务器端发生变化之后，会对设置Watch的客户端发送通知。一次发送之后，就将删除该Watch，以后的变更或不再设置Watch则不会通知。</span></p><p style="margin-bottom:0pt; margin-top:0pt; "><span style="mso-spacerun:'yes'; font-weight:bold; font-size:10.5000pt; font-family:'宋体'; ">ACLs</span></p><p style="margin-bottom:0pt; margin-top:0pt; "><span style="mso-spacerun:'yes'; font-size:10.5000pt; font-family:'宋体'; ">节点的权限限制使用ACL，如增删改查操作。</span></p><p style="margin-bottom:0pt; margin-top:0pt; "></p><h3><span style="mso-spacerun:'yes'; font-weight:bold; font-size:16.0000pt; font-family:'宋体'; ">Zookeeper的服务器安装：</span></h3><p style="margin-bottom:0pt; margin-top:0pt; "><span style="mso-spacerun:'yes'; font-size:10.5000pt; font-family:'宋体'; ">1、</span><span style="mso-spacerun:'yes'; font-size:10.5000pt; font-family:'宋体'; ">下载对应版本号的tar.gz文件</span></p><p style="margin-bottom:0pt; margin-top:0pt; "><span style="mso-spacerun:'yes'; font-size:10.5000pt; font-family:'宋体'; ">2、</span><span style="mso-spacerun:'yes'; font-size:10.5000pt; font-family:'宋体'; ">使用&nbsp;</span><span style="color: #000000; font-style: normal; font-size: 10.5pt; font-family: Arial; background-image: initial; background-attachment: initial; background-origin: initial; background-clip: initial; background-color: #ffffff; background-position: initial initial; background-repeat: initial initial; ">tar&nbsp;xzvf&nbsp;zookeeper-3.4.2.tar.gz&nbsp;-C&nbsp;./</span><span style="color: #000000; font-style: normal; font-size: 10.5pt; font-family: 宋体; background-image: initial; background-attachment: initial; background-origin: initial; background-clip: initial; background-color: #ffffff; background-position: initial initial; background-repeat: initial initial; ">&nbsp;解压</span></p><p style="margin-bottom:0pt; margin-top:0pt; "><span style="mso-spacerun:'yes'; font-size:10.5000pt; font-family:'宋体'; ">3、</span><span style="mso-spacerun:'yes'; font-size:10.5000pt; font-family:'宋体'; ">设置，将conf/zoo.example.cfg复制到conf/zoo.cfg或者手动建立一个新的。</span></p><p style="margin-bottom:0pt; margin-top:0pt; "><span style="mso-spacerun:'yes'; font-size:10.5000pt; font-family:'宋体'; ">4、</span><span style="mso-spacerun:'yes'; font-size:10.5000pt; font-family:'宋体'; ">启动Zookeeper服务：bin/zkServer.sh&nbsp;start</span></p><p style="margin-bottom:0pt; margin-top:0pt; "><span style="mso-spacerun:'yes'; font-size:10.5000pt; font-family:'宋体'; ">5、</span><span style="mso-spacerun:'yes'; font-size:10.5000pt; font-family:'宋体'; ">启动客户端连接：bin/zkCli.sh&nbsp;-server&nbsp;127.0.0.1:2181（此处在本机，且使用了默认端口，且在Java环境中）</span></p><p style="margin-bottom:0pt; margin-top:0pt; "><span style="mso-spacerun:'yes'; font-size:10.5000pt; font-family:'宋体'; ">6、</span><span style="mso-spacerun:'yes'; font-size:10.5000pt; font-family:'宋体'; ">使用命令：ls、get、set等。</span></p><p style="margin-bottom:0pt; margin-top:0pt; "><span style="mso-spacerun:'yes'; font-size:10.5000pt; font-family:'宋体'; ">7、</span><span style="mso-spacerun:'yes'; font-size:10.5000pt; font-family:'宋体'; ">关闭Zookeeper服务：bin/zkServer.sh&nbsp;stop</span></p><p style="margin-bottom:0pt; margin-top:0pt; text-align:justify; "></p><h3><span style="mso-spacerun:'yes'; font-weight:bold; font-size:16.0000pt; font-family:'宋体'; ">Zookeeper代码编写：</span></h3><p style="margin-bottom:0pt; margin-top:0pt; text-align:justify; "><span style="mso-spacerun:'yes'; font-size:10.5000pt; font-family:'宋体'; ">代码编写部分比较简单，因为暴露的接口很少，主要复杂在于项目如何使用节点以及节点信息。</span></p><p style="margin-bottom:0pt; margin-top:0pt; text-align:justify; "><span style="mso-spacerun:'yes'; font-size:10.5000pt; font-family:'宋体'; ">启动Zookeeper服务之后，客户端代码进行节点的增删，Watch的设置，内容的改查等。</span></p><p style="margin-bottom:0pt; margin-top:0pt; text-align:justify; "><span style="mso-spacerun:'yes'; font-size:10.5000pt; font-family:'宋体'; ">此处建议查看官方的《Programming&nbsp;with&nbsp;ZooKeeper&nbsp;-&nbsp;A&nbsp;basic&nbsp;tutorial》部分，当中举了两个例子来模拟分布式系统的应用。</span></p><p style="margin-bottom:0pt; margin-top:0pt; text-align:justify; "><span style="mso-spacerun:'yes'; font-size:10.5000pt; font-family:'宋体'; ">代码基本没有问题，唯一需要注意的就是：若之间按照原版进行调试时，有可能在调用</span></p><p style="margin-bottom:0pt; margin-top:0pt; text-align:justify; "></p><p style="margin-bottom:0pt; margin-top:0pt; text-align:justify; "><font class="Apple-style-span" face="宋体"><div style="background-color:#eeeeee;font-size:13px;border:1px solid #CCCCCC;padding-right: 5px;padding-bottom: 4px;padding-left: 4px;padding-top: 4px;width: 98%;word-break:break-all"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><span style="color: #000000; ">&nbsp;Stat&nbsp;s&nbsp;</span><span style="color: #000000; ">=</span><span style="color: #000000; ">&nbsp;zk.exists(root,&nbsp;</span><span style="color: #0000FF; ">false</span><span style="color: #000000; ">);</span></div></font></p><p style="margin-bottom:0pt; margin-top:0pt; text-align:justify; "></p><p style="margin-bottom:0pt; margin-top:0pt; text-align:justify; "><span style="mso-spacerun:'yes'; font-size:10.5000pt; font-family:'宋体'; ">这句代码时会出现一个异常，当中包括&#8220;KeeperErrorCode&nbsp;=&nbsp;ConnectionLoss&nbsp;for&#8221;。</span></p><p style="margin-bottom:0pt; margin-top:0pt; text-align:justify; "><span style="mso-spacerun:'yes'; font-size:10.5000pt; font-family:'宋体'; ">这个问题引起的原因可以看一下代码</span></p><p style="margin-bottom:0pt; margin-top:0pt; text-align:justify; "></p><p style="margin-bottom:0pt; margin-top:0pt; text-align:justify; "><font class="Apple-style-span" face="宋体"><div style="background-color:#eeeeee;font-size:13px;border:1px solid #CCCCCC;padding-right: 5px;padding-bottom: 4px;padding-left: 4px;padding-top: 4px;width: 98%;word-break:break-all"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><span style="color: #000000; ">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; System.out.println(</span><span style="color: #000000; ">"</span><span style="color: #000000; ">Starting&nbsp;ZK:</span><span style="color: #000000; ">"</span><span style="color: #000000; ">);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;zk&nbsp;</span><span style="color: #000000; ">=</span><span style="color: #000000; ">&nbsp;</span><span style="color: #0000FF; ">new</span><span style="color: #000000; ">&nbsp;ZooKeeper(address,&nbsp;</span><span style="color: #000000; ">3000</span><span style="color: #000000; ">,&nbsp;</span><span style="color: #0000FF; ">this</span><span style="color: #000000; ">);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;mutex&nbsp;</span><span style="color: #000000; ">=</span><span style="color: #000000; ">&nbsp;</span><span style="color: #0000FF; ">new</span><span style="color: #000000; ">&nbsp;Integer(</span><span style="color: #000000; ">-</span><span style="color: #000000; ">1</span><span style="color: #000000; ">);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println(</span><span style="color: #000000; ">"</span><span style="color: #000000; ">Finished&nbsp;starting&nbsp;ZK:&nbsp;</span><span style="color: #000000; ">"</span><span style="color: #000000; ">&nbsp;</span><span style="color: #000000; ">+</span><span style="color: #000000; ">&nbsp;zk);</span></div></font></p><p style="margin-bottom:0pt; margin-top:0pt; text-align:justify; "></p><p style="margin-bottom:0pt; margin-top:0pt; text-align:justify; "><span style="mso-spacerun:'yes'; font-size:10.5000pt; font-family:'宋体'; ">最后一行有打印出Zookeeper目前的信息，若未修改的原代码，此处的State应当是CONECTING。连接中的时候去验证是否存在节点会报错。解决的方法也很简单，就是等到Zookeeper客户端以及完全连接上服务器，State为CONECTED之后再进行其他操作。给出代码示例：</span></p><p style="margin-bottom:0pt; margin-top:0pt; text-align:justify; "></p><p style="text-indent:21.0000pt; margin-bottom:0pt; margin-top:0pt; text-align:justify; "><font class="Apple-style-span" face="宋体"><div style="background-color:#eeeeee;font-size:13px;border:1px solid #CCCCCC;padding-right: 5px;padding-bottom: 4px;padding-left: 4px;padding-top: 4px;width: 98%;word-break:break-all"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><span style="color: #008000; ">//</span><span style="color: #008000; ">&nbsp;使用了倒数计数，只需要计数一次</span><span style="color: #008000; "><br /></span><span style="color: #0000FF; ">private</span><span style="color: #000000; ">&nbsp;CountDownLatch&nbsp;connectedSignal&nbsp;</span><span style="color: #000000; ">=</span><span style="color: #000000; ">&nbsp;</span><span style="color: #0000FF; ">new</span><span style="color: #000000; ">&nbsp;CountDownLatch(</span><span style="color: #000000; ">1</span><span style="color: #000000; ">);&nbsp;<br />SyncPrimitive(String&nbsp;address)&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">if</span><span style="color: #000000; ">(zk&nbsp;</span><span style="color: #000000; ">==</span><span style="color: #000000; ">&nbsp;</span><span style="color: #0000FF; ">null</span><span style="color: #000000; ">){<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">try</span><span style="color: #000000; ">&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println(</span><span style="color: #000000; ">"</span><span style="color: #000000; ">Starting&nbsp;ZK:</span><span style="color: #000000; ">"</span><span style="color: #000000; ">);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;zk&nbsp;</span><span style="color: #000000; ">=</span><span style="color: #000000; ">&nbsp;</span><span style="color: #0000FF; ">new</span><span style="color: #000000; ">&nbsp;ZooKeeper(address,&nbsp;</span><span style="color: #000000; ">3000</span><span style="color: #000000; ">,&nbsp;</span><span style="color: #0000FF; ">this</span><span style="color: #000000; ">);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;mutex&nbsp;</span><span style="color: #000000; ">=</span><span style="color: #000000; ">&nbsp;</span><span style="color: #0000FF; ">new</span><span style="color: #000000; ">&nbsp;Integer(</span><span style="color: #000000; ">-</span><span style="color: #000000; ">1</span><span style="color: #000000; ">);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;connectedSignal.await();&nbsp;</span><span style="color: #008000; ">//</span><span style="color: #008000; ">&nbsp;等待连接完成</span><span style="color: #008000; "><br /></span><span style="color: #000000; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println(</span><span style="color: #000000; ">"</span><span style="color: #000000; ">Finished&nbsp;starting&nbsp;ZK:&nbsp;</span><span style="color: #000000; ">"</span><span style="color: #000000; ">&nbsp;</span><span style="color: #000000; ">+</span><span style="color: #000000; ">&nbsp;zk);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;</span><span style="color: #0000FF; ">catch</span><span style="color: #000000; ">&nbsp;(IOException&nbsp;e)&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println(e.toString());<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;zk&nbsp;</span><span style="color: #000000; ">=</span><span style="color: #000000; ">&nbsp;</span><span style="color: #0000FF; ">null</span><span style="color: #000000; ">;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;</span><span style="color: #0000FF; ">catch</span><span style="color: #000000; ">&nbsp;(InterruptedException&nbsp;e)&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000; ">//</span><span style="color: #008000; ">&nbsp;TODO&nbsp;Auto-generated&nbsp;catch&nbsp;block</span><span style="color: #008000; "><br /></span><span style="color: #000000; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;e.printStackTrace();<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000; ">//</span><span style="color: #008000; ">else&nbsp;mutex&nbsp;=&nbsp;new&nbsp;Integer(-1);</span><span style="color: #008000; "><br /></span><span style="color: #000000; ">}<br /></span><span style="color: #0000FF; ">synchronized</span><span style="color: #000000; ">&nbsp;</span><span style="color: #0000FF; ">public</span><span style="color: #000000; ">&nbsp;</span><span style="color: #0000FF; ">void</span><span style="color: #000000; ">&nbsp;process(WatchedEvent&nbsp;event)&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000; ">//</span><span style="color: #008000; ">&nbsp;此处设立在Watch中会在状态变化后触发事件</span><span style="color: #008000; "><br /></span><span style="color: #000000; ">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">if</span><span style="color: #000000; ">&nbsp;(event.getState()&nbsp;</span><span style="color: #000000; ">==</span><span style="color: #000000; ">&nbsp;KeeperState.SyncConnected)&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;connectedSignal.countDown();</span><span style="color: #008000; ">//</span><span style="color: #008000; ">&nbsp;倒数-1</span><span style="color: #008000; "><br /></span><span style="color: #000000; ">&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">synchronized</span><span style="color: #000000; ">&nbsp;(mutex)&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000; ">//</span><span style="color: #008000; ">System.out.println("Process:&nbsp;"&nbsp;+&nbsp;event.getType());</span><span style="color: #008000; "><br /></span><span style="color: #000000; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;mutex.notify();<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />}</span></div></font></p><p style="text-indent:21.0000pt; margin-bottom:0pt; margin-top:0pt; text-align:justify; "></p><p style="margin-bottom:0pt; margin-top:0pt; text-align:justify; "><span style="mso-spacerun:'yes'; font-size:10.5000pt; font-family:'宋体'; ">这样就可以正确运行代码了。</span></p><p style="margin-bottom:0pt; margin-top:0pt; text-align:justify; "></p><h3><span style="mso-spacerun:'yes'; font-weight:bold; font-size:16.0000pt; font-family:'宋体'; ">Zookeeper的应用场景及方式：</span></h3><p style="margin-bottom:0pt; margin-top:0pt; text-align:justify; "><span style="mso-spacerun:'yes'; font-size:10.5000pt; font-family:'宋体'; ">此处是为引用，原地址为（</span><a href="http://rdc.taobao.com/team/jm/archives/1232"><span style="mso-spacerun:'yes'; color:#0000ff; text-decoration:underline ;font-size:10.5000pt; font-family:'Times New Roman'; ">http://rdc.taobao.com/team/jm/archives/1232</span></a>&nbsp;<span style="mso-spacerun:'yes'; font-size:10.5000pt; font-family:'宋体'; ">）</span></p><p style="margin-bottom:0pt; margin-top:0pt; text-align:justify; "></p><p style="margin-bottom:0pt; margin-top:0pt; text-align:justify; "><span style="mso-spacerun:'yes'; font-size:10.5000pt; font-family:'宋体'; ">ZooKeeper是一个高可用的分布式数据管理与系统协调框架。基于对Paxos算法的实现，使该框架保证了分布式环境中数据的强一致性，也正是基于这样的特性，使得zookeeper能够应用于很多场景。网上对zk的使用场景也有不少介绍，本文将结合作者身边的项目例子，系统的对zk的使用场景进行归类介绍。&nbsp;值得注意的是，zk并不是生来就为这些场景设计，都是后来众多开发者根据框架的特性，摸索出来的典型使用方法。因此，也非常欢迎你分享你在ZK使用上的奇技淫巧。</span></p><p style="margin-bottom:0pt; margin-top:0pt; text-align:justify; "></p><table style="border-collapse:collapse; margin-left:5.4000pt; padding:0.0000pt 0.0000pt 0.0000pt 0.0000pt ; "><tbody><tr><td width="57" valign="top" style="width:42.8500pt; padding:2.2500pt 7.5000pt 2.2500pt 7.5000pt ; border-left:0.7500pt solid #cccccc; border-right:0.7500pt solid #cccccc; border-top:0.7500pt solid #cccccc; border-bottom:0.7500pt solid #cccccc; background:#ffffff; "><p style="margin-bottom:0pt; margin-top:0pt; text-autospace:ideograph-other; text-align:left; vertical-align:; background:#ffffff; "><span style="mso-spacerun:'yes'; color:#333333; font-weight:bold; font-size:9.5000pt; font-family:'Tahoma'; background:#ffffff; ">场景类别</span></p></td><td width="259" valign="top" style="width:194.7500pt; padding:2.2500pt 7.5000pt 2.2500pt 7.5000pt ; border-left:none; ; ; border-right:0.7500pt solid #cccccc; border-top:0.7500pt solid #cccccc; border-bottom:0.7500pt solid #cccccc; background:#ffffff; "><p style="margin-bottom:0pt; margin-top:0pt; text-autospace:ideograph-other; text-align:left; vertical-align:; background:#ffffff; "><span style="mso-spacerun:'yes'; color:#333333; font-weight:bold; font-size:9.5000pt; font-family:'Tahoma'; background:#ffffff; ">典型场景描述（ZK特性，使用方法）</span></p></td><td width="259" valign="top" style="width:194.7500pt; padding:2.2500pt 7.5000pt 2.2500pt 7.5000pt ; border-left:none; ; ; border-right:0.7500pt solid #cccccc; border-top:0.7500pt solid #cccccc; border-bottom:0.7500pt solid #cccccc; background:#ffffff; "><p style="margin-bottom:0pt; margin-top:0pt; text-autospace:ideograph-other; text-align:left; vertical-align:; background:#ffffff; "><span style="mso-spacerun:'yes'; color:#333333; font-weight:bold; font-size:9.5000pt; font-family:'Tahoma'; background:#ffffff; ">应用中的具体使用</span></p></td></tr><tr><td width="57" valign="top" style="width:42.8500pt; padding:2.2500pt 7.5000pt 2.2500pt 7.5000pt ; border-left:0.7500pt solid #cccccc; border-right:0.7500pt solid #cccccc; border-top:none; ; border-bottom:0.7500pt solid #cccccc; background:#ffffff; "><p style="margin-bottom:0pt; margin-top:0pt; text-autospace:ideograph-other; text-align:left; vertical-align:; background:#ffffff; "><span style="mso-spacerun:'yes'; color:#333333; font-weight:bold; font-size:9.5000pt; font-family:'Tahoma'; background:#ffffff; ">数据发布与订阅</span></p></td><td width="259" valign="top" style="width:194.7500pt; padding:2.2500pt 7.5000pt 2.2500pt 7.5000pt ; border-left:none; ; ; border-right:0.7500pt solid #cccccc; border-top:none; ; border-bottom:0.7500pt solid #cccccc; background:#ffffff; "><p style="margin-bottom:0pt; margin-top:0pt; text-autospace:ideograph-other; text-align:left; vertical-align:; background:#ffffff; "><span style="mso-spacerun:'yes'; color:#333333; font-size:9.5000pt; font-family:'Tahoma'; background:#ffffff; ">发布与订阅即所谓的配置管理，顾名思义就是将数据发布到zk节点上，供订阅者动态获取数据，实现配置信息的集中式管理和动态更新。例如全局的配置信息，地址列表等就非常适合使用。</span></p></td><td width="259" valign="top" style="width:194.7500pt; padding:2.2500pt 7.5000pt 2.2500pt 7.5000pt ; border-left:none; ; ; border-right:0.7500pt solid #cccccc; border-top:none; ; border-bottom:0.7500pt solid #cccccc; background:#ffffff; "><p style="margin-bottom:0pt; margin-top:0pt; text-autospace:ideograph-other; text-align:left; vertical-align:; background:#ffffff; "><span style="mso-spacerun:'yes'; color:#333333; font-size:9.5000pt; font-family:'Tahoma'; background:#ffffff; ">1.&nbsp;索引信息和集群中机器节点状态存放在zk的一些指定节点，供各个客户端订阅使用。2.&nbsp;系统日志（经过处理后的）存储，这些日志通常2-3天后被清除。&nbsp;</span></p><p style="margin-bottom:13.5000pt; margin-top:0pt; text-autospace:ideograph-other; text-align:left; line-height:13.5000pt; background:#ffffff; "><span style="mso-spacerun:'yes'; color:#333333; font-size:9.5000pt; font-family:'Tahoma'; background:#ffffff; ">3.&nbsp;应用中用到的一些配置信息集中管理，在应用启动的时候主动来获取一次，并且在节点上注册一个Watcher，以后每次配置有更新，实时通知到应用，获取最新配置信息。</span></p><p style="margin-bottom:13.5000pt; margin-top:0pt; text-autospace:ideograph-other; text-align:left; line-height:13.5000pt; background:#ffffff; "><span style="mso-spacerun:'yes'; color:#333333; font-size:9.5000pt; font-family:'Tahoma'; background:#ffffff; ">4.&nbsp;业务逻辑中需要用到的一些全局变量，比如一些消息中间件的消息队列通常有个offset，这个offset存放在zk上，这样集群中每个发送者都能知道当前的发送进度。</span></p><p style="margin-bottom:13.5000pt; margin-top:0pt; text-autospace:ideograph-other; text-align:left; line-height:13.5000pt; background:#ffffff; "><span style="mso-spacerun:'yes'; color:#333333; font-size:9.5000pt; font-family:'Tahoma'; background:#ffffff; ">5.&nbsp;系统中有些信息需要动态获取，并且还会存在人工手动去修改这个信息。以前通常是暴露出接口，例如JMX接口，有了zk后，只要将这些信息存放到zk节点上即可。</span></p></td></tr><tr><td width="57" valign="top" style="width:42.8500pt; padding:2.2500pt 7.5000pt 2.2500pt 7.5000pt ; border-left:0.7500pt solid #cccccc; border-right:0.7500pt solid #cccccc; border-top:none; ; border-bottom:0.7500pt solid #cccccc; background:#ffffff; "><p style="margin-bottom:0pt; margin-top:0pt; text-autospace:ideograph-other; text-align:left; vertical-align:; background:#ffffff; "><span style="mso-spacerun:'yes'; color:#333333; font-weight:bold; font-size:9.5000pt; font-family:'Tahoma'; background:#ffffff; ">Name&nbsp;Service</span></p></td><td width="259" valign="top" style="width:194.7500pt; padding:2.2500pt 7.5000pt 2.2500pt 7.5000pt ; border-left:none; ; ; border-right:0.7500pt solid #cccccc; border-top:none; ; border-bottom:0.7500pt solid #cccccc; background:#ffffff; "><p style="margin-bottom:0pt; margin-top:0pt; text-autospace:ideograph-other; text-align:left; vertical-align:; background:#ffffff; "><span style="mso-spacerun:'yes'; color:#333333; font-size:9.5000pt; font-family:'Tahoma'; background:#ffffff; ">这个主要是作为分布式命名服务，通过调用zk的create&nbsp;node&nbsp;api，能够很容易创建一个全局唯一的path，这个path就可以作为一个名称。</span></p></td><td width="259" valign="top" style="width:194.7500pt; padding:2.2500pt 7.5000pt 2.2500pt 7.5000pt ; border-left:none; ; ; border-right:0.7500pt solid #cccccc; border-top:none; ; border-bottom:0.7500pt solid #cccccc; background:#ffffff; "><p style="margin-bottom:0pt; margin-top:0pt; text-autospace:ideograph-other; text-align:left; vertical-align:; background:#ffffff; ">&nbsp;</p></td></tr><tr><td width="57" valign="top" style="width:42.8500pt; padding:2.2500pt 7.5000pt 2.2500pt 7.5000pt ; border-left:0.7500pt solid #cccccc; border-right:0.7500pt solid #cccccc; border-top:none; ; border-bottom:0.7500pt solid #cccccc; background:#ffffff; "><p style="margin-bottom:0pt; margin-top:0pt; text-autospace:ideograph-other; text-align:left; vertical-align:; background:#ffffff; "><span style="mso-spacerun:'yes'; color:#333333; font-weight:bold; font-size:9.5000pt; font-family:'Tahoma'; background:#ffffff; ">分布通知/协调</span></p></td><td width="259" valign="top" style="width:194.7500pt; padding:2.2500pt 7.5000pt 2.2500pt 7.5000pt ; border-left:none; ; ; border-right:0.7500pt solid #cccccc; border-top:none; ; border-bottom:0.7500pt solid #cccccc; background:#ffffff; "><p style="margin-bottom:0pt; margin-top:0pt; text-autospace:ideograph-other; text-align:left; vertical-align:; background:#ffffff; "><span style="mso-spacerun:'yes'; color:#333333; font-size:9.5000pt; font-family:'Tahoma'; background:#ffffff; ">ZooKeeper中特有watcher注册与异步通知机制，能够很好的实现分布式环境下不同系统之间的通知与协调，实现对数据变更的实时处理。使用方法通常是不同系统都对ZK上同一个znode进行注册，监听znode的变化（包括znode本身内容及子节点的），其中一个系统update了znode，那么另一个系统能够收到通知，并作出相应处理。</span></p></td><td width="259" valign="top" style="width:194.7500pt; padding:2.2500pt 7.5000pt 2.2500pt 7.5000pt ; border-left:none; ; ; border-right:0.7500pt solid #cccccc; border-top:none; ; border-bottom:0.7500pt solid #cccccc; background:#ffffff; "><p style="margin-bottom:0pt; margin-top:0pt; text-autospace:ideograph-other; text-align:left; vertical-align:; background:#ffffff; "><span style="mso-spacerun:'yes'; color:#333333; font-size:9.5000pt; font-family:'Tahoma'; background:#ffffff; ">1.&nbsp;另一种心跳检测机制：检测系统和被检测系统之间并不直接关联起来，而是通过zk上某个节点关联，大大减少系统耦合。2.&nbsp;另一种系统调度模式：某系统有控制台和推送系统两部分组成，控制台的职责是控制推送系统进行相应的推送工作。管理人员在控制台作的一些操作，实际上是修改了ZK上某些节点的状态，而zk就把这些变化通知给他们注册Watcher的客户端，即推送系统，于是，作出相应的推送任务。&nbsp;</span></p><p style="margin-bottom:13.5000pt; margin-top:0pt; text-autospace:ideograph-other; text-align:left; line-height:13.5000pt; background:#ffffff; "><span style="mso-spacerun:'yes'; color:#333333; font-size:9.5000pt; font-family:'Tahoma'; background:#ffffff; ">3.&nbsp;另一种工作汇报模式：一些类似于任务分发系统，子任务启动后，到zk来注册一个临时节点，并且定时将自己的进度进行汇报（将进度写回这个临时节点），这样任务管理者就能够实时知道任务进度。</span></p><p style="margin-bottom:13.5000pt; margin-top:0pt; text-autospace:ideograph-other; text-align:left; line-height:13.5000pt; background:#ffffff; "><span style="mso-spacerun:'yes'; color:#333333; font-size:9.5000pt; font-family:'Tahoma'; background:#ffffff; ">总之，使用zookeeper来进行分布式通知和协调能够大大降低系统之间的耦合。</span></p></td></tr><tr><td width="57" valign="top" style="width:42.8500pt; padding:2.2500pt 7.5000pt 2.2500pt 7.5000pt ; border-left:0.7500pt solid #cccccc; border-right:0.7500pt solid #cccccc; border-top:none; ; border-bottom:0.7500pt solid #cccccc; background:#ffffff; "><p style="margin-bottom:0pt; margin-top:0pt; text-autospace:ideograph-other; text-align:left; vertical-align:; background:#ffffff; "><span style="mso-spacerun:'yes'; color:#333333; font-weight:bold; font-size:9.5000pt; font-family:'Tahoma'; background:#ffffff; ">分布式锁</span></p></td><td width="259" valign="top" style="width:194.7500pt; padding:2.2500pt 7.5000pt 2.2500pt 7.5000pt ; border-left:none; ; ; border-right:0.7500pt solid #cccccc; border-top:none; ; border-bottom:0.7500pt solid #cccccc; background:#ffffff; "><p style="margin-bottom:0pt; margin-top:0pt; text-autospace:ideograph-other; text-align:left; vertical-align:; background:#ffffff; "><span style="mso-spacerun:'yes'; color:#333333; font-size:9.5000pt; font-family:'Tahoma'; background:#ffffff; ">分布式锁，这个主要得益于ZooKeeper为我们保证了数据的强一致性，即用户只要完全相信每时每刻，zk集群中任意节点（一个zk&nbsp;server）上的相同znode的数据是一定是相同的。锁服务可以分为两类，</span><span style="mso-spacerun:'yes'; color:#333333; font-weight:bold; font-size:9.5000pt; font-family:'Tahoma'; background:#ffffff; ">一个是保持独占，另一个是控制时序。</span>&nbsp;</p><p style="margin-bottom:13.5000pt; margin-top:0pt; text-autospace:ideograph-other; text-align:left; line-height:13.5000pt; background:#ffffff; "><span style="mso-spacerun:'yes'; color:#333333; font-size:9.5000pt; font-family:'Tahoma'; background:#ffffff; ">所谓保持独占，就是所有试图来获取这个锁的客户端，最终只有一个可以成功获得这把锁。通常的做法是把zk上的一个znode看作是一把锁，通过create&nbsp;znode的方式来实现。所有客户端都去创建&nbsp;/distribute_lock&nbsp;节点，最终成功创建的那个客户端也即拥有了这把锁。</span></p><p style="margin-bottom:13.5000pt; margin-top:0pt; text-autospace:ideograph-other; text-align:left; line-height:13.5000pt; background:#ffffff; "><span style="mso-spacerun:'yes'; color:#333333; font-size:9.5000pt; font-family:'Tahoma'; background:#ffffff; ">控制时序，就是所有视图来获取这个锁的客户端，最终都是会被安排执行，只是有个全局时序了。做法和上面基本类似，只是这里&nbsp;/distribute_lock&nbsp;已经预先存在，客户端在它下面创建临时有序节点（这个可以通过节点的属性控制：CreateMode.EPHEMERAL_SEQUENTIAL来指定）。Zk的父节点（/distribute_lock）维持一份sequence,保证子节点创建的时序性，从而也形成了每个客户端的全局时序。</span></p></td><td width="259" valign="top" style="width:194.7500pt; padding:2.2500pt 7.5000pt 2.2500pt 7.5000pt ; border-left:none; ; ; border-right:0.7500pt solid #cccccc; border-top:none; ; border-bottom:0.7500pt solid #cccccc; background:#ffffff; "><p style="margin-bottom:0pt; margin-top:0pt; text-autospace:ideograph-other; text-align:left; vertical-align:; background:#ffffff; ">&nbsp;</p></td></tr><tr><td width="57" valign="top" style="width:42.8500pt; padding:2.2500pt 7.5000pt 2.2500pt 7.5000pt ; border-left:0.7500pt solid #cccccc; border-right:0.7500pt solid #cccccc; border-top:none; ; border-bottom:0.7500pt solid #cccccc; background:#ffffff; "><p style="margin-bottom:0pt; margin-top:0pt; text-autospace:ideograph-other; text-align:left; vertical-align:; background:#ffffff; "><span style="mso-spacerun:'yes'; color:#333333; font-weight:bold; font-size:9.5000pt; font-family:'Tahoma'; background:#ffffff; ">集群管理</span></p></td><td width="259" valign="top" style="width:194.7500pt; padding:2.2500pt 7.5000pt 2.2500pt 7.5000pt ; border-left:none; ; ; border-right:0.7500pt solid #cccccc; border-top:none; ; border-bottom:0.7500pt solid #cccccc; background:#ffffff; "><p style="margin-bottom:0pt; margin-top:0pt; text-autospace:ideograph-other; text-align:left; vertical-align:; background:#ffffff; "><span style="mso-spacerun:'yes'; color:#333333; font-size:9.5000pt; font-family:'Tahoma'; background:#ffffff; ">1.&nbsp;</span><span style="mso-spacerun:'yes'; color:#333333; font-weight:bold; font-size:9.5000pt; font-family:'Tahoma'; background:#ffffff; ">集群机器</span><span style="mso-spacerun:'yes'; color:#333333; font-size:9.5000pt; font-family:'Tahoma'; background:#ffffff; ">监控：这通常用于那种对集群中机器状态，机器在线率有较高要求的场景，能够快速对集群中机器变化作出响应。这样的场景中，往往有一个监控系统，实时检测集群机器是否存活。过去的做法通常是：监控系统通过某种手段（比如ping）定时检测每个机器，或者每个机器自己定时向监控系统汇报&#8220;我还活着&#8221;。&nbsp;这种做法可行，但是存在两个比较明显的问题：1.&nbsp;集群中机器有变动的时候，牵连修改的东西比较多。2.&nbsp;有一定的延时。&nbsp;</span></p><p style="margin-bottom:13.5000pt; margin-top:0pt; text-autospace:ideograph-other; text-align:left; line-height:13.5000pt; background:#ffffff; "><span style="mso-spacerun:'yes'; color:#333333; font-size:9.5000pt; font-family:'Tahoma'; background:#ffffff; ">利用ZooKeeper有两个特性，就可以实时另一种集群机器存活性监控系统：a.&nbsp;客户端在节点&nbsp;x&nbsp;上注册一个Watcher，那么如果&nbsp;x&nbsp;的子节点变化了，会通知该客户端。b.&nbsp;创建EPHEMERAL类型的节点，一旦客户端和服务器的会话结束或过期，那么该节点就会消失。</span></p><p style="margin-bottom:13.5000pt; margin-top:0pt; text-autospace:ideograph-other; text-align:left; line-height:13.5000pt; background:#ffffff; "><span style="mso-spacerun:'yes'; color:#333333; font-size:9.5000pt; font-family:'Tahoma'; background:#ffffff; ">例如，监控系统在&nbsp;/clusterServers&nbsp;节点上注册一个Watcher，以后每动态加机器，那么就往&nbsp;/clusterServers&nbsp;下创建一个&nbsp;EPHEMERAL类型的节点：/clusterServers/{hostname}.&nbsp;这样，监控系统就能够实时知道机器的增减情况，至于后续处理就是监控系统的业务了。</span><span style="color:#333333; font-size:9.5000pt; font-family:'Tahoma'; background:#ffffff; "><br /></span><span style="mso-spacerun:'yes'; color:#333333; font-size:9.5000pt; font-family:'Tahoma'; background:#ffffff; ">2.&nbsp;</span><span style="mso-spacerun:'yes'; color:#333333; font-weight:bold; font-size:9.5000pt; font-family:'Tahoma'; background:#ffffff; ">Master选举则是zookeeper中最为经典的使用场景了。</span></p><p style="margin-bottom:13.5000pt; margin-top:0pt; text-autospace:ideograph-other; text-align:left; line-height:13.5000pt; background:#ffffff; "><span style="mso-spacerun:'yes'; color:#333333; font-size:9.5000pt; font-family:'Tahoma'; background:#ffffff; ">在分布式环境中，相同的业务应用分布在不同的机器上，有些业务逻辑（例如一些耗时的计算，网络I/O处理），往往只需要让整个集群中的某一台机器进行执行，其余机器可以共享这个结果，这样可以大大减少重复劳动，提高性能，于是这个master选举便是这种场景下的碰到的主要问题。</span></p><p style="margin-bottom:13.5000pt; margin-top:0pt; text-autospace:ideograph-other; text-align:left; line-height:13.5000pt; background:#ffffff; "><span style="mso-spacerun:'yes'; color:#333333; font-size:9.5000pt; font-family:'Tahoma'; background:#ffffff; ">利用ZooKeeper的强一致性，能够保证在分布式高并发情况下节点创建的全局唯一性，即：同时有多个客户端请求创建&nbsp;/currentMaster&nbsp;节点，最终一定只有一个客户端请求能够创建成功。</span></p><p style="margin-bottom:13.5000pt; margin-top:0pt; text-autospace:ideograph-other; text-align:left; line-height:13.5000pt; background:#ffffff; "><span style="mso-spacerun:'yes'; color:#333333; font-size:9.5000pt; font-family:'Tahoma'; background:#ffffff; ">利用这个特性，就能很轻易的在分布式环境中进行集群选取了。</span></p><p style="margin-bottom:13.5000pt; margin-top:0pt; text-autospace:ideograph-other; text-align:left; line-height:13.5000pt; background:#ffffff; "><span style="mso-spacerun:'yes'; color:#333333; font-size:9.5000pt; font-family:'Tahoma'; background:#ffffff; ">另外，这种场景演化一下，就是动态Master选举。这就要用到&nbsp;EPHEMERAL_SEQUENTIAL类型节点的特性了。</span></p><p style="margin-bottom:13.5000pt; margin-top:0pt; text-autospace:ideograph-other; text-align:left; line-height:13.5000pt; background:#ffffff; "><span style="mso-spacerun:'yes'; color:#333333; font-size:9.5000pt; font-family:'Tahoma'; background:#ffffff; ">上文中提到，所有客户端创建请求，最终只有一个能够创建成功。在这里稍微变化下，就是允许所有请求都能够创建成功，但是得有个创建顺序，于是所有的请求最终在ZK上创建结果的一种可能情况是这样：&nbsp;/currentMaster/{sessionId}-1&nbsp;,&nbsp;/currentMaster/{sessionId}-2&nbsp;,&nbsp;/currentMaster/{sessionId}-3&nbsp;&#8230;..&nbsp;每次选取序列号最小的那个机器作为Master，如果这个机器挂了，由于他创建的节点会马上小时，那么之后最小的那个机器就是Master了。</span></p></td><td width="259" valign="top" style="width:194.7500pt; padding:2.2500pt 7.5000pt 2.2500pt 7.5000pt ; border-left:none; ; ; border-right:0.7500pt solid #cccccc; border-top:none; ; border-bottom:0.7500pt solid #cccccc; background:#ffffff; "><p style="margin-bottom:0pt; margin-top:0pt; text-autospace:ideograph-other; text-align:left; vertical-align:; background:#ffffff; "><span style="mso-spacerun:'yes'; color:#333333; font-size:9.5000pt; font-family:'Tahoma'; background:#ffffff; ">1.&nbsp;在搜索系统中，如果集群中每个机器都生成一份全量索引，不仅耗时，而且不能保证彼此之间索引数据一致。因此让集群中的Master来进行全量索引的生成，然后同步到集群中其它机器。2.&nbsp;另外，Master选举的容灾措施是，可以随时进行手动指定master，就是说应用在zk在无法获取master信息时，可以通过比如http方式，向一个地方获取master。</span></p></td></tr><tr><td width="57" valign="top" style="width:42.8500pt; padding:2.2500pt 7.5000pt 2.2500pt 7.5000pt ; border-left:0.7500pt solid #cccccc; border-right:0.7500pt solid #cccccc; border-top:none; ; border-bottom:0.7500pt solid #cccccc; background:#ffffff; "><p style="margin-bottom:0pt; margin-top:0pt; text-autospace:ideograph-other; text-align:left; vertical-align:; background:#ffffff; "><span style="mso-spacerun:'yes'; color:#333333; font-weight:bold; font-size:9.5000pt; font-family:'Tahoma'; background:#ffffff; ">分布式队列</span></p></td><td width="259" valign="top" style="width:194.7500pt; padding:2.2500pt 7.5000pt 2.2500pt 7.5000pt ; border-left:none; ; ; border-right:0.7500pt solid #cccccc; border-top:none; ; border-bottom:0.7500pt solid #cccccc; background:#ffffff; "><p style="margin-bottom:0pt; margin-top:0pt; text-autospace:ideograph-other; text-align:left; vertical-align:; background:#ffffff; "><span style="mso-spacerun:'yes'; color:#333333; font-size:9.5000pt; font-family:'Tahoma'; background:#ffffff; ">队列方面，我目前感觉有两种，</span><span style="mso-spacerun:'yes'; color:#333333; font-weight:bold; font-size:9.5000pt; font-family:'Tahoma'; background:#ffffff; ">一种是常规的先进先出队列，另一种是要等到队列成员聚齐之后的才统一按序执行</span><span style="mso-spacerun:'yes'; color:#333333; font-size:9.5000pt; font-family:'Tahoma'; background:#ffffff; ">。对于第二种先进先出队列，和分布式锁服务中的控制时序场景基本原理一致，这里不再赘述。&nbsp;</span></p><p style="margin-bottom:13.5000pt; margin-top:0pt; text-autospace:ideograph-other; text-align:left; line-height:13.5000pt; background:#ffffff; "><span style="mso-spacerun:'yes'; color:#333333; font-size:9.5000pt; font-family:'Tahoma'; background:#ffffff; ">第二种队列其实是在FIFO队列的基础上作了一个增强。通常可以在&nbsp;/queue&nbsp;这个znode下预先建立一个/queue/num&nbsp;节点，并且赋值为n（或者直接给/queue赋值n），表示队列大小，之后每次有队列成员加入后，就判断下是否已经到达队列大小，决定是否可以开始执行了。这种用法的典型场景是，分布式环境中，一个大任务Task&nbsp;A，需要在很多子任务完成（或条件就绪）情况下才能进行。这个时候，凡是其中一个子任务完成（就绪），那么就去&nbsp;/taskList&nbsp;下建立自己的临时时序节点（CreateMode.EPHEMERAL_SEQUENTIAL），当&nbsp;/taskList&nbsp;发现自己下面的子节点满足指定个数，就可以进行下一步按序进行处理了。</span></p></td><td width="259" valign="top" style="width:194.7500pt; padding:2.2500pt 7.5000pt 2.2500pt 7.5000pt ; border-left:none; ; ; border-right:0.7500pt solid #cccccc; border-top:none; ; border-bottom:0.7500pt solid #cccccc; background:#ffffff; "><p style="margin-bottom:0pt; margin-top:0pt; text-autospace:ideograph-other; text-align:left; vertical-align:; background:#ffffff; ">&nbsp;</p></td></tr></tbody></table><p style="margin-bottom:0pt; margin-top:0pt; text-align:justify; "></p></div></div><img src ="http://www.blogjava.net/matuobasyouca/aggbug/378164.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/matuobasyouca/" target="_blank">一酌散千忧</a> 2012-05-15 11:02 <a href="http://www.blogjava.net/matuobasyouca/archive/2012/05/15/378164.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Hadoop in action 实践(伪分布式)</title><link>http://www.blogjava.net/matuobasyouca/archive/2012/04/01/373194.html</link><dc:creator>一酌散千忧</dc:creator><author>一酌散千忧</author><pubDate>Sun, 01 Apr 2012 07:00:00 GMT</pubDate><guid>http://www.blogjava.net/matuobasyouca/archive/2012/04/01/373194.html</guid><wfw:comment>http://www.blogjava.net/matuobasyouca/comments/373194.html</wfw:comment><comments>http://www.blogjava.net/matuobasyouca/archive/2012/04/01/373194.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/matuobasyouca/comments/commentRss/373194.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/matuobasyouca/services/trackbacks/373194.html</trackback:ping><description><![CDATA[<div>《Hadoop in action》<span style="font-family: 宋体; ">由</span>Manning<span style="font-family: 宋体; ">出版，磕磕绊绊总算是看完了。书的内容就不做介绍，主要讲一下实践的过程。并且在实践过程中参考的书籍的部分也会简单介绍。<br /><br /></span><span style="font-family: 宋体; color: red; ">灰色背景部分为一些介绍，或过程中出现问题的描述，可以直接忽略。</span><span style="font-family: 宋体; "><br /><br /></span></div><p><span style="font-family: 宋体; ">由于公司的业务需要，要在网络收集网页之后对网页进行结构化的解析，这个结构化过程希望能够基于</span>HDFS<span style="font-family: 宋体; ">并且使用</span>MR<span style="font-family: 宋体; ">算法实现。</span></p><p><span style="font-family: 宋体; ">我虚拟了一个需求，针对</span><a href="http://hadoop.apache.org/common/releases.html">http://hadoop.apache.org/common/releases.html</a>&nbsp;<span style="font-family: 宋体; ">页面，假设已经下载了页面并入库。要求最终体现的数据是</span>&nbsp;<span style="font-family: 宋体; ">&#8220;版本号</span>+<span style="font-family: 宋体; ">完整链接（即</span>a<span style="font-family: 宋体; ">标签全部内容）&#8221;</span>&nbsp;<span style="font-family: 宋体; ">的结构。</span></p><p>&nbsp;</p><p><span style="font-family: 宋体; ">伪分布式环境搭建在虚拟机上，操作系统是</span>centos5.5<span style="font-family: 宋体; ">，</span>hadoop<span style="font-family: 宋体; ">的版本是</span>1.0.0.</p><p>&nbsp;</p><blockquote style="margin: 0 0 0 40px; border: none; padding: 0px;"><blockquote style="margin: 0 0 0 40px; border: none; padding: 0px;"><p><span style="font-family: 宋体; background-color: #c0c0c0; ">插入书中的一些环境搭建的介绍</span></p></blockquote><blockquote style="margin: 0 0 0 40px; border: none; padding: 0px;"><p><span style="font-family: 宋体; background-color: #c0c0c0; ">书中的</span><span style="background-color: #c0c0c0; ">2.1</span><span style="font-family: 宋体; background-color: #c0c0c0; ">节中介绍了每个进程的作用。</span><span style="background-color: #c0c0c0; ">2.2</span><span style="font-family: 宋体; background-color: #c0c0c0; ">节中的</span><span style="background-color: #c0c0c0; ">ssh</span><span style="font-family: 宋体; background-color: #c0c0c0; ">设置也比较重要，否则好像会一直提示你输入密码。</span><span style="background-color: #c0c0c0; ">2.3.2</span><span style="font-family: 宋体; background-color: #c0c0c0; ">节介绍了伪分布式的配置方式，对</span><span style="background-color: #c0c0c0; ">core-site.xml</span><span style="font-family: 宋体; background-color: #c0c0c0; ">，</span><span style="background-color: #c0c0c0; ">mapred-site.xml</span><span style="font-family: 宋体; background-color: #c0c0c0; ">，</span><span style="background-color: #c0c0c0; ">hdfs-site.xml</span><span style="font-family: 宋体; background-color: #c0c0c0; ">进行配置之后，需要对</span><span style="background-color: #c0c0c0; ">namenode</span><span style="font-family: 宋体; background-color: #c0c0c0; ">节点进行格式化。</span></p></blockquote><blockquote style="margin: 0 0 0 40px; border: none; padding: 0px;"><p><span style="background-color: #c0c0c0; ">bin/hadoop namenode &#8211;format</span></p></blockquote></blockquote><p>&nbsp;</p><p>hadoop<span style="font-family: 宋体; ">的根目录为</span>/usr/local/hadoop-1.0.0<span style="font-family: 宋体; ">，直接启动</span>start-all.sh</p><p>&nbsp;</p><p>[root@localhost hadoop-1.0.0]# ./bin/start-all.sh</p><p>&nbsp;</p><p><span style="font-family: 宋体; ">启动成功后使用</span>jps<span style="font-family: 宋体; ">命令<br /></span></p><blockquote style="margin: 0 0 0 40px; border: none; padding: 0px;"><blockquote style="margin: 0 0 0 40px; border: none; padding: 0px;"><p><span style="background-color: #c0c0c0; ">jdk</span><span style="font-family: 宋体; background-color: #c0c0c0; ">小工具</span><span style="background-color: #c0c0c0; ">jps</span><span style="font-family: 宋体; background-color: #c0c0c0; ">介绍</span>&nbsp;</p></blockquote><blockquote style="margin: 0 0 0 40px; border: none; padding: 0px;"><p><span style="background-color: #c0c0c0; ">jps(Java Virtual Machine Process Status Tool)</span><span style="font-family: 宋体; background-color: #c0c0c0; ">是</span><span style="background-color: #c0c0c0; ">JDK 1.5</span><span style="font-family: 宋体; background-color: #c0c0c0; ">提供的一个显示当前所有</span><span style="background-color: #c0c0c0; ">java</span><span style="font-family: 宋体; background-color: #c0c0c0; ">进程</span><span style="background-color: #c0c0c0; ">pid</span><span style="font-family: 宋体; background-color: #c0c0c0; ">的命令，简单实用，非常适合在</span><span style="background-color: #c0c0c0; ">linux/unix</span><span style="font-family: 宋体; background-color: #c0c0c0; ">平台上简单察看当前</span><span style="background-color: #c0c0c0; ">java</span><span style="font-family: 宋体; background-color: #c0c0c0; ">进程的一些简单情况。</span><span style="background-color: #c0c0c0; ">&nbsp;jps</span><span style="font-family: 宋体; background-color: #c0c0c0; ">存放在</span><span style="background-color: #c0c0c0; ">JAVA_HOME/bin/jps</span></p></blockquote></blockquote><p>&nbsp;</p><p>[root@localhost hadoop-1.0.0]# jps</p><p>5694 SecondaryNameNode</p><p>5461 NameNode</p><p>5578 DataNode</p><p>6027 Jps</p><p>5784 JobTracker</p><p>5905 TaskTracker</p><p><span style="font-family: 宋体; ">这几个进程是非常重要的。很多时候出现意外就是因为某项服务未启动或异常。可以看到上面的命令上打印出日志位置。出现异常后可以在日志中查看详细的堆栈信息。</span></p><p>&nbsp;</p><p><span style="font-family: 宋体; ">至此，</span>hadoop<span style="font-family: 宋体; ">已经启动，环境已经准备就绪。</span></p><p>&nbsp;</p><p><span style="font-family: 宋体; ">下面准备我们的测试数据，将目标页面的</span>html<span style="font-family: 宋体; ">保存为</span>news.txt<span style="font-family: 宋体; ">，伪分布式也同样支持</span>hdfs<span style="font-family: 宋体; ">，所以我们使用</span>&nbsp;fs &#8211;put&nbsp;<span style="font-family: 宋体; ">将</span>news.txt<span style="font-family: 宋体; ">存入</span>hdfs<span style="font-family: 宋体; ">中。</span></p><p>[root@localhost hadoop-1.0.0]# ./bin/hadoop fs -put /mnt/hgfs/shared/news.txt /user/root</p><p>[root@localhost hadoop-1.0.0]# ./bin/hadoop fs -lsr /userdrwxr-xr-x&nbsp; &nbsp;- root supergroup&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 0 2012-04-01 11:22 /user/root</p><p>-rw-r--r--&nbsp;&nbsp; 1 root supergroup&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 3935 2012-04-01 11:22 /user/root/news.txt</p><p>&nbsp;</p><p><span style="font-family: 宋体; ">实现的代码在</span>eclipse<span style="font-family: 宋体; ">中使用</span>maven<span style="font-family: 宋体; ">打包，上传至虚拟机。</span></p><p><span style="font-family: 宋体; ">文件名</span>com.suntang.analyse.hadoop-0.0.1.jar<span style="font-family: 宋体; ">。<br />使用hadoop的中的jar命令调用该jar文件。<br /></span></p><p><br class="Apple-interchange-newline" />[root@localhost hadoop-1.0.0]# ./bin/hadoop jar com.suntang.analyse.hadoop-0.0.1.jar com.suntang.analyse.hadoop.AnalyseJob /user/root/news.txt output_root_test</p><p>12/04/01 14:40:04 INFO input.FileInputFormat: Total input paths to process : 1</p><p>12/04/01 14:40:05 INFO mapred.JobClient: Running job: job_201204011420_0001</p><p>12/04/01 14:40:06 INFO mapred.JobClient:&nbsp; map 0% reduce 0%</p><p>12/04/01 14:40:19 INFO mapred.JobClient:&nbsp; map 100% reduce 0%</p><p>12/04/01 14:40:31 INFO mapred.JobClient:&nbsp; map 100% reduce 100%</p><p>12/04/01 14:40:37 INFO mapred.JobClient: Job complete: job_201204011420_0001</p><p>&#8230;</p><p>&nbsp;</p><p>&nbsp;</p><blockquote style="margin: 0 0 0 40px; border: none; padding: 0px;"><blockquote style="margin: 0 0 0 40px; border: none; padding: 0px;"><p><span style="font-family: 宋体; background-color: #c0c0c0; ">此处注意我犯的一个错误：</span></p></blockquote><blockquote style="margin: 0 0 0 40px; border: none; padding: 0px;"><p><span style="background-color: #c0c0c0; ">[root@localhost hadoop-1.0.0]# ./bin/hadoop jar com.suntang.analyse.hadoop-0.0.1.jar AnalyseJob -libjars hadoop-core-1.0.0.jar /user/root/news.txt output_root_test</span></p></blockquote><blockquote style="margin: 0 0 0 40px; border: none; padding: 0px;"><p><span style="background-color: #c0c0c0; ">Exception in thread "main" java.lang.ClassNotFoundException: AnalyseJob</span></p></blockquote><blockquote style="margin: 0 0 0 40px; border: none; padding: 0px;"><p><span style="font-family: 宋体; background-color: #c0c0c0; ">提示找不到类，因为我忘了写完整类名，命令应该改为</span></p><span style="background-color: #c0c0c0; ">./bin/hadoop jar com.suntang.analyse.hadoop-0.0.1.jar com.suntang.analyse.hadoop.AnalyseJob -libjars hadoop-core-1.0.0.jar /user/root/news.txt output_root_test&nbsp;</span><span style="font-family: 宋体; background-color: #c0c0c0; ">即可。</span></blockquote><blockquote style="margin: 0 0 0 40px; border: none; padding: 0px;"><p>&nbsp;</p></blockquote><blockquote style="margin: 0 0 0 40px; border: none; padding: 0px;"><p><span style="font-family: 宋体; background-color: #c0c0c0; ">此处运行可能出现另外一个错误。在命令行中出现</span></p></blockquote><blockquote style="margin: 0 0 0 40px; border: none; padding: 0px;"><p><span style="background-color: #c0c0c0; ">12/04/01 14:01:38 INFO mapred.JobClient: Task Id : attempt_201204011356_0001_m_000001_0, Status : FAILED</span></p></blockquote><blockquote style="margin: 0 0 0 40px; border: none; padding: 0px;"><p><span style="background-color: #c0c0c0; ">java.lang.Throwable: Child Error</span></p></blockquote><blockquote style="margin: 0 0 0 40px; border: none; padding: 0px;"><p><span style="background-color: #c0c0c0; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; at org.apache.hadoop.mapred.TaskRunner.run(TaskRunner.java:271)</span></p></blockquote><blockquote style="margin: 0 0 0 40px; border: none; padding: 0px;"><p><span style="background-color: #c0c0c0; ">Caused by: java.io.IOException: Creation of symlink from /mnt/hgfs/shared/hadoop-1.0.0/libexec/../logs/userlogs/job_201204011356_0001/attempt_201204011356_0001_m_000001_0 to&nbsp;</span><span style="font-family: 宋体; background-color: #c0c0c0; ">。。。</span></p></blockquote><blockquote style="margin: 0 0 0 40px; border: none; padding: 0px;"><p><span style="font-family: 宋体; background-color: #c0c0c0; ">就不打全了，重点在与</span></p><span style="background-color: #c0c0c0; ">Creation of symlink</span><span style="font-family: 宋体; background-color: #c0c0c0; ">，看详细日志中</span><span style="background-color: #c0c0c0; ">hadoop-root-tasktracker-localhost.localdomain.log</span><span style="font-family: 宋体; background-color: #c0c0c0; ">中提示</span><span style="background-color: #c0c0c0; ">org.apache.hadoop.fs.FileUtil: Command 'ln -s ....': Operation not supported</span><span style="font-family: 宋体; background-color: #c0c0c0; ">，即</span><span style="background-color: #c0c0c0; ">ln</span><span style="font-family: 宋体; background-color: #c0c0c0; ">操作不支持。</span><span style="background-color: #c0c0c0; ">google</span><span style="font-family: 宋体; background-color: #c0c0c0; ">可知这个是由于</span><span style="background-color: #c0c0c0; ">vm</span><span style="font-family: 宋体; background-color: #c0c0c0; ">中的共享区域的问题，解决方法就是将</span><span style="background-color: #c0c0c0; ">hadoop</span><span style="font-family: 宋体; background-color: #c0c0c0; ">完全转移至</span><span style="background-color: #c0c0c0; ">linux</span><span style="font-family: 宋体; background-color: #c0c0c0; ">目录中。本例中从</span><span style="background-color: #c0c0c0; ">/mnt/hgfs/shared/hadoop-1.0.0</span><span style="font-family: 宋体; background-color: #c0c0c0; ">转移至</span><span style="background-color: #c0c0c0; ">/usr/local/hadoop-1.0.0</span><span style="font-family: 宋体; background-color: #c0c0c0; ">。</span></blockquote></blockquote><p>&nbsp;</p><p><span style="font-family: 宋体; ">执行完成后可在</span>hdfs<span style="font-family: 宋体; ">中查看结果，查看目录结构为</span></p><p>-rw-r--r--&nbsp;&nbsp; 1 root supergroup&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 0 2012-04-01 14:40 /user/root/output_root_test/_SUCCESS</p><p>drwxr-xr-x&nbsp;&nbsp; - root supergroup&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 0 2012-04-01 14:40 /user/root/output_root_test/_logs</p><p>drwxr-xr-x&nbsp;&nbsp; - root supergroup&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 0 2012-04-01 14:40 /user/root/output_root_test/_logs/history</p><p>-rw-r--r--&nbsp;&nbsp; 1 root supergroup&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 13634 2012-04-01 14:40 /user/root/output_root_test/_logs/history/job_201204011420_0001_1333262405103_root_ccAnalyseJob</p><p>-rw-r--r--&nbsp;&nbsp; 1 root supergroup&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 20478 2012-04-01 14:40 /user/root/output_root_test/_logs/history/job_201204011420_0001_conf.xml</p><p>-rw-r--r--&nbsp;&nbsp; 1 root supergroup&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 3580 2012-04-01 14:40 /user/root/output_root_test/part-r-00000</p><p>&nbsp;</p><p>/user/root/output_root_test/part-r-00000<span style="font-family: 宋体; ">即为最终结果文件。</span></p><p>&nbsp;</p><p>&nbsp;=======================================================================</p><p><span style="font-family: 宋体; ">附加</span>AnalyseJob<span style="font-family: 宋体; ">代码</span></p><p>package com.suntang.analyse.hadoop;</p><p>&nbsp;</p><p>import java.io.IOException;</p><p>&nbsp;</p><p>import org.apache.hadoop.conf.Configuration;</p><p>import org.apache.hadoop.conf.Configured;</p><p>import org.apache.hadoop.fs.Path;</p><p>import org.apache.hadoop.io.LongWritable;</p><p>import org.apache.hadoop.io.Text;</p><p>import org.apache.hadoop.mapreduce.Job;</p><p>import org.apache.hadoop.mapreduce.Mapper;</p><p>import org.apache.hadoop.mapreduce.Reducer;</p><p>import org.apache.hadoop.mapreduce.lib.input.FileInputFormat;</p><p>import org.apache.hadoop.mapreduce.lib.input.TextInputFormat;</p><p>import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat;</p><p>import org.apache.hadoop.mapreduce.lib.output.TextOutputFormat;</p><p>import org.apache.hadoop.util.Tool;</p><p>import org.apache.hadoop.util.ToolRunner;</p><p>&nbsp;</p><p>public class AnalyseJob extends Configured implements Tool {</p><p>&nbsp;</p><p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public static class MapClass extends Mapper&lt;LongWritable, Text, Text, Text&gt; {</p><p>&nbsp;</p><p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; @Override</p><p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; protected void map(LongWritable key, Text value, Context context)</p><p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; throws IOException, InterruptedException {</p><p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</p><p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</p><p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // TODO Auto-generated method stub</p><p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // super.map(key, value, context);</p><p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (value.toString().matches("&lt;a[^&gt;]*&gt;.*?release.*?&lt;/a&gt;"))</p><p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; context.write(</p><p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; new Text(value.toString().substring(</p><p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; value.toString().indexOf("release") + 8,</p><p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; value.toString().indexOf("available") - 1)),</p><p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; value);</p><p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</p><p>&nbsp;</p><p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</p><p>&nbsp;</p><p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public static class ReduceClass extends Reducer&lt;Text, Text, Text, Text&gt; {</p><p>&nbsp;</p><p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; @Override</p><p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; protected void reduce(Text arg0, Iterable&lt;Text&gt; arg1, Context arg2)</p><p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; throws IOException, InterruptedException {</p><p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // TODO Auto-generated method stub</p><p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // super.reduce(arg0, arg1, arg2);</p><p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; arg2.write(arg0, arg1.iterator().next());</p><p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</p><p>&nbsp;</p><p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</p><p>&nbsp;</p><p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public int run(String[] args) throws Exception {</p><p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Configuration conf = getConf();</p><p>&nbsp;</p><p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Job job = new Job(conf, "myAnalyseJob");</p><p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; job.setJarByClass(getClass());</p><p>&nbsp;</p><p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Path in = new Path(args[0]);</p><p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Path out = new Path(args[1]);</p><p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; FileInputFormat.setInputPaths(job, in);</p><p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; FileOutputFormat.setOutputPath(job, out);</p><p>&nbsp;</p><p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; job.setMapperClass(MapClass.class);</p><p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; job.setReducerClass(ReduceClass.class);</p><p>&nbsp;</p><p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; job.setInputFormatClass(TextInputFormat.class);</p><p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; job.setOutputFormatClass(TextOutputFormat.class);</p><p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; job.setOutputKeyClass(Text.class);</p><p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; job.setOutputValueClass(Text.class);</p><p>&nbsp;</p><p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.exit(job.waitForCompletion(true) ? 0 : 1);</p><p>&nbsp;</p><p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return 0;</p><p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</p><p>&nbsp;</p><p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public static void main(String[] args) throws Exception {</p><p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int res = ToolRunner.run(new Configuration(), new AnalyseJob(), args);</p><p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.exit(res);</p><p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</p><p>}</p><img src ="http://www.blogjava.net/matuobasyouca/aggbug/373194.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/matuobasyouca/" target="_blank">一酌散千忧</a> 2012-04-01 15:00 <a href="http://www.blogjava.net/matuobasyouca/archive/2012/04/01/373194.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Hadoop: The Definitive Guide（Hadoop权威指南）Unix Tools 脚本编程实施</title><link>http://www.blogjava.net/matuobasyouca/archive/2012/03/29/372995.html</link><dc:creator>一酌散千忧</dc:creator><author>一酌散千忧</author><pubDate>Thu, 29 Mar 2012 08:21:00 GMT</pubDate><guid>http://www.blogjava.net/matuobasyouca/archive/2012/03/29/372995.html</guid><wfw:comment>http://www.blogjava.net/matuobasyouca/comments/372995.html</wfw:comment><comments>http://www.blogjava.net/matuobasyouca/archive/2012/03/29/372995.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/matuobasyouca/comments/commentRss/372995.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/matuobasyouca/services/trackbacks/372995.html</trackback:ping><description><![CDATA[<p>Example 2-2. A program for finding the maximum recorded temperature by year from NCDC weather records</p>  <p>#!/usr/bin/env bash</p>  <p>for year in all/*</p>  <p>do</p>  <p>&nbsp; echo -ne `basename $year .gz`"\t"</p>  <p>&nbsp; gunzip -c $year | \</p>  <p>&nbsp;&nbsp;&nbsp; awk '{ temp = substr($0, 88, 5) + 0;</p>  <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; q = substr($0, 93, 1);</p>  <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (temp !=9999 &amp;&amp; q ~ /[01459]/ &amp;&amp; temp &gt; max) max = temp }</p>  <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; END { print max }'</p>  <p>done</p>  <p>&nbsp;</p>  <p><span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">使用</span>linux<span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">脚本打印每年最高温度，先解释一下该脚本几个注意点。</span></p>  <p><span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">脚本目的是发现每年的最高温度，第一句</span>for year in <span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">后的</span>all/*<span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">表示在名称为</span>all<span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">的文件夹下每年度的温度信息都以</span> <span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">如</span> 1990.gz <span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">方式存在。使用</span>gunzip<span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">方式解压并打印，对打印的内容使用</span>awk<span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">函数进行处理，获取最大温度，单个文件处理完毕后打印</span>max<span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">。</span></p>  <p>&nbsp;</p>  <p><span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">在上一篇中获取的数据包是这样，年度为文件夹，当中包含若干个温度详情文件。</span></p>  <p>E:\testData\1990\010010-9999-1990.gz</p>  <p>E:\testData\1990\010014-9999-1990.gz</p>  <p>E:\testData\1990\010015-9999-1990.gz</p>  <p>E:\testData\1990\010016-9999-1990.gz</p>  <p>&#8230;</p>  <p>&nbsp;</p>  <p><span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">从后面</span>Appendix C<span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">的描述中得知，实际上作者对这样的数据进行了处理，因为</span>hadoop<span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">在处理大量的小文件时无法达到很高的效率，因此作者使用</span>hadoop<span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">将小文件合并，并且给出了代码。</span></p>  <p>&nbsp;</p>  <p><span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">我比较希望能够使用脚本处理，将所有的</span>gz<span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">解压之后，合并成为一个文件，打包成</span>gz<span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">的格式，这样就能完全符合之前那段脚本的处理方式。所以，脚本如下：</span></p>  <p>packyear</p>  <p>#! /bin/sh</p>  <p># /usr/data/packyear</p>  <p>&nbsp;</p>  <p># unzip all gz files in data</p>  <p>for yeards in data/*</p>  <p>do</p>  <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; # unzip all gz files in year directory</p>  <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for gzfile in $yeards/*</p>  <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; do</p>  <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; gunzip $gzfile</p>  <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; done</p>  <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </p>  <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; # cat all content to year file</p>  <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; cat $yeards/* | head -2 &gt;&gt; $yeards.tc</p>  <p>&nbsp;</p>  <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; # remove year directory</p>  <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; rm -rf $yeards</p>  <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mv $yeards.tc $yeards</p>  <p>&nbsp;</p>  <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; # zip the tc file</p>  <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; gzip $yeards</p>  <p>done</p>  <p>&nbsp;</p>  <p><span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">根据实际路径改写的计算最大温度的脚本</span></p>  <p>maxyear</p>  <p>#! /bin/sh</p>  <p># /usr/data/ maxyear</p>  <p>&nbsp;</p>  <p>for year in /usr/data/*</p>  <p>do</p>  <p>&nbsp; basename $year .gz</p>  <p>&nbsp; gunzip -c $year | \</p>  <p>&nbsp;&nbsp;&nbsp; awk '{temp=substr($0, 88, 5)+0;</p>  <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; q=substr($0, 93, 1);</p>  <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if(temp !=9999 &amp;&amp; q ~ /[01459]/ &amp;&amp; temp &gt; max) max = temp}</p>  <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; END {print max}'</p>  <p>done</p>  <p><span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">这个脚本最终显示出来会是：</span></p>  <p>1990</p>  <p>3</p>  <p><span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">这样的格式。由于对数据结构的不熟悉，所以不确定显示出来的数据是否正确，但是基本的脚本和数据操作方式就是这样了。</span></p><img src ="http://www.blogjava.net/matuobasyouca/aggbug/372995.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/matuobasyouca/" target="_blank">一酌散千忧</a> 2012-03-29 16:21 <a href="http://www.blogjava.net/matuobasyouca/archive/2012/03/29/372995.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Hadoop: The Definitive Guide（Hadoop权威指南）数据获取</title><link>http://www.blogjava.net/matuobasyouca/archive/2012/03/28/372877.html</link><dc:creator>一酌散千忧</dc:creator><author>一酌散千忧</author><pubDate>Wed, 28 Mar 2012 02:32:00 GMT</pubDate><guid>http://www.blogjava.net/matuobasyouca/archive/2012/03/28/372877.html</guid><wfw:comment>http://www.blogjava.net/matuobasyouca/comments/372877.html</wfw:comment><comments>http://www.blogjava.net/matuobasyouca/archive/2012/03/28/372877.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/matuobasyouca/comments/commentRss/372877.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/matuobasyouca/services/trackbacks/372877.html</trackback:ping><description><![CDATA[<p>Hadoop: The Definitive Guide<span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">（</span>Hadoop<span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">权威指南），第十六页中提到了测试数据来源来自于</span>National Climatic Data Center (NCDC, <a href="http://www.ncdc.noaa.gov/">http://www.ncdc.noaa.gov/</a>)<span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">。在下面使用</span>Unix Tool<span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">编写脚本时使用到的文件格式如下：</span></p>  <p>&nbsp;</p>  <p>For example, here are the first entries for 1990:</p>  <p>% ls raw/1990 | head</p>  <p>010010-99999-1990.gz</p>  <p>010014-99999-1990.gz</p>  <p>010015-99999-1990.gz</p>  <p>010016-99999-1990.gz</p>  <p>010017-99999-1990.gz</p>  <p>010030-99999-1990.gz</p>  <p>010040-99999-1990.gz</p>  <p>010080-99999-1990.gz</p>  <p>010100-99999-1990.gz</p>  <p>010150-99999-1990.gz</p>  <p>&nbsp;</p>  <p><span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">对于数据的来源很困惑，不知道如何下载。</span>google<span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">之后在</span><a href="http://lucene.472066.n3.nabble.com/The-NCDC-Weather-Data-for-Hadoop-the-Definitive-Guide-td3736774.html">http://lucene.472066.n3.nabble.com/The-NCDC-Weather-Data-for-Hadoop-the-Definitive-Guide-td3736774.html</a> <span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">这篇帖子中发现方法。现在记录一下</span></p>  <p><span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">连接</span>http://www.ncdc.noaa.gov/</p>  <p><span style="font-family: 宋体; "><img src="http://ww3.sinaimg.cn/large/6c4e0bdcgw1drfazh7mlxj.jpg" width="855" height="626" alt="" /><br />注意到左边的</span>Free Data<span style="font-family: 宋体; ">。</span></p>  <p><span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">点击后转到的页面向下拉，在</span>Free Data B<span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">中友一个完全免费的</span>FTP<span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">（红框所示）</span></p>  <p><img src="http://ww4.sinaimg.cn/large/6c4e0bdcgw1drfazmn63rj.jpg" alt="" /><br /></p>  <p>&nbsp;</p>  <p><span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">提供</span>ftp<span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">地址为：</span><a href="ftp://ftp3.ncdc.noaa.gov/pub/data/noaa/">ftp://ftp3.ncdc.noaa.gov/pub/data/noaa/</a></p>  <p><span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">我使用了</span>FileZilla<span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">（</span><a href="http://dl.pconline.com.cn/html_2/1/89/id=5826&amp;pn=0.html">http://dl.pconline.com.cn/html_2/1/89/id=5826&amp;pn=0.html</a><span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">）进行下载</span></p>  <p><img src="http://ww1.sinaimg.cn/large/6c4e0bdcgw1drfazr18yxj.jpg" alt="" /><br /></p>  <p><span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">共</span>1w<span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">多个文件，可能是不需要完全下载的。</span></p>  <p><span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">（完）</span></p><img src ="http://www.blogjava.net/matuobasyouca/aggbug/372877.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/matuobasyouca/" target="_blank">一酌散千忧</a> 2012-03-28 10:32 <a href="http://www.blogjava.net/matuobasyouca/archive/2012/03/28/372877.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>