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;
}
}