hadoop-mapreduce进阶

【大数据进阶第二阶段之Hadoop学习笔记】Hadoop 运行模式 阅读详情

本文围绕四部分展开

  • Partitioner编程
  • 自定义排序编程
  • Combiner编程
  • 常见的MapReduce算法

Partitioner编程

  1. Partitioner是partitioner的基类,如果需要定制partitioner也需要继承该类。

  2. HashPartitioner是mapreduce的默认partitioner。计算方法是
    which reducer=(key.hashCode() & Integer.MAX_VALUE) % numReduceTasks,得到当前的目的reducer。

AreaPartitioner.java Github-repo-code

package com.elon33.hadoop.mapreduce.partition;

import java.util.HashMap;

import org.apache.hadoop.mapreduce.Partitioner;

public class AreaPartitioner<KEY, VALUE> extends Partitioner<KEY, VALUE> {

    private static HashMap<String, Integer> areaMap = new HashMap<>();

    static {

        areaMap.put("136", 0);
        areaMap.put("137", 1);
        areaMap.put("138", 2);
        areaMap.put("139", 3);

    }

    @Override
    public int getPartition(KEY key, VALUE value, int numPartitions) {

        Integer provinceCode = areaMap.get(key.toString().substring(0, 3));
        return provinceCode == null ? 4 : provinceCode;
    }

}

FlowCountPartition.java Github-repo-code

package com.elon33.hadoop.mapreduce.partition;

import java.io.IOException;

import org.apache.commons.lang.StringUtils;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.io.LongWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Job;
import org.apache.hadoop.mapreduce.Mapper;
import org.apache.hadoop.mapreduce.Reducer;
import org.apache.hadoop.mapreduce.lib.input.FileInputFormat;
import org.apache.hadoop.mapreduce.lib.input.TextInputFormat;
import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat;
import org.apache.hadoop.mapreduce.lib.output.TextOutputFormat;

import com.elon33.hadoop.mapreduce.flowcount.FlowBean;

public class FlowCountPartition {

    public static class FlowCountPartitionMapper 
                        extends Mapper<LongWritable, Text, Text, FlowBean> {

        private FlowBean flowBean = new FlowBean();

        @Override
        protected void map(LongWritable key, Text value, Context context) throws 
                                                IOException, InterruptedException {

            // 拿到一行数据
            String line = value.toString();
            // 切分字段
            String[] fields = StringUtils.split(line, "\t");
            // 拿到我们需要的若干个字段
            String phoneNbr = fields[1];
            long up_flow = Long.parseLong(fields[fields.length - 3]);
            long d_flow = Long.parseLong(fields[fields.length - 2]);
            // 将数据封装到一个flowbean中
            flowBean.set(phoneNbr, up_flow, d_flow);

            // 以手机号为key,将流量数据输出去
            context.write(new Text(phoneNbr), flowBean);

        }
    }

    public static class FlowCountPartitionReducer extends 
                        Reducer<Text, FlowBean, Text, FlowBean> {
        private FlowBean flowBean = new FlowBean();

        @Override
        protected void reduce(Text key, Iterable<FlowBean> values, Context context)
                throws IOException, InterruptedException {

            long up_flow_sum = 0;
            long d_flow_sum = 0;

            for (FlowBean bean : values) {

                up_flow_sum += bean.getUp_flow();
                d_flow_sum += bean.getD_flow();
            }

            flowBean.set(key.toString(), up_flow_sum, d_flow_sum);

            context.write(key, flowBean);

        }
    }

    public static void main(String[] args) throws Exception {

        Configuration conf = new Configuration();
        Job job = Job.getInstance(conf, "flowpartjob");

        job.setJarByClass(FlowCountPartition.class);

        job.setMapperClass(FlowCountPartitionMapper.class);
        job.setReducerClass(FlowCountPartitionReducer.class);

        /**
         * 加入自定义分区定义 : AreaPartitioner
         */
        job.setPartitionerClass(AreaPartitioner.class);

        /**
         * 设置reduce task的数量,要跟AreaPartitioner返回的partition个数匹配 ◆
         * reducetask的数量比partitioner中分组数多,就会产生多余的几个空文件 ◆
         * reducetask的数量比partitioner中分组数少,就会发生异常,因为有一些key没有对应reducetask接收 ◆
         * reducetask的数量为1,也能正常运行,所有的key都会分给这一个reduce task) reduce task 或 map
         * task 指的是,reuder和mapper在集群中运行的实例
         */
        job.setNumReduceTasks(5);

        job.setMapOutputKeyClass(Text.class);
        job.setMapOutputValueClass(FlowBean.class);

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

        job.setInputFormatClass(TextInputFormat.class);
        job.setOutputFormatClass(TextOutputFormat.class);

        FileInputFormat.setInputPaths(job, new Path("./wc/srcdata/input2"));
        FileOutputFormat.setOutputPath(job, new Path("./wc/outdata/output3"));

        job.waitForCompletion(true);
    }

}

自定义排序编程

  1. 在map和reduce阶段进行排序时,比较的是k2。v2是不参与排序比较的。如果要想让v2也进行排序,需要把k2和v2组装成新的类,作为k2,才能参与比较。详见示例

  2. 分组时也是按照k2进行比较的。


利用在Bean中加入compareTo函数的实现,以及在map阶段将Bean通过key全部传入 实现自定义排序

FlowBean.java Github-repo-code

package com.elon33.hadoop.mapreduce.flowcount;

import java.io.DataInput;
import java.io.DataOutput;
import java.io.IOException;

import org.apache.hadoop.io.Writable;
import org.apache.hadoop.io.WritableComparable;

/**
 * 包含Bean对象字节流式传输的序列化和反序列化过程
 * 
 * @author elon
 *
 */
public class FlowBean implements WritableComparable<FlowBean> {

    private String phoneNbr;
    private long up_flow;
    private long d_flow;
    private long sum_flow;

    public void set(String phoneNbr, long up_flow, long d_flow) {

        this.phoneNbr = phoneNbr;
        this.up_flow = up_flow;
        this.d_flow = d_flow;
        this.sum_flow = up_flow + d_flow;

    }

    public String getPhoneNbr() {
        return phoneNbr;
    }

    public void setPhoneNbr(String phoneNbr) {
        this.phoneNbr = phoneNbr;
    }

    public long getUp_flow() {
        return up_flow;
    }

    public void setUp_flow(long up_flow) {
        this.up_flow = up_flow;
    }

    public long getD_flow() {
        return d_flow;
    }

    public void setD_flow(long d_flow) {
        this.d_flow = d_flow;
    }

    public long getSum_flow() {
        return sum_flow;
    }

    public void setSum_flow(long sum_flow) {
        this.sum_flow = sum_flow;
    }

    /**
     * 序列化,将数据字段以字节流写出去
     */
    @Override
    public void write(DataOutput out) throws IOException {

        out.writeUTF(phoneNbr);
        out.writeLong(up_flow);
        out.writeLong(d_flow);
        out.writeLong(sum_flow);

    }

    /**
     * 反序列化,从字节流中读出各个数据字段 读出的顺序应该跟序列化时写入的顺序保持一致
     */
    @Override
    public void readFields(DataInput in) throws IOException {
        phoneNbr = in.readUTF();
        up_flow = in.readLong();
        d_flow = in.readLong();
        sum_flow = in.readLong();
    }

    @Override
    public String toString() {

        return up_flow + "\t" + d_flow + "\t" + sum_flow;
    }

    /**
     * 对FlowBean添加排序机制:按照sun_flow从大到小排序
     */
    @Override
    public int compareTo(FlowBean o) {

        return sum_flow > o.getSum_flow() ? -1 : 1;
    }

}

FlowCountSort.java Github-repo-code

package com.elon33.hadoop.mapreduce.flowcount;

import java.io.IOException;

import org.apache.commons.lang.StringUtils;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.io.LongWritable;
import org.apache.hadoop.io.NullWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Job;
import org.apache.hadoop.mapreduce.Mapper;
import org.apache.hadoop.mapreduce.Reducer;
import org.apache.hadoop.mapreduce.lib.input.FileInputFormat;
import org.apache.hadoop.mapreduce.lib.input.TextInputFormat;
import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat;
import org.apache.hadoop.mapreduce.lib.output.TextOutputFormat;

public class FlowCountSort {

    public static class FlowCountSortMapper extends 
                        Mapper<LongWritable, Text, FlowBean, NullWritable> {
        FlowBean bean = new FlowBean();

        @Override
        protected void map(LongWritable key, Text value, Context context) 
                                    throws IOException, InterruptedException {
            // 拿到一行数据
            String line = value.toString();
            // 切分字段
            String[] fields = StringUtils.split(line, "\t");
            // 拿到我们需要的若干个字段
            String phoneNbr = fields[0];
            // long up_flow = Long.parseLong(fields[1]);
            // long d_flow = Long.parseLong(fields[2]);
            long up_flow = Long.parseLong(fields[fields.length - 3]);
            long d_flow = Long.parseLong(fields[fields.length - 2]);
            // 将数据封装到一个bean中
            bean.set(phoneNbr, up_flow, d_flow);
            // 以整个Bean对象作为key,将Bean整体都参与到排序中
            context.write(bean, NullWritable.get());

        }

    }

    public static class FlowCountSortReducer extends 
                        Reducer<FlowBean, NullWritable, Text, FlowBean> {

        @Override
        protected void reduce(FlowBean bean, Iterable<NullWritable> values, Context context)
                throws IOException, InterruptedException {
            // 以phone作为key,bean的toString方法作为value输出最终reduce结果
            context.write(new Text(bean.getPhoneNbr()), bean);
        }
    }

    public static void main(String[] args) throws Exception {

        Configuration conf = new Configuration();
        Job job = Job.getInstance(conf, "sortjob");

        job.setJarByClass(FlowCountSort.class);

        job.setMapperClass(FlowCountSortMapper.class);
        job.setReducerClass(FlowCountSortReducer.class);

        job.setMapOutputKeyClass(FlowBean.class);
        job.setMapOutputValueClass(NullWritable.class);

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

        job.setInputFormatClass(TextInputFormat.class);
        job.setOutputFormatClass(TextOutputFormat.class);

        FileInputFormat.setInputPaths(job, new Path("./wc/srcdata/input2"));
        FileOutputFormat.setOutputPath(job, new Path("./wc/outdata/output2"));

        job.waitForCompletion(true);

    }
}

Combiner编程

每一个map可能会产生大量的输出,combiner的作用就是在map端对输出先做一次合并,以减少传输到reducer的数据量。

combiner最基本是实现本地key的归并,combiner具有类似本地的reduce功能。

如果不用combiner,那么,所有的结果都是reduce完成,效率会相对低下。使用combiner,先完成的map会在本地聚合,提升速度。

注意:Combiner的输出是Reducer的输入,如果Combiner是可插拔的,添加Combiner绝不能改变最终的计算结果。所以Combiner只应该用于那种Reduce的输入key/value与输出key/value类型完全一致,且不影响最终结果的场景。比如累加,最大值等。

Job执行流程图

这里写图片描述

这里写图片描述

Shuffle

这里写图片描述

  1. 每个map有一个环形内存缓冲区,用于存储任务的输出。默认大小100MB(io.sort.mb属性),一旦达到阀值0.8(io.sort.spill.percent),一个后台线程把内容写到(spill)磁盘的指定目录(mapred.local.dir)下的新建的一个溢出写文件。
  2. 写磁盘前,要partition,sort。如果有combiner,combine排序后数据。
  3. 等最后记录写完,合并全部溢出写文件为一个分区且排序的文件。
  4. Reducer通过Http方式得到输出文件的分区。
  5. TaskTracker为分区文件运行Reduce任务。复制阶段把Map输出复制到Reducer的内存或磁盘。一个Map任务完成,Reduce就开始复制输出。
  6. 排序阶段合并map输出。然后走Reduce阶段。

常见的MapReduce算法

◆ 单词计数
◆ 数据去重
◆ 排序
◆ Top K
◆ 选择
◆ 投影
◆ 分组
◆ 多表连接
◆ 单表关联

参考链接:MapReduce中的常见算法 https://www.cnblogs.com/1130136248wlxk/p/4975116.html

倒排索引过程算法实现

通过多个文件,统计每个单词在每个文件中出现的次数,以 word file1-->count1 file2-->count2...形式输出最终结果

该mr程序分为两步:
1. 对同一文件夹中,相同的key值进行数值统计
2. 将不同文件中的同一个word,统计”文件–>计数“的信息,并拼接在一起输出
{% note success %}
源数据包–>利用map(切分)–>shuffer(合并)、sort(对key值排序)—>reduce(统计value值)—>输出结果
{% endnote %}

InverseIndexStepOne.java Github-repo-code

package com.elon33.hadoop.mapreduce.inverseIndex;

import java.io.IOException;

import org.apache.commons.lang.StringUtils;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.io.LongWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.InputSplit;
import org.apache.hadoop.mapreduce.Job;
import org.apache.hadoop.mapreduce.Mapper;
import org.apache.hadoop.mapreduce.Reducer;
import org.apache.hadoop.mapreduce.lib.input.FileInputFormat;
import org.apache.hadoop.mapreduce.lib.input.FileSplit;
import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat;


/**
 * 倒排索引的第一个步骤
 * 对同一文件夹中,相同的key值进行数值统计
 * @author elon@elon33.com
 *
 */


//cn.itheima.bigdata.hadoop.mr.ii.InverseIndexStepOne
public class InverseIndexStepOne {

    public static class InverseIndexStepOneMapper extends
            Mapper<LongWritable, Text, Text, LongWritable> {
        private Text k = new Text();
        private LongWritable v = new LongWritable();

        @Override
        protected void map(LongWritable key, Text value, Context context)
                throws IOException, InterruptedException {

            String line = value.toString();

            String[] words = StringUtils.split(line, " ");

            //获取本次调用传递进来的数据所在的文件信息,先要获取所属切片信息
            FileSplit inputSplit = (FileSplit) context.getInputSplit();
            //从切片信息中获取到文件路径及文件名
            String fileName = inputSplit.getPath().getName();

            //输出 kv对  < hello-->a.txt , 1>
            for (String word : words) {
                k.set(word + "-->" + fileName);
                v.set(1);
                context.write(k, v);

            }

        }

    }

    public static class InverseIndexStepOneReducer extends 
                        Reducer<Text, LongWritable, Text, LongWritable>{
        private LongWritable v = new LongWritable();

        //  <hello-->a.txt ,{1,1,1...}>
        @Override
        protected void reduce(Text key, Iterable<LongWritable> values,Context context)
                throws IOException, InterruptedException {

            //遍历values进行累加
            long count  = 0;
            for(LongWritable value:values){
                count += value.get();
            }
            v.set(count);
            context.write(key, v);
        }
    }

    public static void main(String[] args) throws Exception {
        Configuration conf = new Configuration();

        Job job_stepOne = Job.getInstance(conf);

        job_stepOne.setJarByClass(InverseIndexStepOne.class);

        job_stepOne.setMapperClass(InverseIndexStepOneMapper.class);
        job_stepOne.setReducerClass(InverseIndexStepOneReducer.class);

        job_stepOne.setOutputKeyClass(Text.class);
        job_stepOne.setOutputValueClass(LongWritable.class);

        FileInputFormat.setInputPaths(job_stepOne, new Path("./wc/srcdata/input3"));
        FileOutputFormat.setOutputPath(job_stepOne, new Path("./wc/outdata/output5"));

        job_stepOne.waitForCompletion(true);

    }

}

InverseIndexStepTwo.java Github-repo-code

package com.elon33.hadoop.mapreduce.inverseIndex;

import java.io.IOException;

import org.apache.commons.lang.StringUtils;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.io.LongWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Job;
import org.apache.hadoop.mapreduce.Mapper;
import org.apache.hadoop.mapreduce.Reducer;
import org.apache.hadoop.mapreduce.lib.input.FileInputFormat;
import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat;
/**
 * 倒排索引的第二个步骤、
 * 将不同文件中的同一个word,统计”文件-->计数“的信息,并拼接在一起输出
 * @author elon@elon33.com
 *
 */
public class InverseIndexStepTwo {

    public static class InverseIndexStepTwoMapper extends
            Mapper<LongWritable, Text, Text, Text> {
        private Text k = new Text();
        private Text v = new Text();

        @Override
        protected void map(LongWritable key, Text value, Context context)
                throws IOException, InterruptedException {
            String line = value.toString();

            // 切分出各个字段
            String[] fields = StringUtils.split(line, "\t");
            long count = Long.parseLong(fields[1]);
            String wordAndFile = fields[0];
            String[] wordAndFileName = StringUtils.split(wordAndFile, "-->");
            String word = wordAndFileName[0];
            String fileName = wordAndFileName[1];

            //将单词作为key  ,文件-->次数 作为value 输出
            k.set(word);
            v.set(fileName + "-->" + count);
            context.write(k, v);
        }

    }


    public static class InverseIndexStepTwoReducer extends Reducer<Text, Text, Text, Text>{

//      private Text k = new Text();
        private Text v = new Text();

        // key: hello    values: [a-->3,b-->2,c-->1]
        @Override
        protected void reduce(Text key, Iterable<Text> values,Context context)
                throws IOException, InterruptedException {

            String result = "";

            //一个key,有多个value 用result将多个value拼接在一起
            for(Text value:values){
                result += value + " ";
            }
            v.set(result);
            // key: hello    v:  a-->3 b-->2 c-->1 
            context.write(key, v);

        }


    }

    public static void main(String[] args) throws Exception {
        Configuration conf = new Configuration();

        Job job_stepTwo = Job.getInstance(conf);

        job_stepTwo.setJarByClass(InverseIndexStepTwo.class);

        job_stepTwo.setMapperClass(InverseIndexStepTwoMapper.class);
        job_stepTwo.setReducerClass(InverseIndexStepTwoReducer.class);

        job_stepTwo.setOutputKeyClass(Text.class);
        job_stepTwo.setOutputValueClass(Text.class);

        FileInputFormat.setInputPaths(job_stepTwo, new Path("./wc/outdata/output5/part-r-00000"));
        FileOutputFormat.setOutputPath(job_stepTwo, new Path("./wc/outdata/output6"));

        job_stepTwo.waitForCompletion(true);

    }
}

多表连接,利用mr程序实现大数据量的关联查询

a.txt
id    name 
001   iphone6
002   xiaominote
003   mate7
004   nubia
005   meilan

b.txt

id    orderid  
001     00101
001     00110
002     01001
...

001   iphone6-->a  00101-->b  00110-->b

join query 期望结果:

select a.name,b.orderid from a,b where a.id=b.id
iphone6  00101
iphone6  00110

JoinQuery.java Github-repo-code

package com.elon33.hadoop.mapreduce.joinquery;

import java.io.IOException;
import java.util.ArrayList;

import org.apache.commons.lang.StringUtils;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.io.LongWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Job;
import org.apache.hadoop.mapreduce.Mapper;
import org.apache.hadoop.mapreduce.Reducer;
import org.apache.hadoop.mapreduce.lib.input.FileInputFormat;
import org.apache.hadoop.mapreduce.lib.input.FileSplit;
import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat;

public class JoinQuery {

    public static class JoinQueryMapper extends Mapper<LongWritable, Text, Text, Text>{

        private Text k = new Text();
        private Text v = new Text();

        @Override
        protected void map(LongWritable key, Text value,Context context)
                throws IOException, InterruptedException {

            String record = value.toString();

            String[] fields = StringUtils.split(record,"\t");

            String id = fields[0];
            String name = fields[1];

            FileSplit inputSplit = (FileSplit) context.getInputSplit();
            String fileName = inputSplit.getPath().getName();

            k.set(id);
            v.set(name+"-->"+fileName);
            // k:001    v:  iphone6-->a.txt
            context.write(k, v);
        }


    }

    public static class JoinQueryReducer extends Reducer<Text, Text, Text, Text>{

        // 通过map阶段,已经将a.txt和b.txt中key值相同的项关联起来了,reduce阶段的任务就是对value做切分
        // k:001    values:[iphone6-->a.txt, 00101-->b.txt,00110-->b.txt]
        @Override
        protected void reduce(Text key, Iterable<Text> values,Context context)
                throws IOException, InterruptedException {

            //第一次循环拿出a表中的那个字段
            String leftKey = "";
            ArrayList<String> rightFields = new ArrayList<>();
            for(Text value:values){
                if(value.toString().contains("a.txt")){
                    leftKey = StringUtils.split(value.toString(), "-->")[0];    // leftKey:["iphone6"]
                }else{
                    rightFields.add(value.toString());  //rightField:["00101-->b.txt", "00110-->b.txt"]
                }

            }

            //再用leftkey去遍历拼接b表中的字段,并输出结果
            for(String field:rightFields){
                    String result ="";
                    result += leftKey +"\t" +StringUtils.split(field.toString(), "-->")[0]; //result:["iphone6  00101","iphone6   00110"]
                    context.write(new Text(leftKey), new Text(result));
            }
        }

    }

    public static void main(String[] args) throws Exception {

        Configuration conf = new Configuration();

        Job joinjob = Job.getInstance(conf);

        joinjob.setJarByClass(JoinQuery.class);

        joinjob.setMapperClass(JoinQueryMapper.class);
        joinjob.setReducerClass(JoinQueryReducer.class);

        joinjob.setOutputKeyClass(Text.class);
        joinjob.setOutputValueClass(Text.class);

        FileInputFormat.setInputPaths(joinjob, new Path(args[0]));
        FileOutputFormat.setOutputPath(joinjob, new Path(args[1]));

        joinjob.waitForCompletion(true);


    }

}

思考题

◆ 如何使用计数器
利用mr程序通过切分,合并、排序,统计得到最终的计数结果,具体实现查看 源代码

◆ Combiner的作用是什么,应用场景是什么 导航Combiner
Mapper过程中Combiner的作用 http://www.aboutyun.com/thread-7093-1-1.html

◆ Partitioner的作用是什么,应用场景是什么
将reduce通过多个分区来分别运算,得到不同分区的值。
MapReduce中combine、partition、shuffle的作用是什么?在程序中怎么运用? http://blog.youkuaiyun.com/u013063153/article/details/72357560

◆ Shuffler的过程是什么
MapReduce:详解Shuffle过程 http://langyu.iteye.com/blog/992916

MapReduce进阶编程 它配置并启动一个 MapReduce 作业,包括设置 Mapper、Reducer、Combiner、Partitioner 类,指定输入和输出路径,以及配置输入和输出格式。Reducer 根据键中的日志时间判断该日志属于哪个月份(2021年1月或2月),并增加相应月份的计数器。然后,它对值集合中的所有值进行累加,并将累加结果与原始键一起输出。对象的日志时间,如果日期包含 “2021/1”,则将该键分配到分区 0,否则分配到分区 1。主要功能是连接到 HDFS 文件系统,并删除指定路径下的文件或目录。 阅读详情

相关推荐

Hadoop系列之五:MapReduce进阶(2)

Hadoop系列之五:MapReduce进阶(2)

马哥教育Linux运维培训 699

Hadoop大数据开发基础系列:五、MapReduce进阶编程

五、MapReduce进阶编程 目录: 1.筛选日志文件并生成序列化文件 2.HadoopJavaAPI读取序列化日志文件 3.优化日志文件统计程序 4.Eclipse提交日志文件统计程序 5.小结 6.实训 7.小练习 任务背景:网站运营方又提出来新的需求,为了比较今年与去年同期的用户访问数据,要求分别统计出2016年1月与2月的用户访问次数,并输出到不同的目录中。在本章中...

Nelson_hehe的博客 6824

【重启后nvidia-smi 命令出现错误】

NVIDIA-SMI has failed because it couldn't communicate with the NVIDIA driver. Make sure that the latest NVIDIA driver is installed and running.

qq_44769377的博客 5217

MapReduce的应用开发与编程模型详细进阶概述

!!!学习之前请回顾一下之前的菜鸟基础介绍 https://blog.youkuaiyun.com/weixin_42507474/article/details/107055643 首先我们 复习一下什么是MapReduce:是Google的一个编程模型,采用并行计算的处理方式来及进行大数据的计算 **MapReduce拥有“分散任务、汇总结果”的特点,及把对大规模数据集的操作,分发给主节点管理下的各个子节点共同完成,然后整合各个子节点的中间结果,从而得到最终的计算结果。**这以特点有效的更简洁的让程序员的程序

weixin_42507474的博客 885

Android MediaCodec学习笔记

模块介绍 基本概念 OpenMAX是Khronos Group提出的标准,目标在于创造一个统一的接口,加速大量多媒体资料的处理。OpenMAX分成三层:应用层(Application Layer, AL), 整合层(Integration Layer, IL) 以及开发层(Development Layer, DL)。 OpenMAX (Open Media Acceleration) OpenMAX AL Application Layer ..

kisshine 2358

Habitat-baselines v0.1.7防踩坑手把手带你跑通(全网唯一)

Habitat-baselines v0.1.7防踩坑手把手带你跑通(全网唯一)

shannanshouyin的博客 1279

Hadoop进阶之路

Hadoop 是一个开源的分布式计算平台,能够使用简单的编程模型跨计算机集群分布式处理大规模数据,为任何类型的数据提供海量存储,巨大的处理能力以及处理几乎无限的并发任务或作业的能力。它的核心组件包括 HDFS(Hadoop Distributed File System)、MapReduce 和 Yarn,这些组件相互协作,使得 Hadoop 能够高效地处理和存储海量数据。

£菜鸟也有梦的博客 1983

R语言分段回归

1.利用虚拟变量进行线性回归 (MEdata.csv的数据来源:https://github.com/ChenQihome9/优快云-Data-Library/blob/master/MEdata.csv) 问题13:针对TAX~GDP,使用分段回归方法,找到其回归方程。编程,并根据程序结果叙述如下几方面问题:(1)分几段最佳?(不超过5段内)(2)分段位置定在哪儿最佳?(3)写出最佳方...

ChenQihome9的博客 1万+

Hadoop:MapReduce进阶编程(WritableComparable和cleanup的使用)

Hadoop:MapReduce进阶编程(WritableComparable和cleanup的使用)一、案例要求实验内容 1,自定义类型实验内容 2,Top N 求解实验简析二、实现过程1.IntelliJ IDEA 创建Maven工程2.完整代码子实验1子实验23.Maven打包4.Hadoop集群运行参考网站及视频 一、案例要求 实验内容 1,自定义类型 1)已知数据格式如下(用户名\t 收入\t 支出\t 日期);PS:实际是按空格,如下面的数据 zhangsan 6000 0 2016-05-0

weixin_43594279的博客 1215

信号处理仿真:自适应信号处理_(8).自适应信道均衡

在无线通信系统中,信道的多径效应和时变特性会导致信号的失真,从而影响通信质量。自适应信道均衡技术通过实时调整均衡器的参数,以补偿信道失真,提高信号的质量和可靠性。本节将详细介绍自适应信道均衡的原理、算法和实现方法,并通过具体的仿真例子来说明其应用。

2401_87715305的博客 1041

基于ESP32的室内空气质量检测系统开发

随着环境污染问题的日益严重,室内空气质量的监测变得越来越重要。室内空气质量的好坏直接影响到人们的健康,尤其是对于在封闭空间长时间待着的人群。为此,基于ESP32的室内空气质量检测系统应运而生。ESP32作为一款集成了Wi-Fi和蓝牙的高性能微控制器,为嵌入式开发提供了良好的平台,适用于构建各种智能硬件设备。本博客将详细介绍如何基于ESP32开发一个室内空气质量检测系统。系统可以实时监测空气中的温度、湿度、二氧化碳浓度、甲醛浓度等指标,并通过Wi-Fi将数据传输到云端或移动设备,方便用户随时查看空气质量情况。

2201_76125393的博客 832

Hadoop MapReduce 进阶实战:自定义组件与多场景案例

用户ID,IP,访问时间,URL按月份(2021/1、2021/2)统计每月访问量;不同月份结果输出到独立文件(避免数据混杂)。自定义 Partitioner:需保证 ReduceTask 数与分区数一致,适用于多维度结果分类;利用 Key 合并特性:简化去重、分组等场景的代码开发;组件解耦:Mapper 负责解析、Reducer 负责聚合、Driver 负责配置,便于维护。

wyyyyhdh的博客 947

Android功耗系列专题理论之十三:MTK平台待机功耗问题分析方法

摘要:本文详细分析了MTK平台待机功耗问题的调试方法,重点介绍了SPM电源管理机制、26M时钟控制逻辑以及系统深睡眠状态的判断标准。文章提供了完整的Debug流程,包括日志抓取、唤醒源分析、SCP睡眠状态检查以及时钟/LDO状态排查等实用技巧,并给出硬件漏电点和软件配置异常的排查方案。针对不同模块(Modem/Conn/SSPM等)提供了具体的电源管理绕过命令,适用于功耗问题调试和低功耗模式验证场景。

561

Hadoop进阶之MapReduce编程模型简介和总结

本文转载修改自《MapReduce编程模型简介和总结》 https://www.cnblogs.com/mmaa/p/5789911.html InputFormat OutputFormat Mapper和Reducer Partitioner MapReduce应用广泛的原因之一就是其易用性,提供了一个高度抽象化而变得非常简单的编程模型,它是在总结大量应用的共同特点的基础

啊左的专栏 4101

完整的 Python 数据分析案例:新能源汽车续航里程预测

随着新能源汽车的普及,续航里程成为消费者关注的重要指标。准确预测新能源汽车的续航里程,有助于车企优化电池管理系统、提升车辆性能,也能帮助消费者合理规划出行。本案例将基于新能源汽车的各项参数,如电池容量、行驶速度、环境温度等,构建续航里程预测模型。通过以上改进,可以提高数据处理的准确性、模型的性能和可视化的效果。

daqsdfas的博客 1588

jre9下载 jdk9

(Java SE Runtime Environment 9.0) 9.0u175 官方最新版 【x86|x64】

Hadoop系列之四:MapReduce进阶

Hadoop系列之四:MapReduce进阶

马哥教育Linux运维培训 776

汉书HE8,好用的汇编代码编写工具

汉书HE8,好用的汇编代码编写工具早期编写汇编代码所用功能强大

Hadoop MapReduce进阶 使用Chain

情况:在进行高级的数据处理时,你会发现你的程序不能放在一个的MapReduce job之中了。Hadoop支持将多个MapReduce Job串成一条链来形成一个更大的MapReduce Job。同时你会发现Hadoop数据处理过程中通常包括多个数据源,我们将探索一些join技术同时处理多个数据源。 1.将具有复杂依赖关系的多个MapReduce Job串联起来。 情况:有三个Job,分别成为

jokes000的专栏 6614

NTscan扫描工具

ntscan是一个扫描器,可以扫描没有密码和弱密码的共享,先到配置文件中填写猜测的用户名和密码,扫描过程中右侧出现的是扫描日志。

RU DOS版、EFI版32bit/64bit BIOS常用工具

DOS版、EFI版的RU工具,可用来查看IO、MEM、PCI、SMBIOS等资源。亲测在EFI SHELL下可用。

Hadoop进阶(hadoop streaming c++实现 & MapReduce参数调优)

hadoop streaming c++实现 心得 与 MapReduce参数调用 目录: 1,机器学习 & MR Hadoop进阶(hadoop streaming c++实现 & MapReduce参数调优) hadoop streaming (shell执行 & combiner & 数据分割) hadoop streaming python 处理 lzo 文件遇到的问题 spark安装与调试 推荐算法之Jaccard相似度与Consine相似度 LibLinear使用总结 深度学习在推荐领域的应用

思緒凌亂 2473

Hadoop学习之路(十):MapReduce进阶之链式MapReduce操作实战

内容简介一、链式MapReduce操作的概念二、链式MapReduce实战案例1. 需求分析2. 数据准备3. 代码编写4. 打包上传5. 测试三、总结 一、链式MapReduce操作的概念 在以往的MapReduce案例中,无论是简单的WordCount还是比较复杂的使用MR统计社交共同好友的MapReduce作业都仅仅包含一个Map类和Reducer类,这就使得MR作业在实现某些复杂的程序时...

萧邦主的城邦 808

hadoop之mapreduce详解(进阶篇)

上篇文章hadoop之mapreduce详解(基础篇)我们了解了mapreduce的执行过程和shuffle过程,本篇文章主要从mapreduce的组件和输入输出方面进行阐述。 一、mapreduce作业控制模块以及其他功能小说阅读网 https://www.7wx.org/ mapreduce包括作业控制模块,编程模型,数据处理引擎。这里我们重点阐述作业控制模块MRAppMaster。...

代码小牛的博客 556

Hadoop MapReduce进阶 使用DataJoin包实现Join

概念: Hadoop有一个叫DataJoin的包为Data Join提供相应的框架。它的Jar包存在于contrib/datajoin/hadoop-*-datajoin。 为区别于其他的data join技术,我们称其为reduce-side join。(因为我们在reducer上作大多数的工作) reduce-side join引入了一些术语及概念:             1.Dat

jokes000的专栏 7701

Hadoop入门进阶课程5--MapReduce原理及操作

* 1 环境说明* 部署节点操作系统为CentOS,防火墙和SElinux禁用,创建了一个shiyanlou用户并在系统根目录下创建/app目录,用于存放Hadoop等组件运行包。因为该目录用于安装hadoop等组件程序,用户对shiyanlou必须赋予rwx权限(一般做法是root用户在根目录下创建/app目录,并修改该目录拥有者为shiyanlou(chown –R shiyanlou

yirenboy的专栏 1476

Hadoop入门进阶课程6--MapReduce应用案例

1 环境说明 注意:本实验是对前述实验的延续,如果直接点开始实验进入则需要按先前学习的方法启动hadoop 部署节点操作系统为CentOS,防火墙和SElinux禁用,创建了一个shiyanlou用户并在系统根目录下创建/app目录,用于存放Hadoop等组件运行包。因为该目录用于安装hadoop等组件程序,用户对shiyanlou必须赋予rwx权限(一般做法是root用户在根目录下创建/

yirenboy的专栏 1818

Hadoop学习笔记:MapReduce 编程进阶

数据类型 Hadoop 使用派生于 Writable 接口的类作为 Mapreduce 计算的数据类型。 value 数据类型,必须实现 org.apache.hadoop.io.Writable 接口,此接口确定了如何进行序列化与反序列化。 key 数据类型必须实现 org.apache.hadoop.io.WritableComparable 接口,定义了键的相互比较。 WritableCom...

narata1的博客 764
上一篇: 分布式文件系统与HDFS笔记
下一篇: hadoop-mapreduce
gamedev˚
博客等级 码龄12年 280粉丝 293原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值