部署Hive后启动HiveServer2居然抛出了以下的异常:
反复检查了配置文件,配置都是正确,就是启动失败,实在没有办法只能根据错误信息排查。
* 找到HiveConf.java-->unitFor(String unit, TimeUnit defaultUnit)方法,通过代码可以看出是因为unit这个变量都是false才抛出的异常,那么就继续看是哪里调用了这个方法。
1 public static TimeUnit unitFor(String unit, TimeUnit defaultUnit) { 2 unit = unit.trim().toLowerCase(); 3 if (unit.isEmpty()) { 4 if (defaultUnit == null) { 5 throw new IllegalArgumentException("Time unit is not specified"); 6 } 7 return defaultUnit; 8 } else if (unit.equals("d") || unit.startsWith("day")) { 9 return TimeUnit.DAYS; 10 } else if (unit.equals("h") || unit.startsWith("hour")) { 11 return TimeUnit.HOURS; 12 } else if (unit.equals("m") || unit.startsWith("min")) { 13 return TimeUnit.MINUTES; 14 } else if (unit.equals("s") || unit.startsWith("sec")) { 15 return TimeUnit.SECONDS; 16 } else if (unit.equals("ms") || unit.startsWith("msec")) { 17 return TimeUnit.MILLISECONDS; 18 } else if (unit.equals("us") || unit.startsWith("usec")) { 19 return TimeUnit.MICROSECONDS; 20 } else if (unit.equals("ns") || unit.startsWith("nsec")) { 21 return TimeUnit.NANOSECONDS; 22 } 23 throw new IllegalArgumentException("Invalid time unit " + unit); 24 }
* 通过错信息知道是HiveConf.java-->toTime(String value, TimeUnit inputUnit, TimeUnit outUnit)方法调用了unitFor方法,并且传递处理后的value值,继续看代码。
1 public static long toTime(String value, TimeUnit inputUnit, TimeUnit outUnit) { 2 String[] parsed = parseTime(value.trim()); 3 return outUnit.convert(Long.valueOf(parsed[0].trim().trim()), unitFor(parsed[1].trim(), inputUnit)); 4 }
* 通过错信息知道是HiveConf.java-->getTimeVar(Configuration conf, ConfVars var, TimeUnit outUnit)方法调用了toTiime方法,并且通过getVar(conf, var)方法传递处理后的var值,继续看代码。
1 public static long getTimeVar(Configuration conf, ConfVars var, TimeUnit outUnit) { 2 return toTime(getVar(conf, var), getDefaultTimeUnit(var), outUnit); 3 }
* getTimeVar方法被CLIServer.java-->getOperationStatus方法调用了,继续看代码。
1 public OperationStatus getOperationStatus(OperationHandle opHandle) 2 throws HiveSQLException { 3 Operation operation = sessionManager.getOperationManager().getOperation(opHandle); 4 /** 5 * If this is a background operation run asynchronously, 6 * we block for a configured duration, before we return 7 * (duration: HIVE_SERVER2_LONG_POLLING_TIMEOUT). 8 * However, if the background operation is complete, we return immediately. 9 */ 10 if (operation.shouldRunAsync()) { 11 HiveConf conf = operation.getParentSession().getHiveConf(); 12 long timeout = HiveConf.getTimeVar(conf, 13 HiveConf.ConfVars.HIVE_SERVER2_LONG_POLLING_TIMEOUT, TimeUnit.MILLISECONDS); 14 try { 15 operation.getBackgroundHandle().get(timeout, TimeUnit.MILLISECONDS); 16 } catch (TimeoutException e) { 17 // No Op, return to the caller since long polling timeout has expired 18 LOG.trace(opHandle + ": Long polling timed out"); 19 } catch (CancellationException e) { 20 // The background operation thread was cancelled 21 LOG.trace(opHandle + ": The background operation was cancelled", e); 22 } catch (ExecutionException e) { 23 // The background operation thread was aborted 24 LOG.warn(opHandle + ": The background operation was aborted", e); 25 } catch (InterruptedException e) { 26 // No op, this thread was interrupted 27 // In this case, the call might return sooner than long polling timeout 28 } 29 } 30 OperationStatus opStatus = operation.getStatus(); 31 LOG.debug(opHandle + ": getOperationStatus()"); 32 sessionManager.clearIpAddress(); 33 return opStatus; 34 }
* 在上面的方法有以下这句代码。
1 long timeout = HiveConf.getTimeVar(conf, HiveConf.ConfVars.HIVE_SERVER2_LONG_POLLING_TIMEOUT, TimeUnit.MILLISECONDS);
* 可以看到是把HiveConf.ConfVars.HIVE_SERVER2_LONG_POLLING_TIMEOUT这个参数的值传递到getTimeVar方法的,现在看看这个参数。
1 HIVE_SERVER2_LONG_POLLING_TIMEOUT("hive.server2.long.polling.timeout", "5000ms", new TimeValidator(TimeUnit.MILLISECONDS))
* 对应配置文件的hive.server2.long.polling.timeout参数,在hive-site.xml查看这个值是多少。
1 <property> 2 <name>hive.server2.long.polling.timeout</name> 3 <value>5000L</value> 4 <description>Time in milliseconds that HiveServer2 will wait, before responding to asynchronous calls that use long polling</description> 5 </property>
* 可以看到这个参数对应的值是5000L,回头看看抛出异常的方法,发现if语句的判断根本没有L这个单位,到这就明白了原来是配置文件错是一个BUG,把配置文件这个参数值单位修改为ms,问题解决。
1 <property> 2 <name>hive.server2.long.polling.timeout</name> 3 <value>5000ms</value> 4 <description>Time in milliseconds that HiveServer2 will wait, before responding to asynchronous calls that use long polling</description> 5 </property>
使用的版本是:hive-0.13.1-cdh5.2.1,已经确认后续的版本已经修复这个BUG。