Mapreduce

Mapreduce是一个批量查询处理器,基本上是一个批处理系统,并不适合交互式分析。HBase,一种使用HDFS做底层存储的键值存储模型。HBase不仅提供对单行的在线读/写访问,还提供对数据块读/写的批操作。
一些不同的,能与Hadoop协同工作的处理方式:
1.交互式SQL
利用Mapreduce进行分发并使用一个分布式查询引擎,使得在Hadoop上获得SQL查询低延迟响应的同时还能保持对大数据集规模的可扩展性。这个引擎使用指定的“总是开启”守护进程或容器重用。
2.迭代处理
许多算法,例如机器学习算法,自身具有迭代性,因此和那种每次迭代都从硬盘加载的方式相比,这种在内存中保存每次中间结果集的方式更加高效。Mapreduce的架构不允许这样,但如果使用Spark就会比较直接,它在使用数据集方面展现了一种高度探究的风格。
3.流处理
流系统,如Spark Streaming使得在无边界数据流上运行实时,分布式的计算,并向Hadoop存储系统或外部系统发布结果成为可能。
4.搜索
搜索平台能够在Hadoop集群上运行,当文档加入HDFS后就可对其进行索引,且根据HDFS中存储的索引为搜索查询提供服务。

相较于其他系统的优势:
1.关系型数据库管理系统
Mapreduce适合一次写入,多次读取数据的应用,关系型数据库则更适合持续更新的数据集。关系型数据库处理结构化的数据,Mapreduce处理半结构化或非结构化的数据。
2.网格计算
相较于网格计算,数据本地化是Hadoop数据处理的核心,并因此获得良好的性能,尽量在计算节点存储数据。

Mapreduce
Mapreduce程序本质上是并行运行的,因此可以将大规模的数据分析任务分发给任何一个拥有足够多机器的数据中心。map阶段的输入是NCDC原始数据。我们选择文本格式作为输入格式,将数据集的每一行作为文本输入。键是某一行起始位置相对于文件起始位置的偏移量。

Mapper例子

import java.io.IOException;
import org.apache.hadoop.io.IntWritable;
import org.apache.hadoop.io.LongWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Mapper;
public class MaxTemperatureMapper extends Mapper<LongWritable,Text,Text,IntWritable>{
    //Mapper类是一个泛型类型,它有四个形参类型,分别指定map函数的输入键、输入值、输出键、输出值的类型
    //LongWritable类型相当于Java的long类型,Text类型相当于String类型,IntWritable类型相当于Integer类型
    private static final int MISSING = 9999;

    @Override
    public void map(LongWritable key,Text value,Context context) throws IOException,  InterruptedException {
        String line = value.toString();
        String year = line.substring(15,19);
        int airTemperature;
        if(line.charAt(87) == '+'){
            airTemperature = Integer.parseInt(line.substring(88,92));
        }else{
            airTemperature = Integer.parseInt(line.substring(87,92));
        }
        String quality = line.substring(92,93);
        if(airTemperature != MISSING && quality.matches("[01459]")){
            context.write(new Text(year),new IntWritable(airTemperature));
            //context实例用于输出内容的写入
        }
    }
}

Reducer的例子

import java.io.IOException;
import org.apache.hadoop.io.IntWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Reducer;
public class MaxTemperatureReducer extends Reducer<Text,IntWritable,Text,IntWritable>{
//reducer输出是mapper的输入
    @Override
    public void reduce(Text key,Iterable<IntWritable> values,Context context) throws IOException,InterruptedException{
    //Iterable迭代器,因为reduce方法的输入的键值对中的值是数组
        int maxValue = Integer.MIN_VALUE;
        for(IntWritable value:values){
            maxValue = Math.max(maxValue,value.get());
        }
        context.write(key,new IntWritable(maxValue));
    }
}

Mapreduce作业

import java.io.IOException;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.io.IntWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Job;
import org.apache.hadoop.mapreduce.lib.input.FileInputFormat;
import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat;
public class MaxTemperature {
    public static void main(String[] args) throws Exception{
        if (args.length !=2){
            System.err.println("Usage:MaxTemperature <input path> <output path>");
            System.exit(-1);
        }

        Job job = new Job();
        job.setJarByClass(MaxTemperature.class);
        job.setJobName("Max temperature");

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

        job.setMapperClass(MaxTemperatureMapper.class);
        job.setReducerClass(MaxTemperatureReducer.class);

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

        System.exit(job.waitForCompletion(true)?0:1);
    }
}

横向扩展

通过使用Hadoop资源管理系统YARN,Hadoop可以将MapReduce计算转移到存储有部分数据的各台机器上。

Mapreduce作业是客户端需执行的一个工作单元:它包括输入数据,MapReduce程序和配置信息。Hadoop将作业分成若干任务来执行,其中包括两类任务:map任务和reduce任务。这些任务运行在集群的节点上,并通过YARN进行调度。如果一个任务失败,它将在另一个不同的节点上重新调度运行。

Hadoop将Mapreduce的输入数据划分成等长的小数据块,称为输入分片。对于大多数作业来说,一个合理的分片大小趋向于HDFS的一个块的大小,默认为128MB(确保存储在单个节点上的最大输入快的大小)。一般情况下,Hadoop都是在存储有输入数据的节点上运行map任务,数据本地化优势。偶尔情况下某个数据节点忙碌中时,会使用其他节点运行map任务,但会导致机架和机架间的网络传输。

map任务将其输出写入本地硬盘,而非HDFS,因为map的输出是中间结果,便于删除。reduce的输出通常存储在HDFS中以实现可靠存储。reduce任务的数量并非由输入数据的大小决定,相反是独立指定的。如果由好多个reduce任务,每个map任务就会针对输出进行分区,即为每个reduce任务建一个分区。每个分区由许多键,但每个键对应的键值对记录都在同一分区中。分区可由用户定义的分区函数控制,但通常用默认的partioner通过哈希函数来分区,很高效。

combiner函数

combiner函数的输出作为reduce函数的输入,combiner属于优化方案。combiner函数能帮助减少mapper和reducer之间的数据传输量。

import java.io.IOException;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.io.IntWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Job;
import org.apache.hadoop.mapreduce.lib.input.FileInputFormat;
import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat;
public class MaxTemperature {
    public static void main(String[] args) throws Exception{
        if (args.length !=2){
            System.err.println("Usage:MaxTemperature <input path> <output path>");
            System.exit(-1);
        }

        Job job = new Job();
        job.setJarByClass(MaxTemperature.class);
        job.setJobName("Max temperature");

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

        job.setMapperClass(MaxTemperatureMapper.class);
        job.setReducerClass(MaxTemperatureReducer.class);

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

        System.exit(job.waitForCompletion(true)?0:1);
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值