Details
Description
beeline can't get the correct hiveserver2 using the zoopkeeper with serviceDiscoveryMode=zooKeeper.
// code placeholder [root@vhost-120-28 hive]# beeline -u "jdbc:hive2://vhost-120-26:2181,vhost-120-27:2181,vhost-120-28:2181/;serviceDiscoveryMode=zooKeeper;zooKeeperNamespace=hiveserver2" --verbose=true SLF4J: Class path contains multiple SLF4J bindings. SLF4J: Found binding in [jar:file:/usr/wdp/1.0/hive/lib/log4j-slf4j-impl-2.10.0.jar!/org/slf4j/impl/StaticLoggerBinder.class] SLF4J: Found binding in [jar:file:/usr/wdp/1.0/hadoop/lib/slf4j-log4j12-1.7.25.jar!/org/slf4j/impl/StaticLoggerBinder.class] SLF4J: See http://www.slf4j.org/codes.html#multiple_bindings for an explanation. SLF4J: Actual binding is of type [org.apache.logging.slf4j.Log4jLoggerFactory] !connect jdbc:hive2://vhost-120-26:2181,vhost-120-27:2181,vhost-120-28:2181/;serviceDiscoveryMode=zooKeeper;zooKeeperNamespace=hiveserver2 '' [passwd stripped] Connecting to jdbc:hive2://vhost-120-26:2181,vhost-120-27:2181,vhost-120-28:2181/;serviceDiscoveryMode=zooKeeper;zooKeeperNamespace=hiveserver2 Error: org.apache.hive.jdbc.ZooKeeperHiveClientException: Unable to read HiveServer2 configs from ZooKeeper (state=,code=0) java.sql.SQLException: org.apache.hive.jdbc.ZooKeeperHiveClientException: Unable to read HiveServer2 configs from ZooKeeper at org.apache.hive.jdbc.HiveConnection.<init>(HiveConnection.java:170) at org.apache.hive.jdbc.HiveDriver.connect(HiveDriver.java:107) at java.sql.DriverManager.getConnection(DriverManager.java:664) at java.sql.DriverManager.getConnection(DriverManager.java:208) at org.apache.hive.beeline.DatabaseConnection.connect(DatabaseConnection.java:145) at org.apache.hive.beeline.DatabaseConnection.getConnection(DatabaseConnection.java:209) at org.apache.hive.beeline.Commands.connect(Commands.java:1641) at org.apache.hive.beeline.Commands.connect(Commands.java:1536) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:498) at org.apache.hive.beeline.ReflectiveCommandHandler.execute(ReflectiveCommandHandler.java:56) at org.apache.hive.beeline.BeeLine.execCommandWithPrefix(BeeLine.java:1384) at org.apache.hive.beeline.BeeLine.dispatch(BeeLine.java:1423) at org.apache.hive.beeline.BeeLine.connectUsingArgs(BeeLine.java:900) at org.apache.hive.beeline.BeeLine.initArgs(BeeLine.java:795) at org.apache.hive.beeline.BeeLine.begin(BeeLine.java:1048) at org.apache.hive.beeline.BeeLine.mainWithInputRedirection(BeeLine.java:538) at org.apache.hive.beeline.BeeLine.main(BeeLine.java:520) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:498) at org.apache.hadoop.util.RunJar.run(RunJar.java:323) at org.apache.hadoop.util.RunJar.main(RunJar.java:236) Caused by: org.apache.hive.jdbc.ZooKeeperHiveClientException: Unable to read HiveServer2 configs from ZooKeeper at org.apache.hive.jdbc.ZooKeeperHiveClientHelper.configureConnParams(ZooKeeperHiveClientHelper.java:147) at org.apache.hive.jdbc.Utils.configureConnParamsFromZooKeeper(Utils.java:511) at org.apache.hive.jdbc.Utils.parseURL(Utils.java:334) at org.apache.hive.jdbc.HiveConnection.<init>(HiveConnection.java:168) ... 25 more
You know, HiveServer2#startPrivilegeSynchronizer will create the namespace of /hiveserver2/leader in the zookeeper,
however, if you want to connect to the hiveserver2 using beeline with the command like "jdbc:hive2://vhost-120-26:2181,vhost-120-27:2181,vhost-120-28:2181/;serviceDiscoveryMode=zooKeeper;zooKeeperNamespace=hiveserver2", the beeline will randomly chose the sub-namespace under /hiveserver2.
That arises a problem that the beeline will not find the hiveserver2 information in the namespace of /hiveserver2/leader, it's impossible to detect the hiveserver2 connection information.
That's to say, the sub-namespace of /hiveserver2 is like this:
[zk: vhost-120-28:2181,vhost-120-27:2181,vhost-120-26:2181(CONNECTED) 1] ls /hiveserver2
[leader, serverUri=vhost-120-26:10000;version=3.1.2;sequence=0000000010, serverUri=vhost-120-28:10000;version=3.1.2;sequence=0000000011]
Codes list bellow show HiveServer2#startPrivilegeSynchronizer and beeline how to connect the hiveserver2.
HiveServer2#startPrivilegeSynchronizer:
public void startPrivilegeSynchronizer(HiveConf hiveConf) throws Exception {
if (!HiveConf.getBoolVar(hiveConf, ConfVars.HIVE_PRIVILEGE_SYNCHRONIZER)) {
return;
}
PolicyProviderContainer policyContainer = new PolicyProviderContainer();
HiveAuthorizer authorizer = SessionState.get().getAuthorizerV2();
if (authorizer.getHivePolicyProvider() != null) {
policyContainer.addAuthorizer(authorizer);
}
if (MetastoreConf.getVar(hiveConf, MetastoreConf.ConfVars.PRE_EVENT_LISTENERS) != null &&
MetastoreConf.getVar(hiveConf, MetastoreConf.ConfVars.PRE_EVENT_LISTENERS).contains(
"org.apache.hadoop.hive.ql.security.authorization.AuthorizationPreEventListener") &&
MetastoreConf.getVar(hiveConf, MetastoreConf.ConfVars.HIVE_AUTHORIZATION_MANAGER)!= null) {
List<HiveMetastoreAuthorizationProvider> providers = HiveUtils.getMetaStoreAuthorizeProviderManagers(
hiveConf, HiveConf.ConfVars.HIVE_METASTORE_AUTHORIZATION_MANAGER, SessionState.get().getAuthenticator());
for (HiveMetastoreAuthorizationProvider provider : providers) {
if (provider.getHivePolicyProvider() != null) {
policyContainer.addAuthorizationProvider(provider);
}
}
}
if (policyContainer.size() > 0) {
setUpZooKeeperAuth(hiveConf);
zKClientForPrivSync = hiveConf.getZKConfig().startZookeeperClient(zooKeeperAclProvider, true);
String rootNamespace = hiveConf.getVar(HiveConf.ConfVars.HIVE_SERVER2_ZOOKEEPER_NAMESPACE);
String path = ZooKeeperHiveHelper.ZOOKEEPER_PATH_SEPARATOR + rootNamespace
+ ZooKeeperHiveHelper.ZOOKEEPER_PATH_SEPARATOR + "leader";
LeaderLatch privilegeSynchronizerLatch = new LeaderLatch(zKClientForPrivSync, path);
privilegeSynchronizerLatch.start();
LOG.info("Find " + policyContainer.size() + " policy to synchronize, start PrivilegeSynchronizer");
Thread privilegeSynchronizerThread = new Thread(
new PrivilegeSynchronizer(privilegeSynchronizerLatch, policyContainer, hiveConf), "PrivilegeSynchronizer");
privilegeSynchronizerThread.setDaemon(true);
privilegeSynchronizerThread.start();
} else {
LOG.warn(
"No policy provider found, skip creating PrivilegeSynchronizer");
}
}
ZooKeeperHiveClientHelper#configureConnParams
static void configureConnParams(JdbcConnectionParams connParams) throws ZooKeeperHiveClientException {
if (isZkHADynamicDiscoveryMode(connParams.getSessionVars())) {
configureConnParamsHA(connParams);
} else {
CuratorFramework zooKeeperClient = null;
try {
zooKeeperClient = getZkClient(connParams);
final List<String> serverHosts = getServerHosts(connParams, zooKeeperClient);
if (serverHosts.isEmpty()) {
throw new ZooKeeperHiveClientException("No more HiveServer2 URIs from ZooKeeper to attempt");
}
// Pick a server node randomly
final String serverNode = serverHosts.get(ThreadLocalRandom.current().nextInt(serverHosts.size()));
updateParamsWithZKServerNode(connParams, zooKeeperClient, serverNode);
} catch (ZooKeeperHiveClientException zkhce) {
throw zkhce;
} catch (Exception e) {
throw new ZooKeeperHiveClientException("Unable to read HiveServer2 configs from ZooKeeper", e);
} finally {
if (zooKeeperClient != null) {
zooKeeperClient.close();
}
}
}
}
I wonder if it's ok to use /hiveserver2-leader to replace /hiveserver2/leader?