敏捷、分布式、ALM过程自动化、企业应用架构
posts - 14, comments - 0, trackbacks - 0, articles - 1
  BlogJava :: 首页 :: 新随笔 :: 联系 :: 聚合  :: 管理

Hadoop in action 实践(伪分布式)

Posted on 2012-04-01 15:00 一酌散千忧 阅读(815) 评论(0)  编辑  收藏 所属分类: Hadoop
《Hadoop in action》Manning出版,磕磕绊绊总算是看完了。书的内容就不做介绍,主要讲一下实践的过程。并且在实践过程中参考的书籍的部分也会简单介绍。

灰色背景部分为一些介绍,或过程中出现问题的描述,可以直接忽略。

由于公司的业务需要,要在网络收集网页之后对网页进行结构化的解析,这个结构化过程希望能够基于HDFS并且使用MR算法实现。

我虚拟了一个需求,针对http://hadoop.apache.org/common/releases.html 页面,假设已经下载了页面并入库。要求最终体现的数据是 “版本号+完整链接(即a标签全部内容)” 的结构。

 

伪分布式环境搭建在虚拟机上,操作系统是centos5.5hadoop的版本是1.0.0.

 

插入书中的一些环境搭建的介绍

书中的2.1节中介绍了每个进程的作用。2.2节中的ssh设置也比较重要,否则好像会一直提示你输入密码。2.3.2节介绍了伪分布式的配置方式,对core-site.xmlmapred-site.xmlhdfs-site.xml进行配置之后,需要对namenode节点进行格式化。

bin/hadoop namenode –format

 

hadoop的根目录为/usr/local/hadoop-1.0.0,直接启动start-all.sh

 

[root@localhost hadoop-1.0.0]# ./bin/start-all.sh

 

启动成功后使用jps命令

jdk小工具jps介绍 

jps(Java Virtual Machine Process Status Tool)JDK 1.5提供的一个显示当前所有java进程pid的命令,简单实用,非常适合在linux/unix平台上简单察看当前java进程的一些简单情况。 jps存放在JAVA_HOME/bin/jps

 

[root@localhost hadoop-1.0.0]# jps

5694 SecondaryNameNode

5461 NameNode

5578 DataNode

6027 Jps

5784 JobTracker

5905 TaskTracker

这几个进程是非常重要的。很多时候出现意外就是因为某项服务未启动或异常。可以看到上面的命令上打印出日志位置。出现异常后可以在日志中查看详细的堆栈信息。

 

至此,hadoop已经启动,环境已经准备就绪。

 

下面准备我们的测试数据,将目标页面的html保存为news.txt,伪分布式也同样支持hdfs,所以我们使用 fs –put news.txt存入hdfs中。

[root@localhost hadoop-1.0.0]# ./bin/hadoop fs -put /mnt/hgfs/shared/news.txt /user/root

[root@localhost hadoop-1.0.0]# ./bin/hadoop fs -lsr /userdrwxr-xr-x   - root supergroup          0 2012-04-01 11:22 /user/root

-rw-r--r--   1 root supergroup       3935 2012-04-01 11:22 /user/root/news.txt

 

实现的代码在eclipse中使用maven打包,上传至虚拟机。

文件名com.suntang.analyse.hadoop-0.0.1.jar
使用hadoop的中的jar命令调用该jar文件。


[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

12/04/01 14:40:04 INFO input.FileInputFormat: Total input paths to process : 1

12/04/01 14:40:05 INFO mapred.JobClient: Running job: job_201204011420_0001

12/04/01 14:40:06 INFO mapred.JobClient:  map 0% reduce 0%

12/04/01 14:40:19 INFO mapred.JobClient:  map 100% reduce 0%

12/04/01 14:40:31 INFO mapred.JobClient:  map 100% reduce 100%

12/04/01 14:40:37 INFO mapred.JobClient: Job complete: job_201204011420_0001

 

 

此处注意我犯的一个错误:

[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

Exception in thread "main" java.lang.ClassNotFoundException: AnalyseJob

提示找不到类,因为我忘了写完整类名,命令应该改为

./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 即可。

 

此处运行可能出现另外一个错误。在命令行中出现

12/04/01 14:01:38 INFO mapred.JobClient: Task Id : attempt_201204011356_0001_m_000001_0, Status : FAILED

java.lang.Throwable: Child Error

        at org.apache.hadoop.mapred.TaskRunner.run(TaskRunner.java:271)

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 。。。

就不打全了,重点在与

Creation of symlink,看详细日志中hadoop-root-tasktracker-localhost.localdomain.log中提示org.apache.hadoop.fs.FileUtil: Command 'ln -s ....': Operation not supported,即ln操作不支持。google可知这个是由于vm中的共享区域的问题,解决方法就是将hadoop完全转移至linux目录中。本例中从/mnt/hgfs/shared/hadoop-1.0.0转移至/usr/local/hadoop-1.0.0

 

执行完成后可在hdfs中查看结果,查看目录结构为

-rw-r--r--   1 root supergroup          0 2012-04-01 14:40 /user/root/output_root_test/_SUCCESS

drwxr-xr-x   - root supergroup          0 2012-04-01 14:40 /user/root/output_root_test/_logs

drwxr-xr-x   - root supergroup          0 2012-04-01 14:40 /user/root/output_root_test/_logs/history

-rw-r--r--   1 root supergroup      13634 2012-04-01 14:40 /user/root/output_root_test/_logs/history/job_201204011420_0001_1333262405103_root_ccAnalyseJob

-rw-r--r--   1 root supergroup      20478 2012-04-01 14:40 /user/root/output_root_test/_logs/history/job_201204011420_0001_conf.xml

-rw-r--r--   1 root supergroup       3580 2012-04-01 14:40 /user/root/output_root_test/part-r-00000

 

/user/root/output_root_test/part-r-00000即为最终结果文件。

 

 =======================================================================

附加AnalyseJob代码

package com.suntang.analyse.hadoop;

 

import java.io.IOException;

 

import org.apache.hadoop.conf.Configuration;

import org.apache.hadoop.conf.Configured;

import org.apache.hadoop.fs.Path;

import org.apache.hadoop.io.LongWritable;

import org.apache.hadoop.io.Text;

import org.apache.hadoop.mapreduce.Job;

import org.apache.hadoop.mapreduce.Mapper;

import org.apache.hadoop.mapreduce.Reducer;

import org.apache.hadoop.mapreduce.lib.input.FileInputFormat;

import org.apache.hadoop.mapreduce.lib.input.TextInputFormat;

import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat;

import org.apache.hadoop.mapreduce.lib.output.TextOutputFormat;

import org.apache.hadoop.util.Tool;

import org.apache.hadoop.util.ToolRunner;

 

public class AnalyseJob extends Configured implements Tool {

 

       public static class MapClass extends Mapper<LongWritable, Text, Text, Text> {

 

              @Override

              protected void map(LongWritable key, Text value, Context context)

                            throws IOException, InterruptedException {

                    

                    

                     // TODO Auto-generated method stub

                     // super.map(key, value, context);

                     if (value.toString().matches("<a[^>]*>.*?release.*?</a>"))

                            context.write(

                                          new Text(value.toString().substring(

                                                        value.toString().indexOf("release") + 8,

                                                        value.toString().indexOf("available") - 1)),

                                          value);

              }

 

       }

 

       public static class ReduceClass extends Reducer<Text, Text, Text, Text> {

 

              @Override

              protected void reduce(Text arg0, Iterable<Text> arg1, Context arg2)

                            throws IOException, InterruptedException {

                     // TODO Auto-generated method stub

                     // super.reduce(arg0, arg1, arg2);

                     arg2.write(arg0, arg1.iterator().next());

              }

 

       }

 

       public int run(String[] args) throws Exception {

              Configuration conf = getConf();

 

              Job job = new Job(conf, "myAnalyseJob");

              job.setJarByClass(getClass());

 

              Path in = new Path(args[0]);

              Path out = new Path(args[1]);

              FileInputFormat.setInputPaths(job, in);

              FileOutputFormat.setOutputPath(job, out);

 

              job.setMapperClass(MapClass.class);

              job.setReducerClass(ReduceClass.class);

 

              job.setInputFormatClass(TextInputFormat.class);

              job.setOutputFormatClass(TextOutputFormat.class);

              job.setOutputKeyClass(Text.class);

              job.setOutputValueClass(Text.class);

 

              System.exit(job.waitForCompletion(true) ? 0 : 1);

 

              return 0;

       }

 

       public static void main(String[] args) throws Exception {

              int res = ToolRunner.run(new Configuration(), new AnalyseJob(), args);

              System.exit(res);

       }

}


只有注册用户登录后才能发表评论。


网站导航: