MapReduce的执行过程: 如何计算str="abcadefa"中每一个字符出现的次数? char[] chs = str.toCharArray(); Map<Character, Integer> map = new HashMap<Character, Integer>(); for(char ch : chs) { //Integer count = map.get(ch); /*if(count == null) { count = 1; map.put(ch, count); } else { map.put(ch, count + 1); }*/ /*if(count == null) { count = 0; } map.put(ch, count + 1);*/ //map.put(ch, map.get(ch) == null ? 1 : map.get(ch) + 1); //map.put(ch, map.getOrElse(ch, 0) + 1) } ----------------------------------------------------------------- 使用MapReduce来计算统计数据: 统计 hello you hello me hello he中每一个单词出现的次数? 按照上述的单机中的计算思路,首先肯定要把这一行行的文本数据进行拆分,转化成一个个的单词。 map的工作(只负责拆分): String[] words = str.split(" "); for(String word : words) { (word, 1) } 将计算出来的这样一个个(word, 1)的<K, V>的数据类型,写出去,交给进行汇总的程序reduce reduce的工作: 就拿到了非常多的(word, 1),(word, 1)(word, 1),(hello, 1),(hello, 1),(hello, 1) 按照key进行累加操作 但是,在计算过程中有没有问题? 因为有大量的重复类似(word, 1)数据,通过网络从map段进入reduce,需要消耗大量的网络资源,而且延迟非常严重, 只能减少这些重复的数据,减少有两种方式: 第一种方式:------->就是我们在mr运行过程中不可避免的阶段:shuffle (word, 1),(word, 1)(word, 1),(hello, 1),(hello, 1),(hello, 1) ===》 <word, [1, 1, 1]> <hello, [1, 1, 1]> 经历分区 分组 排序等等shuffle操作,把原先的<K, V>的数据类型,转化为<K, [V]>的数据类型 所以,一定要注意:通过shuffle将key相同的数据聚合在一起,然后进入reduce阶段,那么必然在reduce函数计算过程中, key必然相同。 第二种方式:------->一般的mr中没有,需要我们手动指定,本地规约(Combiner),或者就是本地聚合抑或本地reduce (word, 1),(word, 1)(word, 1),(hello, 1),(hello, 1),(hello, 1) ===》 <word, 3> <hello, 3> ---------------------------------------------------- MR-------------- Map的执行过程 框架使用InputFormat类的子类把输入文件(夹)划分为很多InputSplit,默认每个HDFS的block对应一个InputSplit。通过RecordReader类,每个InputSplit解析成一个个<k1,v1>。默认,框架对每个InputSplit中的每一行,解析成一个<k1,v1>。 框架调用Mapper类中的map(...)函数,map函数的形参是<k1,v1>对,输出是<k2,v2>对。 一个InputSplit对应一个map task。程序员可以覆盖map函数,实现自己的逻辑。 (假设reduce不存在)框架对map结果直接输出到HDFS中。(假设reduce存在)框架对map输出的<k2,v2>进行分区。不同的分区中的<k2,v2>由不同的reduce task处理。默认只有1个分区。 (假设reduce存在)框架对每个分区内部的数据,按照k2进行排序、分组。分组指的是相同k2的v2分成一个组。注意:分组不会减少<k2,v2>数量。 (假设reduce存在,可选)在map节点,框架可以执行reduce归约。 (假设reduce存在)框架会对map task输出的<k2,v2>写入到linux 的磁盘文件中。 至此, 整个map阶段结束。 Reduce的执行过程 框架对多个map任务的输出,按照不同的分区,通过网络copy到不同的reduce节点。这个过程称作shuffle。 框架对reduce端接收的<k2,v2>数据进行合并、排序、分组。 框架调用Reducer类中的reduce方法,reduce方法的形参是<k2,{v2}>分组,输出是<k3,v3>。 一个<k2,{v2}>分组调用一次reduce函数。程序员可以覆盖reduce函数,实现自己的逻辑。 框架把reduce的输出保存到HDFS中 至此, 整个reduce阶段结束。 ------------------------------------------------------ 使用MR进行编程,统计文件中每一个单词出现 使用mr-jobhistory-daemon.sh start historyserver启动JobHistoryServer进程 |
|
来自: BIGDATA云 > 《Hadoop大数据分布式存储》