MapReduce进阶与经典案例

HDFS分为文件格式和压缩格式

文件格式分为两大类:面向行和面向列两大类文件格式.

面向行/

类型名称

是否可切分

优点

缺点

适用场景

面向行

文本文件格式(.txt)

查看方便编辑简单

无压缩占空间大、传输压力大、数据解析开销大

学习练习使用

面向行

sequenceFile序列文件格式(.seq)

原生支持、二进制kv存储、支持行和块压缩

本地查看不方便:小文件合并成kv结构后不易查看内部数据

生产环境使用、map输出的默认文件格式

面向列

rcfile文件格式(.rc)

数据加载快、查询快、空间利用率高、高负载能力

每一项都不是最高

学习生产均可

面向列

orcfile文件格式(.orc)

兼具了rcfile优点,进一步提高了读取、存储效率、新数据类型的支持

每一项都不是最高

学习生产均可

压缩格式分为可切分计算和不可切分计算两种

可切分性

类型名称

是否原生

优点

缺点

适用场景

可切分

lzo(.lzo)

压缩/解压速度快,合理的压缩率

压缩率比gzip低,非原生、需要native安装

单个文件越大,lzo优点越明显,压缩完成后>=200M为宜

可切分

bzip2(.bz2)

高压缩率超过gzip,原生支持、不需要native安装,用linux bzip可解压操作

压缩/解压速率慢

处理速度要求不高、压缩率要求高的情况

不可切分

gzip(.gz)

压缩/解压速度快,原生/native都支持,使用方便

不可切分,对cpu要求较高

压缩完成后<=128M的文件适宜

不可切分

snappy(.snappy)

高压缩/解压速度,合理的压缩率

压缩率比gzip低,非原生、需要native安装

适合作为map->reduce或是job数据流中间的数据传输格式

文件格式的使用

MR输出结果的默认文件格式为txt文件格式

设置输出格式为gzip

通过shell命令改动,添加参数设置模板:
yarn jar jar_path main_class_path -Dk1=v1参数列表 <in> <out>
具体应用:
yarn jar TlHadoopCore-jar-with-dependencies.jar \  
com.tianliangedu.examples.WordCountV2 \
-Dmapred.output.compress=true \
-Dmapred.output.compression.codec=org.apache.hadoop.io.compress.GzipCodec \
/tmp/tianliangedu/input /tmp/tianliangedu/output19

WordCount第二版-WorCountV2.java源码:

//启动mr的driver类
public class WordCountV2 {

       //map类,实现map函数
       public static class TokenizerMapper extends
                    Mapper<Object, Text, Text, IntWritable> {
             //暂存每个传过来的词频计数,均为1,省掉重复申请空间
             private final static IntWritable one = new IntWritable(1);
             //暂存每个传过来的词的值,省掉重复申请空间
             private Text word = new Text();

             //核心map方法的具体实现,逐个<key,value>对去处理
             public void map(Object key, Text value, Context context)
                          throws IOException, InterruptedException {
                    //用每行的字符串值初始化StringTokenizer
                    StringTokenizer itr = new StringTokenizer(value.toString());
                    //循环取得每个空白符分隔出来的每个元素
                    while (itr.hasMoreTokens()) {
                          //将取得出的每个元素放到word Text对象中
                          word.set(itr.nextToken());
                          //通过context对象,将map的输出逐个输出
                          context.write(word, one);
                    }
             }
       }

       //reduce类,实现reduce函数
       public static class IntSumReducer extends
                    Reducer<Text, IntWritable, Text, IntWritable> {
             private IntWritable result = new IntWritable();

             //核心reduce方法的具体实现,逐个<key,List(v1,v2)>去处理
             public void reduce(Text key, Iterable<IntWritable> values,
                          Context context) throws IOException, InterruptedException {
                    //暂存每个key组中计算总和
                    int sum = 0;
                    //加强型for,依次获取迭代器中的每个元素值,即为一个一个的词频数值
                    for (IntWritable val : values) {
                          //将key组中的每个词频数值sum到一起
                          sum += val.get();
                    }
                    //将该key组sum完成的值放到result IntWritable中,使可以序列化输出
                    result.set(sum);
                    //将计算结果逐条输出
                    context.write(key, result);
             }

结果样例: 

设置输出格式为lzo格式:

lzo非原生支持,需要先安装lzo

先安装lzo再安装lzop lzo应用

安装lzo命令:
yum -y install lzo lzo-devel hadooplzo hadooplzo-native
安装lzop命令:
yum install lzop
yarn jar TlHadoopCore-jar-with-dependencies.jar \
com.tianliangedu.core.WordCountV2 \
-Dmapred.output.compress=true \
-Dmapred.output.compression.codec=com.hadoop.compression.lzo.LzopCodec \
/tmp/tianliangedu/input /tmp/tianliangedu/output37

查看结果

 

//从hdfs中下载lzo文件

hdfs dfs -get /tmp/tianliangedu/output41/part-r-00000.lzo

//通过安装了lzo包的lzop命令解压后查看

lzop -cd part-r-00000.lzo | more

//查看效果

 MR应用--自定义Partition

Partition默认实现-HashPartition

//source code:
package org.apache.hadoop.mapreduce.lib.partition;

import org.apache.hadoop.classification.InterfaceAudience;
import org.apache.hadoop.classification.InterfaceStability;
import org.apache.hadoop.mapreduce.Partitioner;
/** Partition keys by their {@link Object#hashCode()}. */
@InterfaceAudience.Public
@InterfaceStability.Stable
public class HashPartitioner<K, V> extends Partitioner<K, V> {
  /** Use {@link Object#hashCode()} to partition. */
  public int getPartition(K key, V value, int numReduceTasks) {
    return (key.hashCode() & Integer.MAX_VALUE) % numReduceTasks;
  }
}

MapReduce个数的确定时机

提交job后,任务开始正式计算之间即已经确定

Map数量的 确定:由输入数据文件的总大小、数据格式  块大小综合确定

Reduce数量确定:系统根据输入数据量的大小自动确定,有固定的计算公式,待冲刺环节详解。另外,用户可以自定义设置,通过参数配置,由用户决定。

自定义reduce数量

yarn jar TlHadoopCore-jar-with-dependencies.jar \
com.tianliangedu.examples.WordCountV2 \
-Dmapred.output.compress=true \
-Dmapred.output.compression.codec=org.apache.hadoop.io.compress.GzipCodec \
-Dmapred.reduce.tasks=2 \
/tmp/tianliangedu/input /tmp/tianliangedu/output38

最终效果图

 自定义Partition实现

继承Partitioner类,自定义实现Partition

通过继承Partitioner类,自定义实现Partition
/**
    自定义Partition的定义
     */
    public static class MyHashPartitioner<K, V> extends Partitioner<K, V> {

        /** Use {@link Object#hashCode()} to partition. */
        public int getPartition(K key, V value, int numReduceTasks) {
            return (key.toString().charAt(0) < 'q' ? 0 : 1) % numReduceTasks;
            // return key.toString().charAt(0);
        }

    }

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值