赞
踩
最近在做大数据项目,首先就是配置Hadoop集群,之后就是通过IDEA来连接虚拟机中搭建好的HDFS,但是由于是mac系统,而且网络上面IDEA的配置教程相比于eclipse来说大多都不详细清楚,所以遇到了很多的坑,解决问题之后把相关的过程和方法写下来供交流参考。
这个网上有很多的教程,我就不写了
这里建议把之前在linux上面配置好的Hadoop文件夹直接从虚拟机上面传出来,这样既省事又可以避免出错,毕竟配置环境还是比较复杂的。从虚拟机上面导出来之后,可以开始配置mac的Hadoop环境变量了。
终端输入命令:
sudo vim .bash_profile
在其中的空闲位置处写下环境变量,这里HADOOP_HOME是你从虚拟机中导出来的Hadoop文件路径,我的在/Volumes/Al的扩展/Hadoop/hadoop-2.7.7
,我配置了HADOOP_USER_NAME=root
是为了等会要跑程序的用户是root用户。
#hadoop
export HADOOP_HOME=/Volumes/Al的扩展/Hadoop/hadoop-2.7.7
export HADOOP_USER_NAME=root
export PATH=$PATH:$HADOOP_HOME/sbin:$HADOOP_HOME/bin
之后保存文件,然后
source .bash_profile
这时在mac终端上输入hadoop就可以看到这样的信息
这样就算成功啦!
插件的代码地址:https://github.com/fangyuzhong2016/HadoopIntellijPlugin
如果下载不到的老哥也可以从下面这个链接下载
链接:https://pan.baidu.com/s/1qRBia2dJvCeZbon8q5edHQ 密码:td8r
下载之后要进行编译,需要电脑有maven3环境和1.8的jdk,只能是1.8!上面有讲下载下来需要在里面改hadoop版本为本机hadoop版本,但是我没改也可以使用,
把这个zip下载下来之后,打开IDEA,创建maven项目,然后使用“command + ,“
来打开Preferences,找到里面的Plugin插件设置
点击上方的齿轮,选择从硬盘安装
找到你下载的安装包的位置
点击open,会显示这个
这时候OK就可以了,这时候重启一下IDEA,就会发现右上角多了个Hadoop的选项。这里选择设置
连接名称随便写,描述随便写,下面两个地址要填虚拟机中的那台master机的ip地址,第一个端口是虚拟机配置Hadoop的时候可以得到的,第二个端口写9000。不要点击下面的测试,是不可能成功的,直接点击确定。
然后你会发现在IDEA的最左侧多了一个黄色的小象,点开它,如果可以成功连接上的话,可以看到你hdfs中的文件
但是他不如eclipse上面对应的插件好用,刷新没有那么快,可能有些时候需要手动一下。至此我们成功连接上虚拟机中的HDFS
一开始不知道maven项目可以直接自动导入依赖,按照网上的教程一个一个从我的hadoop文件里面吧jar包导入进去,给我累坏了,后来改了项目中的pom.xml文件才知道,直接从阿里云的maven仓库自动导入依赖。修改项目中的pom.xml文件,把groupId和artifactId改成自己的,添加阿里云的仓库,并且加入slf4的日志输出:
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>cn.Al</groupId> <artifactId>HadoopTest2</artifactId> <version>1.0-SNAPSHOT</version> <repositories> <repository> <id>aliyun</id> <url>https://maven.aliyun.com/repository/public</url> </repository> </repositories> <properties> <hadoop.version>2.7.7</hadoop.version> </properties> <dependencies> <!-- https://mvnrepository.com/artifact/org.apache.hadoop/hadoop-core --> <!-- <dependency>--> <!-- <groupId>org.apache.hadoop</groupId>--> <!-- <artifactId>hadoop-core</artifactId>--> <!-- <version>1.2.1</version>--> <!-- </dependency>--> <dependency> <groupId>org.apache.hadoop</groupId> <artifactId>hadoop-common</artifactId> <version>${hadoop.version}</version> </dependency> <dependency> <groupId>org.apache.hadoop</groupId> <artifactId>hadoop-mapreduce-client-core</artifactId> <version>${hadoop.version}</version> </dependency> <dependency> <groupId>org.apache.hadoop</groupId> <artifactId>hadoop-hdfs</artifactId> <version>${hadoop.version}</version> </dependency> <dependency> <groupId>org.apache.hadoop</groupId> <artifactId>hadoop-mapreduce-client-jobclient</artifactId> <version>${hadoop.version}</version> </dependency> <dependency> <groupId>org.apache.hadoop</groupId> <artifactId>hadoop-mapreduce-client-common</artifactId> <version>${hadoop.version}</version> </dependency> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.12</version> <scope>test</scope> </dependency> <dependency> <groupId>org.apache.hadoop</groupId> <artifactId>hadoop-client</artifactId> <version>2.7.7</version> </dependency> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-api</artifactId> <version>1.7.26</version> </dependency> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-simple</artifactId> <version>1.6.4</version> </dependency> </dependencies> </project>
刚把这些内容复制进去的时候会发现他们是红色的字体,因为jar包没有导入进来,这时候看IDEA的右下角你会发现他在飞快的导包,过一会完成了我们的字体也就恢复常规颜色了。这时我们使用hadoop的包就不会报错了。之后要在resource文件夹中配置log4j
log4j.rootLogger=INFO, stdout, R log4j.appender.stdout=org.apache.log4j.ConsoleAppender log4j.appender.stdout.layout=org.apache.log4j.PatternLayout # Pattern to output the caller's file name and line number. log4j.appender.stdout.layout.ConversionPattern=%5p [%t] (%F:%L) - %m%n log4j.appender.R=org.apache.log4j.RollingFileAppender log4j.appender.R.File=example.log log4j.appender.R.MaxFileSize=100KB # Keep one backup file log4j.appender.R.MaxBackupIndex=1 log4j.appender.R.layout=org.apache.log4j.PatternLayout log4j.appender.R.layout.ConversionPattern=%p %t %c - %m%n
现在开始写我们第一个WordCount小程序吧!新建一个JAVA类,然后把下面的代码粘贴上去。(代码不是本人的,部分注释是)
package com.Al; import java.io.IOException; import java.util.Arrays; 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.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; /** * 统计文本中单词出现的次数 以文件形式输出 * * @author lyd */ public class MyWordCount { public static void main(String[] args) throws IOException, ClassNotFoundException, InterruptedException { //1.设置conf对象,并配置hdfs路径 //2.设置job对象,在job对象中设置 Jar map reduce reduce的输出类型(key value) 输出格式化方式 //文件的输入和输出路径 系统退出 Configuration conf = new Configuration(); conf.set("fs.defaultFS", "hdfs://master:9000"); //设置成集群的key,我的是fs.defaultFS,value是上一步配的hdfs的地址 Job job = Job.getInstance(conf, "wordcount"); job.setJarByClass(MyWordCount.class); job.setMapperClass(MyMapper.class); job.setReducerClass(MyReducer.class); job.setOutputKeyClass(Text.class); job.setOutputValueClass(IntWritable.class); job.setInputFormatClass(TextInputFormat.class); FileInputFormat.addInputPath(job, new Path("/222.txt")); //设置成你要转换的文本,我这里是222.txt,要在hdfs中存在 Path outputPath = new Path("/wordcount/"); FileSystem.get(conf).delete(outputPath, true);// 检查是否存在输出路径,如果存在就先删除 FileOutputFormat.setOutputPath(job, outputPath); System.exit(job.waitForCompletion(true) ? 0 : 1); } /** * @param KEYIN →k1 表示每一行的起始位置(偏移量offset) * @param VALUEIN →v1 表示每一行的文本内容 * @param KEYOUT →k2 表示每一行中的每个单词 * @param VALUEOUT →v2 表示每一行中的每个单词的出现次数,固定值为1 * @author lyd * @version 1.0 */ //Mapper中第三个和第四个参数必须和Reducer中第一个和第二个参数相同,输出结果<key, {value}> public static class MyMapper extends Mapper<LongWritable, Text, Text, IntWritable> { @Override protected void map(LongWritable key, Text value, Mapper<LongWritable, Text, Text, IntWritable>.Context context) throws IOException, InterruptedException { System.err.println("key的值为:" + key.toString()); System.err.println("value的值为:" + value.toString()); String[] words = value.toString().split("\\s+"); System.out.println(Arrays.toString(words) + "-_-"); IntWritable one = new IntWritable(1); Text text = new Text(); for (String word : words) { System.out.println("------------->" + word); text.set(word); context.write(text, one); //连接map和reduce的context } } } /** * @param KEYIN →k2 表示每一行中的每个单词 * @param VALUEIN →v2 表示每一行中的每个单词的出现次数,固定值为1 * @param KEYOUT →k3 表示每一行中的每个单词 * @param VALUEOUT →v3 表示每一行中的每个单词的出现次数之和 * @author lyd * @version 1.0 */ public static class MyReducer extends Reducer<Text, IntWritable, Text, IntWritable> { @Override protected void reduce(Text value, Iterable<IntWritable> iterable, Reducer<Text, IntWritable, Text, IntWritable>.Context context) throws IOException, InterruptedException { int sum = 0; IntWritable i = new IntWritable(); System.err.println("value的值为:" + value + " end!"); for (IntWritable intWritable : iterable) { System.err.println("===>" + intWritable + "<===="); sum += intWritable.get(); } i.set(sum); context.write(value, i); } } }
这时候点击main方法旁边的绿色箭头来运行程序,可以看到程序成功执行,
稍等一会我们会在hdfs里面发现多了一个wordcount文件夹
SUCCESS是成功执行的标志,下面那个文件就是我们最后的结果,我们可以在项目的data文件夹中同步找到这个文件,看一下程序输出的结果吧。
到此为止就全部结束啦!希望能对你有帮助哦~
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。