Hive UDTF 接受參數及Redis連接問題

hive-exec-2.7.3版本中最通用的方法,所有的類型都可以接收。

ObjectInspector[] inputIOS;
public StructObjectInspector initialize(ObjectInspector[] args) {
    this.inputIOS = args;
}
public void process(Object[] o) {
    Object obj = ((PrimitiveObjectInspector)inputIOs[i]).getPrimitiveJavaObject(o[i]);
    String input = obj.toString();
    // 然後將input轉換正任何想要的類型
}

 

 

1、UDTF中process方法會被執行多次,是串行執行的,close方法只會執行一次。

2、可以定義實例範圍的局部變量,不需要考慮線程安全問題。但是由於運行中UDTF會多次實例化,所以就會有很多個連接。實測100萬數據大概會有100個實例,也就會有100個連接,process執行10s以內,整個函數運行46s。

3、如果想要降低連接數,就要使用類範圍的全部靜態變量,所以需要加鎖,無論如何,肯定會影響性能。

(1)JedisPool,整體耗時增加至256s。

(2)單例加鎖,整體耗時大約也要300s左右。

(3)自定義隊列,長度100,初始化10,整體耗時54s。

4、代碼
 

public class MyUDTF extends GenericUDTF {
    @Override
    public StructObjectInspector initialize(ObjectInspector[] argOIs)
        throws UDFArgumentException {
    
    }
    @Override
    public void process(Object[] args) throws HiveException {
    /******************************方法1*******************************/
        getJedis().get("key");
    /******************************方法2*******************************/
        Jedis jedis = getJedis();
        jedis.get("key");
        returnJedis(jedis);
    /******************************方法3*******************************/
        Jedis jedis = getJedis();
        jedis.get("key");
        returnJedis(jedis);
    }

    @Override
    public void close() throws HiveException {
    /******************************方法1*******************************/
        returnJedis(jedis);
    /******************************方法2*******************************/
        // do nothing:無法在close時釋放資源,在後續實例化中仍然需要使用。
    /******************************方法3*******************************/
        // do nothing:無法在close時釋放資源,在後續實例化中仍然需要使用。
    }
    /******************************方法1*******************************/
    private Jedis jedis = null;
    private Jedis getJedis() {
        if(null == Jedis) {
            jedis = new Jedis("127.0.0.1", 6379);
        }
        return jedis;
    }
    private static void returnJedis(Jedis jedis) {
        if(null != jedis) {
            jedis.close();
        }
    }
    /******************************方法2*******************************/
    private static final JedisPool pool;
    static {
        JedisPoolConfig config = new JedisPoolConfig();
        config.setMaxTotal(10);
        config.setMinIdle(0);
        config.setTestOnBorrow(false);
        config.setTestOnCreate(false);
        config.setTestOnReturn(false);
        pool = new JedisPool(config, "127.0.0.1", 6379);
    }
    private static Jedis getJedis() {
        return pool.getResource();
    }
    private static void returnJedis(Jedis jedis) {
        if(null != jedis) {
            jedis.close();
        }
    }
    /******************************方法3*******************************/
    private static final LinkedBlockingQueue<Jedis> queue;
    static {
        int n = 10;
        queue = new LinkedBlockingQueue<>(10 * n);
        Jedis jedis;
        for(int i = 0; i < n; i++) {
            jedis = createJedis();
            returnJedis(jedis);
        }
    }
    private static Jedis getJedis() {
        Jedis jedis = null;
        try {
            jedis = queue.poll(1, TimeUnit.MICROSECONDS);
        } catch(Exception e) {
            // log
        }
        if (null == jedis) {
            jedis = createJedis();
        }
        return jedis;
    }
    private static void returnJedis(Jedis jedis) {
        if(!queue.offer(jedis)) {
            // log
        }
    }
    private static void createJedis(Jedis jedis) {
        jedis = new Jedis("127.0.0.1", 6379);
        return jedis;
    }
}

 

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