MAC系統IDEA中利用Hadoop的插件來連接虛擬機HDFS

寫在前面

最近在做大數據項目,首先就是配置Hadoop集羣,之後就是通過IDEA來連接虛擬機中搭建好的HDFS,但是由於是mac系統,而且網絡上面IDEA的配置教程相比於eclipse來說大多都不詳細清楚,所以遇到了很多的坑,解決問題之後把相關的過程和方法寫下來供交流參考。

配置虛擬機Hadoop集羣

這個網上有很多的教程,我就不寫了

在mac上面配置Hadoop 環境

這裏建議把之前在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就可以看到這樣的信息
在這裏插入圖片描述
這樣就算成功啦!

在IDEA中使用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項目來運行我們第一個MapReduce程序

一開始不知道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文件夾中同步找到這個文件,看一下程序輸出的結果吧。
在這裏插入圖片描述
到此爲止就全部結束啦!希望能對你有幫助哦~

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章