HiveUdf动态设置读取HDFS上的配置文件

背景:
在hive中编写udf时,我们可能会加载外部的配置文件,可以将配置打到Jar中 ,或者读取mysql配置,或者将配置放在hdfs上。 在使用hiveCli客户端时也可以通过add file 添加资源,然后直接 new FileInputStream(“fileName”)就能加载到 ,最后这种add file 的方式测试下来只能在hiveCli客户端先能读到配置,在beeline 中无法读取到,jar或者mysql 这两种方式在这里不讨论,主要记录下配置放在hdfs 时的处理方式 。

代码
1.首先我们在这里实现udf 时采用的是 GenericUDF 接口
2.重写实现以下方法
3.这里是为了实现可以自定义或者动态传入hdfs上配置文件的路径,而不是写死在Jar中,如下中 sensword.file.path 是通过 -hiveconf 传递进来的,或者可以在开启beeline 后 自行 set sensword.file.path=xxx,这里有一点需要注意的是hive 在set 自定义变量时需要做一些单独的配置,否则在set或者-hiveconf时将会报错,另外还需要注意的是 自定义的变量 不要使用 hive开头 即不能是:hive.sensword.file.path ,这里在set时hive 是禁止的(会报错 not exists 类似的信息):

HiveUdf动态设置读取HDFS上的配置文件_第1张图片

   //这里重写configure 方法 通过此方法 获取到自动注入的  MapredContext 类 
   //通过context 我们可以获取到外部传入的配置即:-hiveconf 传入的变量值
   //注意:hivevar在这里是不会获取的
    @Override
    public void configure(MapredContext context) {
        this.context = context;
    }

   //这里主要是对函数进行初始化  定义函数返回值类型等
   //在这里我们可以使用上面拿到的context 来获取传入的hiveconf值,但是这里有一点要注意 configure 方法只有在
   //启动mr 任务时才会被调用,因此 在一些不会启动mr的情况下,这个地方也是获取不到传入的变量的,因此下面的代码中
   //会有判空,在为空情况下会使用hive 的sessionState来获取当前传入的变量,这里也要注意在mr情况下 sessionState
   //是为空的 ,因此这两部分结合起来正好可以实现在mr 与非mr 模式下的参数获取
    @Override
    public ObjectInspector initialize(ObjectInspector[] arguments) throws UDFArgumentException {
        String path = SENS_FILE_HDFS;
        if (context != null) {
            //启动mr 任务时
            JobConf jobConf = context.getJobConf();
            path = jobConf.get("sensword.file.path", SENS_FILE_HDFS);
        } else {
            //sessionstate 非mr情况下
            SessionState sessionState = SessionState.get();
            if (null != sessionState) {
                HiveConf conf = sessionState.getConf();
                path = conf.get("sensword.file.path", SENS_FILE_HDFS);
            }
        }
        logger.info("==>sensword file path: " + path);
        .......省略其他无关代码
       }

	//加载配置文件
	//注意此处不要对fileSystem 进行关闭
	//这里猜测是跟当前mr 任务共用了相同的fileSystem instance, 这里在new Configuration时不需要传入hive-site.xml 等配置,
	//会从当前环境中进行加载
	
     protected void buildSensWordSetFromHdfs(String path) throws HiveException {
        try {
            fileSystem = FileSystem.get(new Configuration());
            FSDataInputStream open = fileSystem.open(new Path(path));
            BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(open));
            String line = null;
            while (null != (line = bufferedReader.readLine())) {
                sensWord.add(line.trim().toLowerCase());
            }
            bufferedReader.close();
            open.close();
        } catch (IOException e) {
            throw new HiveException(e.getMessage());
        }
    }
       
    //这里对资源进行释放 ,切忌不要把close 放在初始化方法中,否则hive 不会输出任何结果也不会报错
    @Override
    public void close() throws IOException {
        fileSystem.close();
    }

转载请注明: https://blog.csdn.net/sinat_23257429/article/details/121830265

你可能感兴趣的:(hive,hdfs,hive,java)