1. 程式人生 > >Windows下開發Hadoop程式遇到的坑及解決方案

Windows下開發Hadoop程式遇到的坑及解決方案

背景

過幾天工作需要用到Hadoop,於是就弄了本PDF看。看了半天也是暈暈乎乎的。乾脆直接動手,這樣還能掌握的快一點。於是我就在本地要搭建一個Hadoop的開發環境。

環境前提

1、Hadoop部署在測試伺服器上。 2、開發人員在Windows上使用eclipse進行開發。(即執行和開發環境是分開的) 3、環境引數

Linux:CentOS release 6.7 (Final) x86_64

Java ,version:1.7.0_80 (x86_64)

Hadoop ,version:1.2.1

------------------------------

windows ,version:Windows 7 professional x86_64

eclipse ,version:Luna Service Release 2 (4.4.2)

------------------------------

4、其他需要使用的開源庫

Apache Ant ,version:1.9.4

開始前準備

1、千萬不要有中文路徑!!!

2、如果Windows使用者名稱是中文的,改掉它!!!變成英文的使用者名稱!!!

Linux上的Hadoop安裝

Java安裝

1、Java安裝還是相對簡單的

2、首先去oracle官網下載對應的Java程式包,下載的時候需要登入,這個比較麻煩。Java下載頁面

3、下載好之後是一個tar.gz檔案,放到Linux下的某個目錄(此處我放在了/opt下)

4、執行命令,解包

cd /opt
tar xvf 剛剛下載的tar.gz的檔名
// 示例
tar xvf jdk-7u80-linux-x64.tar.gz
// 解壓出來的資料夾名稱太長,這裡我把資料夾重新命名,這一步不是必須的
mv 解壓出的檔名 新檔名
// 示例
mv jdk-7u80-linux-x64 jdk1.7.0_80
5、設定PATH環境變數
vim /etc/profile
// 增加JAVA_HOEM
export JAVA_HOME=/opt/jdk1.7.0_80
export PATH=$PATH:$JAVA_HOME/bin
6、載入當前環境變數
source /etc/profile
7、檢視是否成功
java -version
若出現Java的版本資訊等文字,證明安裝成功。

Hadoop安裝

2、與Java安裝一樣,使用tar命令解壓,然後配置環境變數 3、
vim /etc/profile
export HADOOP_HOME=/opt/hadoop-1.2.1
export PATH=$PATH:$HADOOP_HOME/bin
source /etc/profile
4、對hadoop進行相關的配置(hadoop資料夾下的conf,這裡我的路徑為/opt/hadoop-1.2.1) (1)進入conf目錄,vim編輯core-site.xml,編輯如下
<?xml version="1.0"?>
<?xml-stylesheet type="text/xsl" href="configuration.xsl"?>

<!-- Put site-specific property overrides in this file. -->

<configuration>

<property>
    <name>hadoop.tmp.dir</name>
    <value>/hadoop</value>
</property>
<property>
    <name>dfs.name.dir</name>
    <value>/hadoop/name</value>
</property>
<property>
    <name>fs.default.name</name>
    <value>hdfs://hostname:9000</value>
</property>
<property>
    <name>dfs.permissions</name>
    <value>false</value>
</property>

</configuration>
這裡我遇到了第一個坑就是
hdfs://hostname:9000
這一行配置,我根據網上的教程配置自己的hostname,於是變成了這樣
hdfs://localhost:9000
幾乎網上所有的教程都是這麼寫的。但是。請最好不要這樣,因為這會再你配置eclipse時帶來無盡的麻煩。(不要問我是怎麼知道的)。我的建議是這樣
hdfs://Linux伺服器的IP地址:9000
(2)vim 編輯hadoop-env.sh

找到這一行

# export JAVA_HOME=/usr/lib/j2sdk1.5-sun
將它變為
export JAVA_HOME=/opt/jdk1.7.0_80
也就是把剛剛配置的JAVA_HOME的內容複製到此

(3)vim編輯hdfs-site.xml

<?xml version="1.0"?>
<?xml-stylesheet type="text/xsl" href="configuration.xsl"?>

<!-- Put site-specific property overrides in this file. -->

<configuration>

<property>
    <name>dfs.data.dir</name>
    <value>/hadoop/data</value>
</property>
<property>
    <name>dfs.permissions</name>
    <value>false</value>
</property>

</configuration>
(4)vim編輯mapred-site.xml
<?xml version="1.0"?>
<?xml-stylesheet type="text/xsl" href="configuration.xsl"?>

<!-- Put site-specific property overrides in this file. -->

<configuration>

<property>
    <name>mapred.job.tracker</name>
    <value>Linux的IP地址:9001</value>
</property>

</configuration>

說明一下,dfs.permissions配置預設為true,由於是測試用,這裡將其關閉,避免過多的麻煩

這裡的配置是最簡單的一個配置,目的是為了能讓使用者快速開始hadoop的使用。
IP:埠號中的埠號可以進行自定義,不一定非要9000和9001,自己能區分就ok

5、進入/opt/hadoop-1.2.1/bin下

./start-all.sh

會出現讓你輸入root密碼的選項,3次。輸入就ok

之後格式化hdfs

hadoop fs -format
執行jps命令,若出現以下字樣,代表啟成功了(前邊的數字可能不太一樣)

windows下的開發環境搭建

eclipse外掛的安裝

之前一般eclipse外掛都是能在網上下載到的,這次出乎我的意料,很少有下載的,網上的教程幾乎清一色都是要自己編譯的。我偏不信。。下載了幾個。。果然不能用,有幾個能用的,但是各種出錯。最好的辦法還是自己編譯一下。

編譯很簡單的。

首先將剛剛下載的hadoop的tar.gz解壓出來,這裡我解壓到了D盤。

eclipse外掛編譯

(1)進入D:\hadoop-1.2.1\src\contrib\eclipse-plugin目錄下 (2)build.properties檔案最下邊新增2個配置,注意不要有空格
eclipse.home=D:/eclipse
version=1.2.1
第一行就是你的eclipse的安裝目錄。第二個的意思就是你的hadoop的版本 (3)修改build.xml 在節點<path id="eclipse-sdk-jars">內新增一個節點
<fileset dir="../../../">  
	<include name="hadoop*.jar"/>  
</fileset>
整個path節點就變成了這樣
  <path id="eclipse-sdk-jars">
    <fileset dir="${eclipse.home}/plugins/">
      <include name="org.eclipse.ui*.jar"/>
      <include name="org.eclipse.jdt*.jar"/>
      <include name="org.eclipse.core*.jar"/>
      <include name="org.eclipse.equinox*.jar"/>
      <include name="org.eclipse.debug*.jar"/>
      <include name="org.eclipse.osgi*.jar"/>
      <include name="org.eclipse.swt*.jar"/>
      <include name="org.eclipse.jface*.jar"/>

      <include name="org.eclipse.team.cvs.ssh2*.jar"/>
      <include name="com.jcraft.jsch*.jar"/>
    </fileset> 
	<fileset dir="../../../">  
		<include name="hadoop*.jar"/>  
    </fileset>
  </path>
在<target name="jar" depends="compile" unless="skip.contrib">節點內註釋掉2行,新增2行,最終target節點變成了這樣
  <target name="jar" depends="compile" unless="skip.contrib">
    <mkdir dir="${build.dir}/lib"/>
	<!-- 
        <copy file="${hadoop.root}/build/hadoop-core-${version}.jar" tofile="${build.dir}/lib/hadoop-core.jar" verbose="true"/>
        <copy file="${hadoop.root}/build/ivy/lib/Hadoop/common/commons-cli-${commons-cli.version}.jar"  todir="${build.dir}/lib" verbose="true"/>
	-->
    <copy file="${hadoop.root}/hadoop-core-${version}.jar" tofile="${build.dir}/lib/hadoop-core.jar" verbose="true"/>  
    <copy file="${hadoop.root}/lib/commons-cli-${commons-cli.version}.jar"  todir="${build.dir}/lib" verbose="true"/>
	
    <jar
      jarfile="${build.dir}/hadoop-${name}-${version}.jar"
      manifest="${root}/META-INF/MANIFEST.MF">
      <fileset dir="${build.dir}" includes="classes/ lib/"/>
      <fileset dir="${root}" includes="resources/ plugin.xml"/>
    </jar>
  </target>
之後使用windows的smd命令列工具,進入D:\hadoop-1.2.1\src\contrib\eclipse-plugin,輸入“ant”命令。等待幾分鐘就ok了(期間需要聯網)。 編譯成功後,進入D:\hadoop-1.2.1\build\contrib\eclipse-plugin目錄下,可以看到有一個hadoop-eclipse-plugin-1.2.1.jar檔案,將其複製到eclipse的安裝目錄下的plugins資料夾內,重啟eclipse即可。


eclipse外掛配置

(1)首先調出hadoop的view,右上角,開啟新的view,選擇藍色的大象,map/reduce
然後選擇windows-->preferences
選擇剛剛解壓到D盤的hadoop路徑 (2)配置Location

右鍵,選擇“new hadoop location”,出現新的選項卡

需要填寫的地方有幾個, Location Name,自己隨便起個名字。 左側的Master Host和Port,寫之前字啊Linux下配置IP與埠號,右側也是,埠號的對應關係是: mapred.job.tracker節點的value對應左側,core-site.xml裡的fs.default.name節點value對應右側。 username寫root,因為我之前在Linux一直是用root使用者操作的。
(3)修改advanced引數
有好多個引數,這裡只要把我們之前在Linux上配置過的節點的值改過來即可。

比如之前我們配置的hadoop.tmp.dir的值是/hadoop,而這裡預設的值不是這個,需要改正過來。改好之後,點選完成即可。

eclipse外掛使用


我們可以看見剛剛建立的location在左側顯示出來了,點選箭頭,可以檢視什麼在HDFS中的目錄結構,在對應目錄上右鍵,可以進行建立,修改檔案之類的操作。

遇到的問題

是不是感覺上邊太容易了?沒有什麼坑嘛,是因為我都拿在這裡說了。。。

(1)剛剛第一步編譯的hadoop-eclipse-plugin-1.2.1.jar,直接使用的話,在配置location時會有各種錯誤,通過分析錯誤日誌可以發現是由於缺少jar包導致的,我們先關閉eclipse,對這個jar處理一下。

(2)用壓縮工具開啟jar包,是開啟,不是解壓,然後進入lib資料夾下,右鍵新增檔案,在D:\hadoop-1.2.1\lib路徑下選擇要增加的jar包,如圖所示


新增這幾個jar包之後,我們回到上級目錄,進入META-INF,修改MANIFEST.MF檔案。

在倒數第二行,將原來的Bundle-ClassPath值修改為

Bundle-ClassPath: classes/,lib/hadoop-core.jar,lib/commons-cli-1.2.jar,lib/commons-configuration-1.6.jar,lib/commons-httpclient-3.0.1.jar,lib/commons-lang-2.4.jar,lib/jackson-core-asl-1.8.8.jar,lib/jackson-mapper-asl-1.8.8.jar
注意,要在一行上寫,也就是說中間不要有空格,不要打回車

弄好之後我們儲存一下,替換原來的jar包即可。

第二個問題是關於許可權問題的,由於在windows上和linux上的檔案許可權不盡相同,會帶來不必要的麻煩,所以我們需要對D:\hadoop-1.2.1\hadoop-core-1.2.1.jar進行修改,不過我按照網上的教程,註釋掉部分原始碼之後,在進行編譯,還是會出現錯誤,不知道是不是我的操作不正確,後來我在網上找到一個修改過的hadoop-core-1.0.3.jar,經測試可以正常使用,我在下邊給出連線,大家可以下載使用

hadoop例項

新建Map/Reduce工程,複製如下程式碼
package xavier.hadoop.wordcount;

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

import org.apache.hadoop.conf.Configuration;
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;
import org.apache.hadoop.mapreduce.lib.output.TextOutputFormat;

public class WordCount {

	public static class WordCountMap extends
			Mapper<LongWritable, Text, Text, IntWritable> {

		private final IntWritable one = new IntWritable(1);
		private Text word = new Text();

		public void map(LongWritable key, Text value, Context context)
				throws IOException, InterruptedException {
			String line = value.toString();
			StringTokenizer token = new StringTokenizer(line);
			while (token.hasMoreTokens()) {
				word.set(token.nextToken());
				context.write(word, one);
			}
		}
	}

	public static class WordCountReduce extends
			Reducer<Text, IntWritable, Text, IntWritable> {

		public void reduce(Text key, Iterable<IntWritable> values,
				Context context) throws IOException, InterruptedException {
			int sum = 0;
			for (IntWritable val : values) {
				sum += val.get();
			}
			context.write(key, new IntWritable(sum));
		}
	}

	public static void main(String[] args) throws Exception {
		Configuration conf = new Configuration();
		Job job = new Job(conf);
		job.setJarByClass(WordCount.class);
		job.setJobName("wordcount");

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

		job.setMapperClass(WordCountMap.class);
		job.setReducerClass(WordCountReduce.class);

		job.setInputFormatClass(TextInputFormat.class);
		job.setOutputFormatClass(TextOutputFormat.class);

		FileInputFormat.addInputPath(job, new Path(args[0]));
		FileOutputFormat.setOutputPath(job, new Path(args[1]));

		job.waitForCompletion(true);
	}
}
這是一個比較簡單的wordcount的入門例子,本人也剛剛接觸,就不在講解程式碼了。

要執行,需要先配置輸入引數,選擇run confignation

裡邊的IP換成自己的就ok。

需要注意的是,input/file01需要自己去建立的,file01隨便寫幾個英文單詞的句子就可以,最後會輸出檔案內每個單詞出現的數量。

感覺最後敘述的有些混亂了。。。大家明白意思就好。不一定非要按我的配置來,可以靈活變動的。

以上是我首次配置hadoop的過程,其中花費我不少時間,希望這篇文章能幫更多的初學者少走一些彎路。

最後奉上連線

連結: http://pan.baidu.com/s/1qY3thZQ 密碼: g53i