使用Cygwin類比Linux環境安裝配置運行基於單機的Hadoop__Linux

來源:互聯網
上載者:User

其實,使用Cygwin類比Linux環境來運行Hadoop是非常輕鬆的,只需要簡單地配置一下就可以運行基於單機的Hadoop。

這裡,比較關鍵的就是Cygwin的安裝,在選擇安裝的時候一定要安裝openssh,否則不會成功的,下面簡單說一下Cygwin的安裝及其配置:

Cygwin的下載安裝

首先點擊http://cygwin.com/setup.exe下載setup.exe,例如儲存到案頭,點擊就可以進行下載安裝了。

在選擇安裝類型的時候,最好是選擇第一個,直接從網路上下載並緊接著安裝,如圖所示:

然後選擇安裝路徑、安裝檔案存放路徑、串連方式(這裡選擇Use IE5 Settings)、下載網站鏡像,自動建立下載檔案清單,接下來一步比較重要了:選擇安裝類型,可以單擊最頂層的All後面的迴圈樣式表徵圖切換安裝類型,是的最頂層All行的最後一個單詞為Install,如圖所示:

其實,如果你選擇了Install安裝類型,就已經選擇了openssh包。

為讓你看到openssh包,你可以在Net [表徵圖] Install 下面看到與網路有關的包,如圖所示:

向下滑動捲軸,可以看到openssh,如圖所示:

在Cirrent下如果顯示版本號碼,說明該包已經被此次安裝選擇上了,否則的話會顯示一個Skip,意思是跳過該包,並不會安裝該包的。

最後就等著下載安裝了,這個過程可能會花費一點時間的。

Cygwin的配置

安裝完成之後,例如我的Cygwin安裝在G:/Cygwin/目錄下面,進行配置如下:

設定環境變數:

在系統變數中建立變數【變數名:CYGWIN,變數值:ntsec tty】;編輯添加變數【變數名:Path,變數值:G:/Cygwin/bin;其它的保留】。

OK,基本配置好了,可以配置Hadoop了。

Hadoop目前的有幾個版本:hadoop-0.16.4、hadoop-0.18.0,到Apache下載一個並解壓縮即可。

將解壓縮的Hadoop放到G盤下,例如我的是:G:/hadoop-0.16.4。

配置Hadoop只需要修改G:/hadoop-0.16.4/conf目錄下的hadoop-env.sh檔案即可,開啟它你可以看到:

# The java implementation to use. Required.
# export JAVA_HOME=/usr/lib/j2sdk1.5-sun

將第二行的注釋符號去掉,同時指定在你的機器上JAVA_HOME的值,如下為我修改的內容:

# The java implementation to use. Required.
export JAVA_HOME="D:/Program Files/Java/jdk1.6.0_07"

這裡要注意,如果你的JDK安裝目錄中存在空格,需要使用雙引號引起來,否則就會報錯。

啟動Cygwin,當前它是在home/yourname目錄下的,如圖所示:

切換到根目錄下,從而進入G:/hadoop-0.16.4目錄,並建立一個資料輸入目錄input-dir,如圖所示:

下面,開啟G:/hadoop-0.16.4/input-dir,在該目錄下建立幾個記事本檔案,例如我建立了3個:input-a.txt、input-b.txt、input-c.txt。三個檔案的內容如下所示:

input-a.txt:as after append actor as as add as apache as after add as

input-b.txt:bench be bench believe background bench be block

input-c.txt:cafe cat communications connection cat cat cat cust cafe

接著就可以執行Hadoop內建的一個統計英文單詞出現頻率的例子了,直接輸入命令bin/hadoop jar hadoop-0.16.4-examples.jar wordcount input-dir output-dir,其中hadoop-0.16.4-examples.jar是G:/hadoop-0.16.4包中的例子,input-dir是資料輸入目錄,在裡面已經存在我們建立的三個檔案了,output-dir是經過Hadoop處理後的輸出結果的目錄,這裡,你需要對Google的MapReduce演算法有一個簡單的瞭解,主要就是在處理資料的時候是怎樣的一個流程,引用IBM上的一片技術文章片段瞭解一下:

引 用

用 MapReduce 來處理大資料集的過程, 這個 MapReduce 的計算過程簡而言之,就是將大資料集分解為成百上千的小資料集,每個(或若干個)資料集分別由叢集中的一個結點(一般就是一台普通的電腦)進行處理並產生中間結果,然後這些中間結果又由大量的結點進行合并, 形成最終結果。

計算模型的核心是 Map 和 Reduce 兩個函數,這兩個函數由使用者負責實現,功能是按一定的映射規則將輸入的 <key, value> 對轉換成另一個或一批 <key, value> 對輸出。


表一 Map 和 Reduce 函數

函數 輸入 輸出 說明
Map <k1, v1> List(<k2,v2>) 1. 將小資料集進一步解析成一批 <key,value> 對,輸入 Map 函數中進行處理。
2. 每一個輸入的 <k1,v1> 會輸出一批 <k2,v2>。 <k2,v2> 是計算的中間結果。
Reduce <k2,List(v2)> <k3,v3> 輸入的中間結果 <k2,List(v2)> 中的 List(v2) 表示是一批屬於同一個 k2 的 value

基於 MapReduce 計算模型編寫分布式並行程式非常簡單,程式員的主要編碼工作就是實現 Map 和 Reduce 函數,其它的並行編程中的種種複雜問題,如分布式儲存,工作調度,Server Load Balancer,容錯處理,網路通訊等,均由 MapReduce 架構(比如 Hadoop )負責處理,程式員完全不用操心。

本地計算

資料存放區在哪一台電腦上,就由這台電腦進行這部分資料的計算,這樣可以減少資料在網路上的傳輸,降低對網路頻寬的需求。在 Hadoop 這樣的基於叢集的分布式並行系統中,計算結點可以很方便地擴充,而因它所能夠提供的計算能力近乎是無限的,但是由是資料需要在不同的電腦之間流動,故網路頻寬變成了瓶頸,是非常寶貴的,“本地計算”是最有效一種節約網路頻寬的手段,業界把這形容為“移動計算比移動資料更經濟”。

任務粒度

把原始大資料集切割成小資料集時,通常讓小資料集小於或等於 HDFS 中一個 Block 的大小(預設是 64M),這樣能夠保證一個小資料集位於一台電腦上,便於本地計算。有 M 個小資料集待處理,就啟動 M 個 Map 任務,注意這 M 個 Map 任務分佈於 N 台電腦上並行運行,Reduce 任務的數量 R 則可由使用者指定。

Partition

把 Map 任務輸出的中間結果按 key 的範圍劃分成 R 份( R 是預先定義的 Reduce 任務的個數),劃分時通常使用 hash 函數如: hash(key) mod R,這樣可以保證某一段範圍內的 key,一定是由一個 Reduce 任務來處理,可以簡化 Reduce 的過程。

Combine

在 partition 之前,還可以對中間結果先做 combine,即將中間結果中有相同 key的 <key, value> 對合并成一對。combine 的過程與 Reduce 的過程類似,很多情況下就可以直接使用 Reduce 函數,但 combine 是作為 Map 任務的一部分,在執行完 Map 函數後緊接著執行的。Combine 能夠減少中間結果中 <key, value> 對的數目,從而減少網路流量。

Reduce 任務從 Map 任務結點取中間結果

Map 任務的中間結果在做完 Combine 和 Partition 之後,以檔案形式存於本地磁碟。中間結果檔案的位置會通知主控 JobTracker, JobTracker 再通知 Reduce 任務到哪一個 DataNode 上去取中間結果。注意所有的 Map 任務產生中間結果均按其 Key 用同一個 Hash 函數劃分成了 R 份,R 個 Reduce 任務各自負責一段 Key 區間。每個 Reduce 需要向許多個 Map 任務結點取得落在其負責的 Key 區間內的中間結果,然後執行 Reduce 函數,形成一個最終的結果檔案。

任務管道

有 R 個 Reduce 任務,就會有 R 個最終結果,很多情況下這 R 個最終結果並不需要合并成一個最終結果。因為這 R 個最終結果又可以做為另一個計算任務的輸入,開始另一個並行計算任務。

執行過程如下所示:

SHIYANJUN@cbbd2ce9428e48b /cygdrive/g/hadoop-0.16.4
$ bin/hadoop jar hadoop-0.16.4-examples.jar wordcount input-dir output-dir
cygpath: cannot create short name of g:/hadoop-0.16.4/logs
08/09/12 20:42:50 INFO jvm.JvmMetrics: Initializing JVM Metrics with processName
=JobTracker, sessionId=
08/09/12 20:42:51 INFO mapred.FileInputFormat: Total input paths to process : 3
08/09/12 20:42:51 INFO mapred.JobClient: Running job: job_local_1
08/09/12 20:42:51 INFO mapred.MapTask: numReduceTasks: 1
08/09/12 20:42:52 INFO mapred.JobClient: map 0% reduce 0%
08/09/12 20:42:52 INFO mapred.LocalJobRunner: file:/g:/hadoop-0.16.4/input-dir/i
nput-a.txt:0+57
08/09/12 20:42:52 INFO mapred.TaskRunner: Task 'job_local_1_map_0000' done.
08/09/12 20:42:52 INFO mapred.TaskRunner: Saved output of task 'job_local_1_map_
0000' to file:/g:/hadoop-0.16.4/output-dir
08/09/12 20:42:53 INFO mapred.MapTask: numReduceTasks: 1
08/09/12 20:42:53 INFO mapred.LocalJobRunner: file:/g:/hadoop-0.16.4/input-dir/i
nput-b.txt:0+48
08/09/12 20:42:53 INFO mapred.TaskRunner: Task 'job_local_1_map_0001' done.
08/09/12 20:42:53 INFO mapred.TaskRunner: Saved output of task 'job_local_1_map_
0001' to file:/g:/hadoop-0.16.4/output-dir
08/09/12 20:42:53 INFO mapred.MapTask: numReduceTasks: 1
08/09/12 20:42:53 INFO mapred.LocalJobRunner: file:/g:/hadoop-0.16.4/input-dir/i
nput-c.txt:0+56
08/09/12 20:42:53 INFO mapred.TaskRunner: Task 'job_local_1_map_0002' done.
08/09/12 20:42:53 INFO mapred.TaskRunner: Saved output of task 'job_local_1_map_
0002' to file:/g:/hadoop-0.16.4/output-dir
08/09/12 20:42:53 INFO mapred.JobClient: map 100% reduce 0%
08/09/12 20:42:54 INFO mapred.LocalJobRunner: reduce > reduce
08/09/12 20:42:54 INFO mapred.TaskRunner: Task 'reduce_z7f1uq' done.
08/09/12 20:42:54 INFO mapred.TaskRunner: Saved output of task 'reduce_z7f1uq' t
o file:/g:/hadoop-0.16.4/output-dir
08/09/12 20:42:54 INFO mapred.JobClient: Job complete: job_local_1
08/09/12 20:42:54 INFO mapred.JobClient: Counters: 9
08/09/12 20:42:54 INFO mapred.JobClient:   Map-Reduce Framework
08/09/12 20:42:54 INFO mapred.JobClient:     Map input records=3
08/09/12 20:42:54 INFO mapred.JobClient:     Map output records=30
08/09/12 20:42:54 INFO mapred.JobClient:     Map input bytes=161
08/09/12 20:42:54 INFO mapred.JobClient:     Map output bytes=284
08/09/12 20:42:54 INFO mapred.JobClient:     Combine input records=30
08/09/12 20:42:54 INFO mapred.JobClient:     Combine output records=16
08/09/12 20:42:54 INFO mapred.JobClient:     Reduce input groups=16
08/09/12 20:42:54 INFO mapred.JobClient:     Reduce input records=16
$

上面是根據給定的輸入的資料進行執行的一個過程,其實結果已經輸出到output-dir目錄中,你可以進行查看,在目錄G:/hadoop-0.16.4/output-dir下面產生了兩個檔案:.part-00000.crc和part-00000。

查看處理結果,如下所示:

或者,直接到G:/hadoop-0.16.4/output-dir目錄下面開啟part-00000檔案查看即可,內容如下所示:

actor 1
add 2
after 2
apache 1
append 1
as 6
background 1
be 2
believe 1
bench 3
block 1
cafe 2
cat 4
communications 1
connection 1
cust 1

同上面的是一樣的。

這是一個非常簡單的例子,而且Hadoop在其中實現了Google的MapReduce演算法,用以處理資料。

我們可以簡單看一下關於WordCount類的實現,在Hadoop的發行包中也附帶了例子的原始碼,WordCount.java類實現如下所示:

 

package org.apache.hadoop.examples;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.StringTokenizer;

import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.conf.Configured;
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.mapred.JobClient;
import org.apache.hadoop.mapred.JobConf;
import org.apache.hadoop.mapred.MapReduceBase;
import org.apache.hadoop.mapred.Mapper;
import org.apache.hadoop.mapred.OutputCollector;
import org.apache.hadoop.mapred.Reducer;
import org.apache.hadoop.mapred.Reporter;
import org.apache.hadoop.util.Tool;
import org.apache.hadoop.util.ToolRunner; /**

/**
* 這是一個Hadoop Map/Reduce應用的例子。
* 讀取輸入的檔案,實現將檔案的每一行分解成單個的單詞並統計單詞的出現頻率。
* 輸出結果是被分解的單詞的列表及其詞頻。
* 使用如下命令可以運行: bin/hadoop jar build/hadoop-examples.jar wordcount
*            [-m <i>maps</i>] [-r <i>reduces</i>] <i>in-dir</i> <i>out-dir</i>
*/
public class WordCount extends Configured implements Tool {

/**
   * MapClass是一個內部靜態類。統計資料檔案中每一行的單詞。
   */
public static class MapClass extends MapReduceBase
    implements Mapper<LongWritable, Text, Text, IntWritable> {
   
    private final static IntWritable one = new IntWritable(1);
    private Text word = new Text();
   
    public void map(LongWritable key, Text value,
                    OutputCollector<Text, IntWritable> output,
                    Reporter reporter) throws IOException {
      String line = value.toString();
      StringTokenizer itr = new StringTokenizer(line);
      while (itr.hasMoreTokens()) {
        word.set(itr.nextToken());
        output.collect(word, one);
      }
    }
}

/**
   * Reduce是一個內部靜態類。作為統計單詞數量的中間結果類,由於這個例子簡單無須執行中間結果的合并。
   */
public static class Reduce extends MapReduceBase
    implements Reducer<Text, IntWritable, Text, IntWritable> {
   
    public void reduce(Text key, Iterator<IntWritable> values,
                       OutputCollector<Text, IntWritable> output,
                       Reporter reporter) throws IOException {
      int sum = 0;
      while (values.hasNext()) {
        sum += values.next().get();
      }
      output.collect(key, new IntWritable(sum));
    }
}

static int printUsage() { // 提示輸入命令的用法
    System.out.println("wordcount [-m <maps>] [-r <reduces>] <input> <output>");
    ToolRunner.printGenericCommandUsage(System.out);
    return -1;
}

/**
   * map/reduce程式的驅動部分,用於實現提交map/reduce任務。
   */
public int run(String[] args) throws Exception {
    JobConf conf = new JobConf(getConf(), WordCount.class);
    conf.setJobName("wordcount");

    // the keys are words (strings)
    conf.setOutputKeyClass(Text.class);
    // the values are counts (ints)
    conf.setOutputValueClass(IntWritable.class);
   
    conf.setMapperClass(MapClass.class);       
    conf.setCombinerClass(Reduce.class);
    conf.setReducerClass(Reduce.class);
   
    List<String> other_args = new ArrayList<String>();
    for(int i=0; i < args.length; ++i) {
      try {
        if ("-m".equals(args[i])) {
          conf.setNumMapTasks(Integer.parseInt(args[++i]));
        } else if ("-r".equals(args[i])) {
          conf.setNumReduceTasks(Integer.parseInt(args[++i]));
        } else {
          other_args.add(args[i]);
        }
      } catch (NumberFormatException except) {
        System.out.println("ERROR: Integer expected instead of " + args[i]);
        return printUsage();
      } catch (ArrayIndexOutOfBoundsException except) {
        System.out.println("ERROR: Required parameter missing from " +
                           args[i-1]);
        return printUsage();
      }
    }
    // Make sure there are exactly 2 parameters left.
    if (other_args.size() != 2) {
      System.out.println("ERROR: Wrong number of parameters: " +
                         other_args.size() + " instead of 2.");
      return printUsage();
    }
    conf.setInputPath(new Path(other_args.get(0)));
    conf.setOutputPath(new Path(other_args.get(1)));
       
    JobClient.runJob(conf);
    return 0;
}


public static void main(String[] args) throws Exception {
    int res = ToolRunner.run(new Configuration(), new WordCount(), args);
    System.exit(res);
}

}

通過對著這個例子進行簡單的說明,大致瞭解一下MapReduce演算法的思想及其實現。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.