自己实现 一个MapReduce 示例


有这样一个实际的问题需要要通过hadoop的来解决一下。
有一个学生成绩表,有学生姓名 和成绩格式如下
zs 89
zs 100
ls 98
ls 100
zs 20
ww 89
ww 67
ls 30
ww 20


一个学生 有多个科目,有不同的成绩。
需要对每个同学的成绩求平均值。
同时,把这个student.txt 上传到 hadoop的 file System 中。

./bin/hadoop fs -put ~/file/student.txt

代码如下:

package com.picc.test;

import java.io.IOException;
import java.util.Iterator;
import java.util.StringTokenizer;

import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.io.IntWritable;
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 org.apache.hadoop.util.Tool;
import org.apache.hadoop.util.ToolRunner;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.picc.mapreducetest.MyMapReduceTest;
/***
* 定义一个AvgScore 求学生的平均值 要实现一个Tool 工具类,是为了初始化一个hadoop配置实例
*/
public class AvgScore implements Tool{
    public static final Logger log=LoggerFactory.getLogger(AvgScore.class);
    Configuration configuration;
	// 是版本 0.20.2的实现
    public static class MyMap extends Mapper<Object, Text, Text, IntWritable>{

        @Override
        protected void map(Object key, Text value, Context context)  throws IOException, InterruptedException {
            String stuInfo = value.toString();//将输入的纯文本的数据转换成String
            System.out.println("studentInfo:"+stuInfo);
            log.info("MapSudentInfo:"+stuInfo);
			//将输入的数据先按行进行分割
            StringTokenizer tokenizerArticle = new StringTokenizer(stuInfo, "\n");
			//分别对每一行进行处理
            while(tokenizerArticle.hasMoreTokens()){
			// 每行按空格划分 
                StringTokenizer tokenizer = new StringTokenizer(tokenizerArticle.nextToken());
                String name = tokenizer.nextToken();//学生姓名
                String score = tokenizer.nextToken();//学生成绩
                Text stu = new Text(name);
                int intscore = Integer.parseInt(score);
                log.info("MapStu:"+stu.toString()+" "+intscore);
                context.write(stu,new IntWritable(intscore));//输出学生姓名和成绩  
            }
        }
        
    }
    public static class MyReduce extends Reducer<Text, IntWritable, Text, IntWritable>{

        @Override
        protected void reduce(Text key, Iterable<IntWritable> values,Context context)
                throws IOException, InterruptedException {
            int sum=0;
            int count=0;
            Iterator<IntWritable> iterator=    values.iterator();
            while(iterator.hasNext()){
                sum+=iterator.next().get();//计算总分
                count++;//统计总科目
            }
            int avg= (int)sum/count;
            context.write(key,new  IntWritable(avg));//输出学生姓名和平均值
        }
        
    }
    public  int run(String [] args) throws Exception{
        
          Job job = new Job(getConf());
          job.setJarByClass(AvgScore.class);
          job.setJobName("avgscore");
          job.setOutputKeyClass(Text.class);
          job.setOutputValueClass(IntWritable.class);
          job.setMapperClass(MyMap.class);
          job.setCombinerClass(MyReduce.class);
          job.setReducerClass(MyReduce.class);
          job.setInputFormatClass(TextInputFormat.class);
          job.setOutputFormatClass(TextOutputFormat.class);
          FileInputFormat.addInputPath(job, new Path(args[0]));//设置输入文件路径 
          FileOutputFormat.setOutputPath(job, new Path(args[1]));//设置输出文件路径
          boolean success=  job.waitForCompletion(true);
          
          return success ? 0 : 1;
          
    }
   public static void main(String[] args) throws Exception {
    //在eclipse 工具上配置输入和输出参数
    int ret = ToolRunner.run(new AvgScore(), args);
    System.exit(ret);
   }
@Override
public Configuration getConf() {
    return configuration;
}
@Override
public void setConf(Configuration conf) {
       conf = new Configuration();
       configuration=conf;
}
}
我在eclipse 上配置参数。会报异常。所以,我把以上代码导出成 avgscore.jar
把这个avgscore.jar 放到hadoop 0.20.2/目录下。
输入命令 ./bin/hadoop  jar avgscore.jar com/picc/test/AvgScore  input/student.txt out1

结果 图:

和计算的结果 没有错。

以下是对 以上算法的一个分析:

 package com.picc.test;

import java.io.IOException;
import java.util.Iterator;
import java.util.StringTokenizer;

import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.hbase.HBaseConfiguration;
import org.apache.hadoop.hbase.client.HTable;
import org.apache.hadoop.hbase.client.Put;
import org.apache.hadoop.hbase.util.Bytes;
import org.apache.hadoop.io.IntWritable;
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 org.apache.hadoop.util.Tool;
import org.apache.hadoop.util.ToolRunner;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.picc.mapreducetest.MyMapReduceTest;

public class AvgScore implements Tool{
    public static final Logger log=LoggerFactory.getLogger(AvgScore.class);
    Configuration configuration;
    
    public static class MyMap extends Mapper<Object, Text, Text, IntWritable>{
        Configuration config = HBaseConfiguration.create();//获取hbase 的操作上下文
        private static IntWritable linenum = new IntWritable(1);//初始化一个变量值
        @Override
        protected void map(Object key, Text value, Context context) throws IOException, InterruptedException {
            String stuInfo = value.toString();
            System.out.println("studentInfo:"+stuInfo);
            log.info("MapSudentInfo:"+stuInfo);
            StringTokenizer tokenizerArticle = new StringTokenizer(stuInfo, "\n");
            while(tokenizerArticle.hasMoreTokens()){
                StringTokenizer tokenizer = new StringTokenizer(tokenizerArticle.nextToken());
                String name = tokenizer.nextToken();
                String score = tokenizer.nextToken();
                Text stu = new Text(name);
                int intscore = Integer.parseInt(score);
                log.info("MapStu:"+stu.toString()+" "+intscore);
                context.write(stu,new IntWritable(intscore));  //zs 90
                //create 'stu','name','score'
                HTable table=new HTable(config,"stu");
                byte[] row1 = Bytes.toBytes("name"+linenum);
                Put p1=new Put(row1);
                byte[] databytes = Bytes.toBytes("name");
                p1.add(databytes, Bytes.toBytes("1"), Bytes.toBytes(name));
                table.put(p1);//put 'stu','name','name:1','zs'
                table.flushCommits();
                
                byte [] row2 = Bytes.toBytes("score"+linenum);
                Put p2 = new Put(row2);
                byte [] databytes2 = Bytes.toBytes("score");
                p2.add(databytes2, Bytes.toBytes("1"), Bytes.toBytes(score));
                table.put(p2);//put 'stu','score','score:1','90'
                table.flushCommits();
                linenum= new IntWritable(linenum.get()+1);//对变量值进行变值处理
            }
        }
        
    }
    public static class MyReduce extends Reducer<Text, IntWritable, Text, IntWritable>{

        @Override
        protected void reduce(Text key, Iterable<IntWritable> values,Context context)
                throws IOException, InterruptedException {
            int sum=0;
            int count=0;
            Iterator<IntWritable> iterator=    values.iterator();
            while(iterator.hasNext()){
                sum+=iterator.next().get();
                count++;
            }
            int avg= (int)sum/count;
            context.write(key,new  IntWritable(avg));
        }
        
    }
    public  int run(String [] args) throws Exception{
        
          Job job = new Job(getConf());
          job.setJarByClass(AvgScore.class);
          job.setJobName("avgscore");
          job.setOutputKeyClass(Text.class);
          job.setOutputValueClass(IntWritable.class);
          job.setMapperClass(MyMap.class);
          job.setCombinerClass(MyReduce.class);
          job.setReducerClass(MyReduce.class);
          job.setInputFormatClass(TextInputFormat.class);
          job.setOutputFormatClass(TextOutputFormat.class);
          FileInputFormat.addInputPath(job, new Path(args[0]));
          FileOutputFormat.setOutputPath(job, new Path(args[1]));
          boolean success=  job.waitForCompletion(true);
          
          return success ? 0 : 1;
          
    }
   public static void main(String[] args) throws Exception {
    
    int ret = ToolRunner.run(new AvgScore(), args);
    System.exit(ret);
   }
@Override
public Configuration getConf() {
    return configuration;
}
@Override
public void setConf(Configuration conf) {
       conf = new Configuration();
       configuration=conf;
}
}


这个代码是对上一个代码的调试分析处理后的代码,

把map 处理的过程放到的数据库中,在MapReduce 中处理 hbase数据时,需要 把hbase 的数据包放到hadoop的lib 包下。

处理的结果,见视图:


注意,在hbase数据库中 row中的Key是不能相同的,否则会 后一条会覆盖前一条值。需要保让其唯一性。

name1 和score1 是一条数据,这两列表是一个学生的成绩,和关系型数据库不同,以列值存储,思想需要转换一下。


基于hadoop的Hive数据仓库JavaAPI简单调用的实例,关于Hive的简介在此不赘述。hive提供了三种用户接口:CLI,JDBC/ODBC和 WebUI CLI,即Shell命令行 JDBC/ODBC 是 Hive 的Java,与使用传统数据库JDBC的方式类似 WebGUI是通过浏览器访问 Hive 本文主要介绍的就是第二种用户接口,直接进入正题。 1、Hive 安装: 1)hive的安装请参考网上的相关文章,测试时只在hadoop一个节点上安装hive即可。 2)测试数据data文件'\t'分隔: 1 zhangsan 2 lisi 3 wangwu 3)将测试数据data上传到linux目录下,我放置在:/home/hadoop01/data 2、在使用 JDBC 开发 Hive 程序时, 必须首先开启 Hive 的远程服务接口。使用下面命令进行开启: Java代码 收藏代码 hive --service hiveserver >/dev/null 2>/dev/null & 我们可以通过CLI、Client、Web UI等Hive提供的用户接口来和Hive通信,但这三种方式最常用的是CLI;Client 是Hive的客户端,用户连接至 Hive Server。在启动 Client 模式的时候,需要指出Hive Server所在节点,并且在该节点启动 Hive Server。 WUI 是通过浏览器访问 Hive。今天我们来谈谈怎么通过HiveServer来操作Hive。   Hive提供了jdbc驱动,使得我们可以用Java代码来连接Hive并进行一些类关系型数据库的sql语句查询等操作。同关系型数据库一样,我们也需要将Hive的服务打开;在Hive 0.11.0版本之前,只有HiveServer服务可用,你得在程序操作Hive之前,必须在Hive安装的服务器上打开HiveServer服务,如下: 1 [wyp@localhost/home/q/hive-0.11.0]$ bin/hive --service hiveserver -p10002 2 Starting Hive Thrift Server 上面代表你已经成功的在端口为10002(默认的端口是10000)启动了hiveserver服务。这时候,你就可以通过Java代码来连接hiveserver,代码如下:
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值