• 先看一下目录结构

这里是job接口,负责参数的传递和定时的调用

下面的图是MR 程序相关的目录图片,其中MR的入口程序负责读取数据,并指定对应的Map、Reduce程序。

  • 程序的流程

首先简单的说一下,整体的流程:

  1. 首先是一个Job(定时任务),定时调用 入口程序,拼装参数。
  2. job调用 MR的入口程序,入口程序获得job传入的参数,根据参数获得所需的数据;可以去Hbase、mysql、HDFS中获取数据;这个文件会配置job名、要调用的Mapper、Reduce,添加需要的jar包
  3. 数据传入Mapper程序,Mapper程序进行数据的整合,整合完成的数据会变成:key:{value1,value2,value3,...}这个样子,所以传入Reduce的value应该是一个可迭代的参数(在这里坑了一会)。Mapper将所有的数据整合完成后,会进入Reduce程序
  4. Reduce程序,接受参数,参数类型要和Mapper的返回类型是一样的;values 的入参是 一个可迭代的类型,泛型必须与Mapper的value返回类型一致。然后根据需求进行处理。
  • 上代码

Job程序:

  1. package com.sky.cy.mapreduce.dispatch;
  2.  
  3. import com.sky.cy.mapreduce.util.BasicMapreduceJob;
  4. import com.ssports.util.LogFormat;
  5. import com.ssports.util.ToolUtil;
  6. import org.apache.commons.logging.Log;
  7. import org.apache.commons.logging.LogFactory;
  8. import org.springframework.stereotype.Component;
  9.  
  10. import java.util.Date;
  11.  
  12. /**
  13. * @描述:
  14. * @文件名: UserActionRecordStatistJob
  15. * @创建人: YangLianjun
  16. * @创建时间: 2019/4/2 9:58
  17. * @修改人:
  18. * @修改备注: Copyright 北京和信金谷科技有限公司 2019/4/2
  19. */
  20. @Component
  21. public class UserActionRecordStatistJob extends BasicMapreduceJob {
  22. public static Log log = LogFactory.getLog(UserActionRecordStatistJob.class);
  23. @Override
  24. public String[] preProcessJob(String... args) {
  25. log.info(LogFormat.formatMsg("UserActionRecordStatistJob.preProcessJob","","UserActionRecordStatistJob is start"));
  26. String statTimeStr = "";
  27. if (args != null && args.length == 1) {
  28. statTimeStr = args[0];
  29. } else {
  30. Date date = ToolUtil.addDay(new Date(), -1);
  31. String statTime = ToolUtil.getDateStr(date, "yyyyMMdd");
  32. // String statTime = "20190401";
  33. log.info(LogFormat.formatMsg("UserActionRecordStatistJob.preProcessJob","statTime:"+statTime,""));
  34. statTimeStr = statTime;
  35. }
  36.  
  37. String[] retArgs = new String[2];
  38. // 这个参数是指定哪个 MR入口程序
  39. retArgs[0] = "com.sky.cy.mapreduce.job.UserActionRecordStatistMR" ;
  40. retArgs[1] = statTimeStr;
  41. return retArgs;
  42. }
  43. }

MR入口程序,负责数据的读取,指定对应的Map、Reduce程序:

  1. package com.sky.cy.mapreduce.job;
  2.  
  3. import com.sky.cy.mapreduce.job.mapper.UserActionRecordMapper;
  4. import com.sky.cy.mapreduce.job.mapper.UserActionRecordStatistMapper;
  5. import com.sky.cy.mapreduce.job.reducer.UserActionRecordReducer;
  6. import com.sky.cy.mapreduce.job.reducer.UserActionRecordStatistReducer;
  7. import com.sky.cy.mapreduce.util.BasicMapreduce;
  8. import com.ssports.util.LogFormat;
  9. import org.apache.commons.logging.Log;
  10. import org.apache.commons.logging.LogFactory;
  11. import org.apache.hadoop.conf.Configuration;
  12. import org.apache.hadoop.fs.Path;
  13. import org.apache.hadoop.hbase.client.Scan;
  14. import org.apache.hadoop.hbase.filter.*;
  15. import org.apache.hadoop.hbase.mapreduce.MultiTableOutputFormat;
  16. import org.apache.hadoop.hbase.mapreduce.TableMapReduceUtil;
  17. import org.apache.hadoop.hbase.util.Bytes;
  18. import org.apache.hadoop.io.Text;
  19. import org.apache.hadoop.mapreduce.Job;
  20.  
  21. import java.io.IOException;
  22.  
  23. /**
  24. * @描述:
  25. * @文件名: UserActionRecordStatistMR
  26. * @创建人: YangLianjun
  27. * @创建时间: 2019/4/2 14:47
  28. * @修改人:
  29. * @修改备注: Copyright 北京和信金谷科技有限公司 2019/4/2
  30. */
  31. public class UserActionRecordStatistMR extends BasicMapreduce {
  32. public static final Log LOG = LogFactory.getLog(UserActionRecordStatistMR.class);
  33.  
  34. public static void main(String[] args) throws IOException, ClassNotFoundException, InterruptedException {
  35. LOG.info(LogFormat.formatMsg("UserActionRecordStatistMR.main","","start ..."));
  36. init();
  37. String statTime = args[0];
  38. // 将日期作为查询条件
  39. Filter filter = new SingleColumnValueFilter(Bytes.toBytes("f"),Bytes.toBytes("stat_time"), CompareFilter.CompareOp.EQUAL,Bytes.toBytes(statTime)) ;
  40. Scan scan = new Scan();
  41. scan.setFilter(filter);
  42.  
  43. Configuration configuration = defaultHbaseConfiguration();
  44. configuration.set("statTime",statTime);
  45.  
  46. Job job = Job.getInstance(configuration, "UserActionRecordStatistMR");
  47.  
  48. TableMapReduceUtil.initTableMapperJob(UserActionRecordStatistMR.Constants.HBASE_FILTER_TABLE, scan, UserActionRecordStatistMapper.class, Text.class, Text.class, job);
  49. job.setReducerClass(UserActionRecordStatistReducer.class);
  50. job.setNumReduceTasks(1);
  51. job.setOutputFormatClass(MultiTableOutputFormat.class);
  52. //添加mysql驱动包
  53. job.addFileToClassPath(new Path(UserActionMR.Constants.MYSQL_JAR_PATH));
  54. //添加spring的jar
  55. job.addFileToClassPath(new Path(ActionFilterStatistMR.Constants.SPRING_CONTEXT_JAR_PATH));
  56. job.addFileToClassPath(new Path(ActionFilterStatistMR.Constants.SPRING_TX_JAR_PATH));
  57. job.addFileToClassPath(new Path(ActionFilterStatistMR.Constants.SPRING_AOP_JAR_PATH));
  58. job.addFileToClassPath(new Path(ActionFilterStatistMR.Constants.SPRING_BEAN_HADOOP_PATH));
  59. job.addFileToClassPath(new Path(ActionFilterStatistMR.Constants.SPRING_DATA_HADOOP_PATH));
  60.  
  61. job.waitForCompletion(true);
  62.  
  63. }
  64.  
  65. public static class Constants {
  66. //需要获取的hbase数据的表名
  67. public static final String HBASE_FILTER_TABLE = "sky_user_action_record";
  68. }
  69.  
  70. }

Map程序:

  1. package com.sky.cy.mapreduce.job.mapper;
  2.  
  3. import com.sky.cy.mapreduce.util.HbaseUtil;
  4. import com.sky.cy.mapreduce.util.RegexUtil;
  5. import com.ssports.util.LogFormat;
  6. import com.ssports.util.SpringHelper;
  7. import com.ssports.util.ToolUtil;
  8. import org.apache.commons.logging.Log;
  9. import org.apache.commons.logging.LogFactory;
  10. import org.apache.hadoop.hbase.client.Result;
  11. import org.apache.hadoop.hbase.io.ImmutableBytesWritable;
  12. import org.apache.hadoop.hbase.mapreduce.TableMapper;
  13. import org.apache.hadoop.io.Text;
  14.  
  15. import java.io.IOException;
  16.  
  17. /**
  18. * @描述:
  19. * @文件名: UserActionRecordStatistMapper
  20. * @创建人: YangLianjun
  21. * @创建时间: 2019/4/2 14:46
  22. * @修改人:
  23. * @修改备注: Copyright 北京和信金谷科技有限公司 2019/4/2
  24. */
  25. public class UserActionRecordStatistMapper extends TableMapper<Text, Text> {
  26. private static final Log log = LogFactory.getLog(UserActionRecordStatistMapper.class);
  27. public static final String FAMILY_F = "f";
  28.  
  29. protected void map(ImmutableBytesWritable key, Result result, Context context) throws IOException, InterruptedException {
  30. log.info(LogFormat.formatMsg("UserActionRecordStatistMapper.map", "", "mapper start ..."));
  31. String userId = HbaseUtil.getValue(FAMILY_F, "user_id", result);
  32. String actionName = HbaseUtil.getValue(FAMILY_F,"action_name",result) ;
  33. String actionId = HbaseUtil.getValue(FAMILY_F,"action_id",result) ;
  34. String statTime = context.getConfiguration().get("statTime");
  35. String keyOut = userId + ":" + statTime;
  36. log.info(LogFormat.formatMsg("UserActionRecordStatistMapper.map", "keyOut:"+keyOut, ""));
  37. Text text = new Text(keyOut);
  38. String valueOut = actionId + ":"+actionName;
  39. log.info(LogFormat.formatMsg("UserActionRecordStatistMapper.map", "valueOut:"+valueOut, ""));
  40. Text value = new Text(valueOut);
  41. context.write(text, value);
  42. log.info(LogFormat.formatMsg("UserActionRecordStatistMapper.map", "", "mapper end ..."));
  43. }
  44. }

Reduce程序:

  1. package com.sky.cy.mapreduce.job.reducer;
  2.  
  3. import com.sky.cy.log.base.dao.SkyUserActionRecordStatistMapper;
  4. import com.ssports.util.LogFormat;
  5. import com.ssports.util.SpringHelper;
  6. import com.ssports.util.ToolUtil;
  7. import org.apache.commons.logging.Log;
  8. import org.apache.commons.logging.LogFactory;
  9. import org.apache.hadoop.hbase.mapreduce.TableReducer;
  10. import org.apache.hadoop.io.NullWritable;
  11. import org.apache.hadoop.io.Text;
  12.  
  13. import java.io.IOException;
  14. import java.util.*;
  15.  
  16. /**
  17. * @描述:
  18. * @文件名: UserActionRecordStatistReducer
  19. * @创建人: YangLianjun
  20. * @创建时间: 2019/4/2 14:47
  21. * @修改人:
  22. * @修改备注: Copyright 北京和信金谷科技有限公司 2019/4/2
  23. */
  24. public class UserActionRecordStatistReducer extends TableReducer<Text, Text, NullWritable> {
  25. private static final Log log = LogFactory.getLog(UserActionRecordStatistReducer.class);
  26. private static final Integer ALL = 1 ; // 统计状态,全部统计
  27.  
  28. protected void setup(Context context) throws IOException, InterruptedException {
  29. SpringHelper.init("classpath*:spring/*.xml");
  30. }
  31.  
  32. protected void reduce(Text key, Iterable<Text> values, Context context){
  33. log.info(LogFormat.formatMsg("UserActionRecordStatistReducer.reduce","","start ..."));
  34. String keyRow = new String(key.getBytes());
  35. String[] keys = keyRow.split(":");
  36. String userId = keys[0] ;
  37. log.info(LogFormat.formatMsg("UserActionRecordStatistReducer.reduce","userId:"+userId,""));
  38. String statTime = keys[1] ;
  39. log.info(LogFormat.formatMsg("UserActionRecordStatistReducer.reduce", "key:"+keyRow, ""));
  40. List<String> actionList = new ArrayList<>();
  41. for (Text value : values) {
  42. log.info(LogFormat.formatMsg("UserActionRecordStatistReducer.reduce", "value:"+value.toString(), ""));
  43. actionList.add(value.toString()) ;
  44. }
  45. SkyUserActionRecordStatistMapper mapper = SpringHelper.getBean("skyUserActionRecordStatistMapper") ;
  46. com.sky.cy.log.base.bean.SkyUserActionRecordStatistEntity entity = new com.sky.cy.log.base.bean.SkyUserActionRecordStatistEntity() ;
  47.  
  48. Set<String> uniqueSet = new HashSet<>(actionList) ;
  49. for (String s : uniqueSet) {
  50. String actionId = s.split(":")[0] ;
  51. log.info(LogFormat.formatMsg("UserActionRecordStatistReducer.reduce","actionId:"+actionId,""));
  52. String actionName = s.split(":")[1] ;
  53. int actionNumber = Collections.frequency(actionList, s) ; //统计出来数量
  54. entity = mapper.selectTotalByIdAndType(userId,actionId,ALL) ; //查询全部统计 的信息
  55. if (null == entity){ //不存在 这个信息,插入
  56. log.info(LogFormat.formatMsg("UserActionRecordStatistReducer.reduce","","insert start ..."));
  57. com.sky.cy.log.base.bean.SkyUserActionRecordStatistEntity entity1 = new com.sky.cy.log.base.bean.SkyUserActionRecordStatistEntity() ;
  58. entity1.setUserId(userId);
  59. entity1.setActionId(actionId);
  60. entity1.setActionName(actionName);
  61. entity1.setStatistTotal(actionNumber);
  62. entity1.setStatistTime(statTime);
  63. entity1.setStatistType(ALL);
  64. int insert = mapper.insertSelective(entity1) ;
  65. log.info(LogFormat.formatMsg("UserActionRecordStatistReducer.reduce","insert number:"+insert,""));
  66. }else { //存在,进行更新
  67. log.info(LogFormat.formatMsg("UserActionRecordStatistReducer.reduce","","update start..."));
  68. int update = mapper.updateTotalAndDays(userId,actionId,actionNumber,ALL) ; //更新
  69. log.info(LogFormat.formatMsg("UserActionRecordStatistReducer.reduce","update number:"+update,"update end..."));
  70. }
  71. }
  72.  
  73. }
  74. }

说明:

利用集群进行整合、计算、归纳,本身是一个特别复杂的事情,Hadoop中的MR框架可以让我们从复杂的操作中解脱出来,只关注于逻辑本身,无疑是程序员的福音。只要理解了MR的流程和基本的运作原理,就可以像写java程序那样简单的对数据进行处理,但是却比单机的java程序效率高得多。当然既然使用到了MR,数据量应该是巨大的,如果只是对单机mysql中的数据进行统计与计算,建议还是使用普通的方式,毕竟最适合自己才是最好的!!!

MapReduce编写的正确姿势的更多相关文章

  1. (转)Git 提交的正确姿势:Commit message 编写指南

    Git 每次提交代码,都要写 Commit message(提交说明),否则就不允许提交. $ git commit -m "hello world" 上面代码的-m参数,就是用来 ...

  2. 开发函数计算的正确姿势 —— 使用 Fun Local 本地运行与调试

    前言 首先介绍下在本文出现的几个比较重要的概念: 函数计算(Function Compute): 函数计算是一个事件驱动的服务,通过函数计算,用户无需管理服务器等运行情况,只需编写代码并上传.函数计算 ...

  3. Git 提交的正确姿势

    Git 提交的正确姿势:Commit message 编写指南 SCOP范围 middleware core config plugin test type范围 Git 每次提交代码,都要写 Comm ...

  4. IphoneX适配正确姿势

    IphoneX适配正确姿势 写在前面 距离18年9月iphonex发布以来已经快两年了(所以对于iphonex机型的头部刘海(sensor housing)和底部小黑条(Home Indicator) ...

  5. 判断是否为gif/png图片的正确姿势

    判断是否为gif/png图片的正确姿势 1.在能取到图片后缀的前提下 1 2 3 4 5 6 7 8 9 //假设这是一个网络获取的URL NSString *path = @"http:/ ...

  6. 在Linux(ubuntu server)上面安装NodeJS的正确姿势

    上一篇文章,我介绍了 在Windows中安装NodeJS的正确姿势,这一篇,我们继续来看一下在Linux上面安装和配置NodeJS. 为了保持一致,这里也列举三个方法 第一个方法:通过官网下载安装 h ...

  7. 程序员取悦女朋友的正确姿势---Tips(iOS美容篇)

    前言 女孩子都喜欢用美图工具进行图片美容,近来无事时,特意为某人写了个自定义图片滤镜生成器,安装到手机即可完成自定义滤镜渲染照片.app独一无二,虽简亦繁. JH定律:魔镜:最漂亮的女人是你老婆魔镜: ...

  8. ios监听ScrollView/TableView滚动的正确姿势

    主要介绍 监测tableView垂直滚动的舒畅姿势 监测scrollView/collectionView横向滚动的正确姿势 1.监测tableView垂直滚动的舒畅姿势 通常我们用KVO或者在scr ...

  9. 玩转 Ceph 的正确姿势

    玩转 Ceph 的正确姿势 本文先介绍 Ceph, 然后会聊到一些正确使用 Ceph 的姿势:在集群规模小的时候,Ceph 怎么玩都没问题:但集群大了(到PB级别),这些准则可是保证集群健康运行的不二 ...

随机推荐

  1. c++多线程编程(三)

    关于WaitForSingleObject函数用法 : 用户模式的线程同步机制效率高,如果需要考虑线程同步问题,应该首先考虑用户模式的线程同步方法. 但是,用户模式的线程同步有限制,对于多个进程之间的 ...

  2. FZU2282 Wand

    题意 n个数字,要求至少k个数字位置不变,其余进行错排的方案数 分析 错排公式: D(n)=(n-1)[D(n-2)+D(n-1)]  如果n个数字,i个数字位置不变,其余进行错排的的方案数是C(n, ...

  3. codeforce453DIV2——D. GCD of Polynomials

    题意 给出n(1–150). 输出两个多项式A,B从常数到最高次的系数,使得对两个多项式求gcd时,恰好经过n步得到结果. 多项式的gcd一步是指(A(x),B(x))变成(B,A mod B)的过程 ...

  4. codeforce469DIV2——C. Zebras

    题意 0, 010, 01010 这一类的01交替且开头和结尾都为0的序列被称为zebra序列.给出一段01序列,尝试能否把他分为k个子序列使得每个子序列都是zebra序列. 分析 这个题应该算是水题 ...

  5. 8.INSERT INTO 语句 UPDATE 语句

    1. INSERT INTO 语句 INSERT INTO 语句用于向表格中插入新的行. 语法 INSERT INTO 表名称 VALUES (值1, 值2,....) INSERT INTO Per ...

  6. Yii2视频

    Yii2 视频分享 需要的小伙伴看过来链接: https://pan.baidu.com/s/1sl4H0RV 密码: nknx  (有问题请留言)

  7. HttpUploader7-授权码配置

    1.1. 七牛云存储 配置方式: 1.配置授权码   2.配置云存储   3.配置空间名称   4.配置上传地址   1.2. 阿里云存储 配置方式: 1.填写授权码   2.配置云存储为阿里云   ...

  8. 策略与计费控制规则(Policy and Charging Control Rule-PCC Rule)解析及模板样例

    内容 PCC规则定义 PCC规则运行 PCC规则模板 PCC规则定义 参考文档: 3gpp ts 23.203-be0 条款6.3 策略与计费控制规则(PCC Rule),即一系列相关信息与一系列相关 ...

  9. 常用Linux命令:mount/umount/blkid

    一.mount:挂载命令 1.命令格式 mount [参数] [设备名称] [挂载点] 2.常用参数 -a     :安装在/etc/fstab文件中列出的所有文件系统 -f :伪装mount,做出检 ...

  10. .net core MVC Filters 过滤器介绍

    一.过滤器的优级依次介绍如下(逐次递减): Authorization Filter ->  Resource Filter -> Acton Filter -> Exception ...