一步两步,学习大数据(四)——IDEA 搭建hadoop mapreduce程序

写在前面

可能大家都习惯用eclipse来写hadoop map/reduce程序,因为eclipse提供有连接集群的插件,可以很方便的帮助我们连接、简单操作集群中的文件,以及创建map/reduce程序。而用IDEA来搭建hadoop程序则稍显复杂,如果你是IDEA的忠实粉丝,又不知如何用IDEA搭建map/reduce程序,就可以参考小编今天的文章啦。

准备工作

工具:hadoop集群,小编选择的hadoop版本是hadoop2.7.4;虚拟机版本是centos7;jdk版本1.8以上;
IDEA2017.2.5;maven版本3.5,开发环境,window7

详细步骤

1.创建空maven项目

选择空模板
此步骤注意选择jdk版本,maven基本配置等。
继续下一步,配置groupid和artifactId,项目保存位置等不再细说。

2.pom文件中增加依赖

<dependencies>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
            <scope>test</scope>
        </dependency>

        <dependency>
            <groupId>org.apache.hadoop</groupId>
            <artifactId>hadoop-common</artifactId>
            <version>2.7.4</version>
        </dependency>
        <dependency>
            <groupId>org.apache.hadoop</groupId>
            <artifactId>hadoop-hdfs</artifactId>
            <version>2.7.4</version>
        </dependency>


        <dependency>
            <groupId>org.apache.hadoop</groupId>
            <artifactId>hadoop-mapreduce-client-core</artifactId>
            <version>2.7.4</version>
        </dependency>

        <dependency>
            <groupId>org.apache.hadoop</groupId>
            <artifactId>hadoop-mapreduce-client-jobclient</artifactId>
            <version>2.7.4</version>
        </dependency>

        <dependency>
            <groupId>log4j</groupId>
            <artifactId>log4j</artifactId>
            <version>1.2.17</version>
        </dependency>
    </dependencies>

hadoop相关jar包的版本尽量和自己集群中的hadoop版本一致。

3.hadoop配置文件

core-site.xml

<configuration>
    <property>
        <name>fs.defaultFS</name>
        <!--<value>hdfs://192.168.13.100:9000</value>-->
        <value>hdfs://master:9000</value>
    </property>
</configuration>

此处还要注意集群访问权限问题,修改hdfs-site.xml文件,增加如下配置项:

    <property>
        <name>dfs.permissions.enabled</name>
        <value>false</value>
    </property>

重启集群生效,当然,在生产环境中这样配置肯定是不行滴!!!

4.log4j.properties文件

这个贴出来只做参考:

log4j.rootLogger = debug,stdout

### 输出信息到控制抬 ###
log4j.appender.stdout = org.apache.log4j.ConsoleAppender
log4j.appender.stdout.Target = System.out
log4j.appender.stdout.layout = org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern = [%-5p] %d{yyyy-MM-dd HH:mm:ss,SSS} method:%l%n%m%n

5.项目总体结构

项目总体结构

6.实验代码

package com.zhiyou100.hadoop;

import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.io.IntWritable;
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.output.FileOutputFormat;

import java.io.IOException;
import java.util.StringTokenizer;

/**
 * @author longping jie
 * @name MyApp
 * @description the class is 统计红楼梦中的哭和笑出现的次数
 * @date 2017/10/12
 */
public class MyApp {
    public static class MyMapper extends Mapper<Object,Text,Text,IntWritable>{
        private IntWritable num = new IntWritable();
        private Text word = new Text();
        private int no = 0;
        public void map(Object key,Text value,Context context) throws IOException, InterruptedException {
            StringTokenizer st = new StringTokenizer(value.toString(), ", 。 ? !");
            while(st.hasMoreElements()) {

                String text=st.nextElement().toString().trim();
                no = no+1;
                context.getCounter("zy", "statement").increment(1);
                if(text.contains("笑")) {
                    word.set("1笑");
                    num.set(no);
                    context.write(word,num);
                }
                if(text.contains("哭")) {
                    word.set("2哭");
                    num.set(no);
                    context.write(word,num);
                }
            }
        }
    }
    public static class MyReducer extends Reducer<Text,IntWritable,Text,IntWritable> {
        private IntWritable result = new IntWritable();
        public void reduce(Text key,Iterable<IntWritable> values,Context context) throws IOException, InterruptedException {
            int sum=0;
            for(IntWritable val : values) {
                System.out.println(key+":"+val);
                sum+=1;
            }
            result.set(sum);
            context.write(key, result);
        }

    }
    public static void main(String [] args)throws IOException, ClassNotFoundException, InterruptedException{
        Configuration conf = new Configuration();
        Job job = Job.getInstance(conf,"HLM");
        job.setJarByClass(MyApp.class);

        job.setReducerClass(MyReducer.class);
        job.setMapperClass(MyMapper.class);


        job.setOutputKeyClass(Text.class);
        job.setOutputValueClass(IntWritable.class);


        Path in_path = new Path("hdfs://master:9000/text/hlm-utf8.txt");
        Path out_path = new Path("hdfs://master:9000/result/hlm01/");

        FileSystem fs = FileSystem.get(conf);
        if(!fs.exists(in_path)){
            System.out.println("输入路径 " + in_path.getName() + " 不存在");
            System.exit(1);
        }
        if (fs.exists(out_path)) {
            //避免手动删除输出目录的麻烦
            System.out.println("输出路径 " + out_path.getName() + " 已存在,默认删除");
            fs.delete(out_path, true);
        }

        FileInputFormat.setInputPaths(job,in_path);
        FileOutputFormat.setOutputPath(job,out_path);
        System.out.println(job.waitForCompletion(true)?0:1);
    }

}

程序运行结果为:
1笑 3807
2哭 567

注意:
1.提前在input文件夹中上传好实验数据——红楼梦的文本文件。
2.输入输出文件路径可以在args参数中指定。方便打jar包后在程序集群中运行。

程序可能会出现的问题:

异常信息1:
Exception in thread "main" org.apache.hadoop.security.AccessControlException: Permission denied: user=Administrator, access=WRITE, inode="/spark/global":root:supergroup:drwxr-xr-x
at org.apache.hadoop.hdfs.server.namenode.FSPermissionChecker.checkFsPermission(FSPermissionChecker.java:271)

at org.apache.hadoop.hdfs.server.namenode.FSPermissionChecker.check(FSPermissionChecker.java:257)

这是因为当前用户Administrator没有对/spark/global的写入权限. 有几种方式解决:

  1. 增加本地环境变量

  2. 修改本地用户账号

  3. 修改hdfs配置 core-site.xml ,添加 dfs.permissions : false, 并修改目录权限可写入(貌似不太行)

小编通过第一种方式,添加本地环境变量HADOOP_USER_NAME=root解决。
异常信息2:

Exception in thread "main" java.lang.IllegalArgumentException: Wrong FS: hdfs://master:9000/text/hlm-utf8.txt, expected: file:///
    at org.apache.hadoop.fs.FileSystem.checkPath(FileSystem.java:649)
    at org.apache.hadoop.fs.RawLocalFileSystem.pathToFile(RawLocalFileSystem.java:82)
    at org.apache.hadoop.fs.RawLocalFileSystem.deprecatedGetFileStatus(RawLocalFileSystem.java:606)
    at org.apache.hadoop.fs.RawLocalFileSystem.getFileLinkStatusInternal(RawLocalFileSystem.java:824)
    at org.apache.hadoop.fs.RawLocalFileSystem.getFileStatus(RawLocalFileSystem.java:601)
    at org.apache.hadoop.fs.FilterFileSystem.getFileStatus(FilterFileSystem.java:428)
    at org.apache.hadoop.fs.FileSystem.exists(FileSystem.java:1426)
    at com.zhiyou100.hadoop.MyApp.main(MyApp.java:78)

原因:缺少core-site.xml配置文件。

整个项目的搭建以及配置遇到的困难基本如上,如果读者自己在练习的过程中遇到其他错误,欢迎在评论区讨论。小编刚开始学hadoop,不足之处还望各位读者多多指教。谢谢。

最后,欢迎读者关注小编其他后续学习大数据的心得及经验。

阅读更多
版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/wolf_333/article/details/78219751
想对作者说点什么? 我来说一句

没有更多推荐了,返回首页

关闭
关闭
关闭