• 如何向map和ruduce方法中传递外部参数


    经常会有这样的需求:

    在MR程序中,map,reduce等方法中需要传入一些外部参数,比如我们要编写MR程序访问页面访问的Top n,其中的n就是我们需要传入的外部参数。但是,map和reduce等方法都是由MapTask和RedcueTask调用的,我们编程的时候是从父类继承方法,然后override来实现我们的逻辑。所以方法的标签是不能改变的,那么,这个外部参数又该用怎样的方式传递给这些方法呢?

    那就是利用方法的一个参数,context来传递。

    先来看下这个,

    Configuration conf = new Configuration();
    conf.setInt("topn", 6);
    Job job = Job.getInstance(conf);

    这是我们编写job提交程序时的一般做法,这句话的含义是创建conf对象,对job运行时的一些参数进行配置,把该conf对象封装到job对象中,job运行的时候就会去读conf中的配置信息,conf对象可以通过Context对象获取。这样反过来我们就可以为map和reduce等方法获得外部参数啦:map方法的形参包括context对象,方法执行时通过MapTask传入该参数值,然后通过context对象我们可以获取job的conf对象,如果在conf中封装了我们要传入的外部参数,那么就可以反向获得这个参数了。

    在map或reduce方法中,通过以下方法可以得到配置参数值:

     Configuration conf = context.getConfiguration();
     int topn = conf.getInt(conf.get("topn", 5));//“topn”为要获取的参数的name,5为该参数的默认值

    这里通过context获得的conf对象,是我们项目运行的通用配置信息(其实它的作用大致相当于我们在进行集群配置时修改的core-site.xml和hdfs.xml)。那么我们又该如何把topn的值放到conf对象里去呢?

    在jobsubmitter中,conf对象创建后,通过set方法封装参数值。

    Configuration conf = new Configuration();
    conf.setInt("topn", 6);

    补充:

    其实,这里也是把参数值写死到代码中,那么我们怎么不把这个参数在代码中写死呢?比如我开始想求top5,现在想求top3。

    方法一:利用main方法在运行时传入参数。

    public class PageCountJobSubmitter {
    
        public static void main(String[] args)
                throws IOException, ClassNotFoundException, InterruptedException {
    
            Configuration conf = new Configuration();
            conf.setInt("topn", args[0]);
            Job job = Job.getInstance(conf);
                  ……
        }
    }

    方法二:通过属性配置文件获取参数

    public class PageCountJobSubmitter {
    
        public static void main(String[] args)
                throws IOException, ClassNotFoundException, InterruptedException {
    
            Configuration conf = new Configuration();
            Properties properties = new Properties();
            properties.load(PageCountJobSubmitter.class.getClassLoader().
                    getResourceAsStream("I:\CodePractice\flowcount\Topn\src\main\resources\topn.proterpties"));
            conf.setInt("topn", Integer.parseInt(properties.getProperty("topn")));
    
            ……
        }
    
    }

    方法三:通过classpath下的xml文件加载

    public class PageCountJobSubmitter {
    
        public static void main(String[] args)
                throws IOException, ClassNotFoundException, InterruptedException {
    
            Configuration conf = new Configuration();
    /*
            Properties properties = new Properties();
            properties.load(PageCountJobSubmitter.class.getClassLoader().
                    getResourceAsStream("topn.proterpties"));
            conf.setInt("topn", Integer.parseInt(properties.getProperty("topn")));
    */
            conf.addResource(new Path("I:\CodePractice\" +
                    "flowcount\Topn\src\main\java\topn.xml"));//这种绝对路径不太优雅。。。
    
    
        }
    
    }

    context里存储项目运行的上下文参数,

    方法一:

    方法二:

    方法三:

     

  • 相关阅读:
    python3中,os.path模块下常用的用法总结
    python 中str format 格式化数字补0方法
    5分钟让你明白“软链接”和“硬链接”的区别
    获得Python脚本所在目录
    sshd超时
    pip 指定源安装
    python编程规范
    Git冲突解决
    Git冲突解决
    git 更新某个目录或文件
  • 原文地址:https://www.cnblogs.com/Jing-Wang/p/10874051.html
Copyright © 2020-2023  润新知