Hive UDF使用資源文件及動態更新方案--後記

Hive UDF使用資源文件及動態更新方案–後記

Hive UDF使用資源文件及動態更新方案 一文中,針對UDF動態更新的問題,提出解決方案:UDF僅使用業務接口,初始化時動態從位於HDFS的Jar文件中加載業務接口實現類;其中,業務接口及實現類與UDF一一對應。

通常情況下,業務接口僅包含一個方法(Method),方法的定義也比較簡單,支持傳入若干參數及一個返回值即可。實踐過程中,逐漸發現爲每一個UDF提供相應的業務接口/實現類的設計有點 冗餘。開始思考是否可以設計一個公用的業務接口?

不同的業務接口本質上有什麼不同呢?這裏的不同主要是針對業務接口中的方法來定義的,如下:

  1. 方法名稱不同;
  2. 方法參數個數、類型不同;
  3. 方法返回值類型不同;

公用的業務接口使用相同的方法名稱是沒有問題的,因爲具體的實現類不同,方法的計算邏輯也就不同;方法參數及返回值的類型,我們可以使用 Object 替代;如此來看,業務接口的不同僅僅體現在方法參數個數不同這一點上面。

UDF是通過我們常說的 函數 的形式在Hive/Spark SQL的場景下使用的,根據我們的經驗可以知道,實際使用時函數的參數個數不會太多,我們假設:10。

PS: 如果對 10 這個假設有疑問,大家試想一下見過多少個SQL 函數的參數個數是大於10的呢?

於是,我們設計了UdfMethod,用於替換業務接口,

package com.weibo.dip.udf.common;

import com.google.common.base.Preconditions;
import java.io.IOException;
import java.io.InputStream;
import java.io.SequenceInputStream;
import java.util.List;
import java.util.Objects;
import java.util.Vector;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang.ArrayUtils;
import org.apache.commons.lang.CharEncoding;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.FileStatus;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * UdfMethod.
 *
 * @author yurun
 */
public abstract class UdfMethod {
  private static final Logger LOGGER = LoggerFactory.getLogger(UdfMethod.class);

  public Object m0() {
    return null;
  }

  public Object m1(Object p1) {
    return p1;
  }

  public Object m2(Object p1, Object p2) {
    return null;
  }

  public Object m3(Object p1, Object p2, Object p3) {
    return null;
  }

  public Object m4(Object p1, Object p2, Object p3, Object p4) {
    return null;
  }

  public Object m5(Object p1, Object p2, Object p3, Object p4, Object p5) {
    return null;
  }

  public Object m6(Object p1, Object p2, Object p3, Object p4, Object p5, Object p6) {
    return null;
  }

  public Object m7(Object p1, Object p2, Object p3, Object p4, Object p5, Object p6, Object p7) {
    return null;
  }

  public Object m8(
      Object p1, Object p2, Object p3, Object p4, Object p5, Object p6, Object p7, Object p8) {
    return null;
  }

  public Object m9(
      Object p1,
      Object p2,
      Object p3,
      Object p4,
      Object p5,
      Object p6,
      Object p7,
      Object p8,
      Object p9) {
    return null;
  }

  public Object m10(
      Object p1,
      Object p2,
      Object p3,
      Object p4,
      Object p5,
      Object p6,
      Object p7,
      Object p8,
      Object p9,
      Object p10) {
    return null;
  }
}

UdfMethod是一個抽象類(抽象類主要用於表示不能直接使用,需要相應的實現類),包含10個方法(方法全部包含默認實現):m0、m1、…、m10;方法名稱中的數字用於表示參數個數,且方法參數及返回值類型均使用 Object 表示。

實際使用時僅需要根據具體情況(根據參數個數決定),重寫實現類中相應參數個數的方法即可。UdfMethod使用及動態加載過程與業務接口相同。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章