Hadoop-mapReduce

什麼是MR: 

 start-dfs.sh  啓動hdfs集羣
 start-yarn.sh 啓動yarn集羣
./hadoop-daemon.sh start namenode/datanode 單個節點的啓動

局部統計(各幹各的:Map):每一臺機器上在其對應的數據上,執行相同的程序,每一個實例執行一部分的程序,得到每一臺機器上的結果

結果就是A:1000, 也就是A這個單詞出現了1000次,同樣的在其他的機器上也會有A出現的次數,

全局統計(彙總:Reduce):在局部統計的基礎之上在進行一次全局統計,使用A 的哈希值對3的模(這裏是舉例說明),那麼都會是等於一個值,非A的哈希值對3的模肯定會和A 不一樣,一這種方式找到所有機器上key=A的結果,進行統計,從而使的相同key 的的結果能到達下一階段的相同的地方。

而在中間程序在每臺機器上的運行,分發,map 到reduce 階段數據的分發等都是框架取做的,程序員只需要關注的就是計算的邏輯。

另一篇文章的總結如下

Mapper任務

  1. 將本地輸入文件按照一定標註分片,按照block的配置大小分片,每一個輸入片由一個mapp進程處理。
  2. 將輸入片按照一定的規則解析爲鍵值對,有一個默認的規則是,鍵是行號,值是行內容
  3. 調用mapper 程序(我們寫的處理邏輯),在2階段解析出來的每一個鍵值對,每一對會調用一次mapper,對輸入的鍵值在處理,生成的還會是鍵值對
  4. 對3階段輸出的鍵值對進行分區,比較是基於鍵的,分類多少個區就是Reduce任務運行的數量,比如我們的鍵表示省份(如北京、上海、山東等),那麼就可以按照不同省份進行分區,同一個省份的鍵值對劃分到一個區中。
  5. 對每個分區中的鍵值進行排序。

Reduce任務:

  1. 調用reduce方法,一個鍵會對應很多的值,(<a,1>,<a,3>...),鍵相等的鍵值對調用一次reduce方法,每次調用會產生零個或者多個鍵值對。最後把這些輸出的鍵值對寫入到HDFS文件中。

在你跑程序之前還應該配置yarn集羣,這個集羣負責機器資源的分配,配置文件

        <property>
                <name>yarn.nodemanager.aux-services</name>
                <value>mapreduce_shuffle</value>
        </property>
        <property>
                <name>yarn.resourcemanager.hostname</name>
                <value>master</value>
        </property>

yarn.resourcemanager.hostname 的值就是yarn主節點的機器(就好比使 dfs 的namenode),nodemanager也最好能放在和dataNode的機器上,因爲在跑程序的時候是在yarn的node上跑的,此時這些node離數據越近自然也就越好了,當啓動start-yarn.sh腳本的時候,這個腳本也會去讀slaves的配置文件,然後將配置文件中的那些node 中都會去啓動nodemanager,這樣nodemanager和dataNode就都在一起了。

還需要配置一個文件:指定mp程序在單機運行的時候就不需要這個配置,但是需要分佈式運行,那麼就需要在yarn上運行。

<configuration>
        <property>
                <name>mapreduce.framework.name</name>
                <value>yarn</value>
        </property>
</configuration>
import java.io.IOException;

/*
    KEYIN: 是MR提供的程序讀取到一行數據的始偏移量 Long
    VALUEIN: 使MR提供的程序讀取到一行數據的內容 String
    KEYOUT: 是用戶邏輯處理方法返回處理完成之後返回給框架中key 的類型 String
    VALUEOUT: 是用戶邏輯處理方法返回處理完成之後返回給框架中key 對應的value 的值 Integer

    Long, String, Integer 等java 的類型是不能在hadoop中傳輸,hadoop 有自己的這些類型,產生這些類型的原因
    是數據需要在hadoop 機器之間需要傳輸,序列化, 反序列化等有較大開銷,
    Long: LongWritable
    String: Text
    Int: IntWritable
 */
public class Map extends Mapper<LongWritable, Text, Text, IntWritable> {
    /*
           MR 提供的方法,沒讀一行數據就會調用一次我們寫的map方法,數據已經被框架傳遞夠來
           只需要寫計算數據的邏輯
     */
    @Override
    protected void map(LongWritable key, Text value, Context context) throws IOException, InterruptedException {
        String line = value.toString();
        String[] split = line.split(" ");
        for (String k:split) {
            context.write(new Text(k), new IntWritable(1));
        }
    }
}


public class Red extends Reducer<Text, IntWritable,Text, IntWritable> {
    /*
        MR 框架提供的reduce端程序接受到的是每一組數據key是一樣的,但是 values是會有很多個得,
        這裏如 a:1, a:1, a:1, a:1,整理好一組後調一次reduce
     */
    @Override
    protected void reduce(Text key, Iterable<IntWritable> values, Context context) throws IOException, InterruptedException {
        int cnt = 0;
        for (IntWritable val:values) {
            cnt += val.get();
        }
        context.write(key, new IntWritable(cnt));
    }
}

public class JobSubmiter {

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

        // 設置整個job需要的jar包
        // 通過JobSubmiter來找到其他依賴WCMapper和WCReducer
        job.setJarByClass(JobSubmiter.class);

        // 本job使用的mapper和reducer類
        job.setMapperClass(Map.class);
        job.setReducerClass(Red.class);

        // 指定reducer的輸出kv類型
        job.setMapOutputKeyClass(Text.class);
        job.setMapOutputValueClass(IntWritable.class);

        // 指定mapper的輸出kv類型
        job.setOutputKeyClass(Text.class);
        job.setOutputValueClass(IntWritable.class);

        // 定義輸入,及數據位置
//        job.setInputFormatClass(TextInputFormat.class);
        FileInputFormat.setInputPaths(job,new Path("/webLog/input"));

        // 定義輸出,及輸出位置
//        job.setOutputFormatClass(TextOutputFormat.class);
        FileOutputFormat.setOutputPath(job, new Path("/webLog/output"));

        // 向yarn 提交
        boolean completion = job.waitForCompletion(true);// 打印程序運行進度

        System.exit(completion?0:1);
    }
}

打jar包:

本地機器上傳到集羣

scp hadooptest2.jar [email protected]:/root

運行:

 hadoop jar hadooptest2.jar MapReduce.JobSubmiter

 

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