This is an automated email from the ASF dual-hosted git repository.
zhangbutao pushed a commit to branch branch-2.3
in repository https://gitbox.apache.org/repos/asf/hive.git
The following commit(s) were added to refs/heads/branch-2.3 by this push:
new 36b32612ba0 HIVE-27172: (2.3) Add the HMS client connection timeout
config (#5115)
36b32612ba0 is described below
commit 36b32612ba0a20d3d305c77a813aca62d7129ed0
Author: Cheng Pan <[email protected]>
AuthorDate: Wed Mar 6 09:06:11 2024 +0800
HIVE-27172: (2.3) Add the HMS client connection timeout config (#5115)
---
.../hadoop/hive/common/auth/HiveAuthUtils.java | 8 ++-
.../java/org/apache/hadoop/hive/conf/HiveConf.java | 3 +
.../hadoop/hive/metastore/HiveMetaStoreClient.java | 8 ++-
.../hive/metastore/TestHiveMetaStoreTimeout.java | 73 ++++++++++++++++------
4 files changed, 69 insertions(+), 23 deletions(-)
diff --git
a/common/src/java/org/apache/hadoop/hive/common/auth/HiveAuthUtils.java
b/common/src/java/org/apache/hadoop/hive/common/auth/HiveAuthUtils.java
index 632980e7cd8..7fb2bd3ed97 100644
--- a/common/src/java/org/apache/hadoop/hive/common/auth/HiveAuthUtils.java
+++ b/common/src/java/org/apache/hadoop/hive/common/auth/HiveAuthUtils.java
@@ -55,6 +55,11 @@ public class HiveAuthUtils {
}
public static TTransport getSSLSocket(String host, int port, int
loginTimeout,
+ String trustStorePath, String trustStorePassWord) throws
TTransportException {
+ return getSSLSocket(host, port, loginTimeout, loginTimeout,
trustStorePath, trustStorePassWord);
+ }
+
+ public static TTransport getSSLSocket(String host, int port, int
socketTimeout, int connectionTimeout,
String trustStorePath, String trustStorePassWord) throws
TTransportException {
TSSLTransportFactory.TSSLTransportParameters params =
new TSSLTransportFactory.TSSLTransportParameters();
@@ -62,7 +67,8 @@ public class HiveAuthUtils {
params.requireClientAuth(true);
// The underlying SSLSocket object is bound to host:port with the given
SO_TIMEOUT and
// SSLContext created with the given params
- TSocket tSSLSocket = TSSLTransportFactory.getClientSocket(host, port,
loginTimeout, params);
+ TSocket tSSLSocket = TSSLTransportFactory.getClientSocket(host, port,
socketTimeout, params);
+ tSSLSocket.setConnectTimeout(connectionTimeout);
return getSSLSocketWithHttps(tSSLSocket);
}
diff --git a/common/src/java/org/apache/hadoop/hive/conf/HiveConf.java
b/common/src/java/org/apache/hadoop/hive/conf/HiveConf.java
index 46a74305eed..b8e54fdd39f 100644
--- a/common/src/java/org/apache/hadoop/hive/conf/HiveConf.java
+++ b/common/src/java/org/apache/hadoop/hive/conf/HiveConf.java
@@ -665,6 +665,9 @@ public class HiveConf extends Configuration {
"MetaStore Client socket lifetime in seconds. After this time is
exceeded, client\n" +
"reconnects on the next MetaStore operation. A value of 0s means the
connection\n" +
"has an infinite lifetime."),
+
METASTORE_CLIENT_CONNECTION_TIMEOUT("hive.metastore.client.connection.timeout",
"600s",
+ new TimeValidator(TimeUnit.SECONDS),
+ "MetaStore Client connection timeout in seconds"),
METASTOREPWD("javax.jdo.option.ConnectionPassword", "mine",
"password to use against metastore database"),
METASTORECONNECTURLHOOK("hive.metastore.ds.connection.url.hook", "",
diff --git
a/metastore/src/java/org/apache/hadoop/hive/metastore/HiveMetaStoreClient.java
b/metastore/src/java/org/apache/hadoop/hive/metastore/HiveMetaStoreClient.java
index c34124f410c..04ae5b0718d 100644
---
a/metastore/src/java/org/apache/hadoop/hive/metastore/HiveMetaStoreClient.java
+++
b/metastore/src/java/org/apache/hadoop/hive/metastore/HiveMetaStoreClient.java
@@ -400,6 +400,8 @@ public class HiveMetaStoreClient implements
IMetaStoreClient {
boolean useCompactProtocol =
conf.getBoolVar(ConfVars.METASTORE_USE_THRIFT_COMPACT_PROTOCOL);
int clientSocketTimeout = (int) conf.getTimeVar(
ConfVars.METASTORE_CLIENT_SOCKET_TIMEOUT, TimeUnit.MILLISECONDS);
+ int connectionTimeout = (int) conf.getTimeVar(
+ ConfVars.METASTORE_CLIENT_CONNECTION_TIMEOUT, TimeUnit.MILLISECONDS);
for (int attempt = 0; !isConnected && attempt < retries; ++attempt) {
for (URI store : metastoreUris) {
@@ -420,7 +422,7 @@ public class HiveMetaStoreClient implements
IMetaStoreClient {
String tokenSig =
conf.getVar(ConfVars.METASTORE_TOKEN_SIGNATURE);
// tokenSig could be null
tokenStrForm = Utils.getTokenStrForm(tokenSig);
- transport = new TSocket(new TConfiguration(), store.getHost(),
store.getPort(), clientSocketTimeout);
+ transport = new TSocket(new TConfiguration(), store.getHost(),
store.getPort(), clientSocketTimeout, connectionTimeout);
if(tokenStrForm != null) {
// authenticate using delegation tokens via the "DIGEST"
mechanism
@@ -451,7 +453,7 @@ public class HiveMetaStoreClient implements
IMetaStoreClient {
HiveConf.ConfVars.HIVE_METASTORE_SSL_TRUSTSTORE_PASSWORD.varname);
// Create an SSL socket and connect
- transport = HiveAuthUtils.getSSLSocket(store.getHost(),
store.getPort(), clientSocketTimeout, trustStorePath, trustStorePassword );
+ transport = HiveAuthUtils.getSSLSocket(store.getHost(),
store.getPort(), clientSocketTimeout, connectionTimeout, trustStorePath,
trustStorePassword );
LOG.info("Opened an SSL connection to metastore, current
connections: " + connCount.incrementAndGet());
} catch(IOException e) {
throw new IllegalArgumentException(e);
@@ -461,7 +463,7 @@ public class HiveMetaStoreClient implements
IMetaStoreClient {
}
} else {
try {
- transport = new TSocket(new TConfiguration(), store.getHost(),
store.getPort(), clientSocketTimeout);
+ transport = new TSocket(new TConfiguration(), store.getHost(),
store.getPort(), clientSocketTimeout, connectionTimeout);
} catch (TTransportException e) {
tte = e;
throw new MetaException(e.toString());
diff --git
a/metastore/src/test/org/apache/hadoop/hive/metastore/TestHiveMetaStoreTimeout.java
b/metastore/src/test/org/apache/hadoop/hive/metastore/TestHiveMetaStoreTimeout.java
index f8eed1820cc..da9cd7860aa 100644
---
a/metastore/src/test/org/apache/hadoop/hive/metastore/TestHiveMetaStoreTimeout.java
+++
b/metastore/src/test/org/apache/hadoop/hive/metastore/TestHiveMetaStoreTimeout.java
@@ -18,14 +18,20 @@
package org.apache.hadoop.hive.metastore;
+import java.util.concurrent.Callable;
+import java.util.concurrent.Executors;
+import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import org.apache.hadoop.hive.conf.HiveConf;
import org.apache.hadoop.hive.metastore.api.Database;
import org.apache.hadoop.hive.metastore.api.MetaException;
-import org.apache.hadoop.util.StringUtils;
+import org.apache.thrift.transport.TTransportException;
+import org.junit.After;
import org.junit.AfterClass;
import org.junit.Assert;
+
+import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
@@ -37,9 +43,10 @@ public class TestHiveMetaStoreTimeout {
protected static HiveMetaStoreClient client;
protected static HiveConf hiveConf;
protected static Warehouse warehouse;
+ protected static int port;
@BeforeClass
- public static void setUp() throws Exception {
+ public static void startMetaStoreServer() throws Exception {
HiveMetaStore.TEST_TIMEOUT_ENABLED = true;
hiveConf = new HiveConf(TestHiveMetaStoreTimeout.class);
hiveConf.setBoolean(HiveConf.ConfVars.HIVE_WAREHOUSE_SUBDIR_INHERIT_PERMS.varname,
true);
@@ -48,25 +55,25 @@ public class TestHiveMetaStoreTimeout {
hiveConf.setTimeVar(HiveConf.ConfVars.METASTORE_CLIENT_SOCKET_TIMEOUT, 10
* 1000,
TimeUnit.MILLISECONDS);
warehouse = new Warehouse(hiveConf);
- try {
- client = new HiveMetaStoreClient(hiveConf);
- } catch (Throwable e) {
- System.err.println("Unable to open the metastore");
- System.err.println(StringUtils.stringifyException(e));
- throw e;
- }
+ port = MetaStoreUtils.startMetaStoreWithRetry(hiveConf);
+ hiveConf.setVar(HiveConf.ConfVars.METASTOREURIS, "thrift://localhost:" +
port);
+ hiveConf.setBoolVar(HiveConf.ConfVars.METASTORE_EXECUTE_SET_UGI, false);
}
@AfterClass
public static void tearDown() throws Exception {
HiveMetaStore.TEST_TIMEOUT_ENABLED = false;
- try {
- client.close();
- } catch (Throwable e) {
- System.err.println("Unable to close metastore");
- System.err.println(StringUtils.stringifyException(e));
- throw e;
- }
+ }
+
+ @Before
+ public void setup() throws MetaException {
+ client = new HiveMetaStoreClient(hiveConf);
+ }
+
+ @After
+ public void cleanup() {
+ client.close();
+ client = null;
}
@Test
@@ -99,9 +106,8 @@ public class TestHiveMetaStoreTimeout {
try {
client.createDatabase(db);
Assert.fail("should throw timeout exception.");
- } catch (MetaException e) {
- Assert.assertTrue("unexpected MetaException",
e.getMessage().contains("Timeout when " +
- "executing method: create_database"));
+ } catch (TTransportException e) {
+ Assert.assertTrue("unexpected Exception", e.getMessage().contains("Read
timed out"));
}
// restore
@@ -140,4 +146,33 @@ public class TestHiveMetaStoreTimeout {
client.dropDatabase(dbName, true, true);
client.setMetaConf(HiveConf.ConfVars.METASTORE_CLIENT_SOCKET_TIMEOUT.varname,
"10s");
}
+
+ @Test
+ public void testConnectionTimeout() throws Exception {
+ final HiveConf newConf = new HiveConf(hiveConf);
+ newConf.setTimeVar(HiveConf.ConfVars.METASTORE_CLIENT_CONNECTION_TIMEOUT,
1000,
+ TimeUnit.MILLISECONDS);
+ // fake host to mock connection time out
+ newConf.setVar(HiveConf.ConfVars.METASTOREURIS, "thrift://1.1.1.1:" +
port);
+ newConf.setIntVar(HiveConf.ConfVars.METASTORETHRIFTCONNECTIONRETRIES, 1);
+
+ Future<Void> future = Executors.newSingleThreadExecutor().submit(new
Callable<Void>() {
+ @Override
+ public Void call() throws Exception {
+ HiveMetaStoreClient c = null;
+ try {
+ c = new HiveMetaStoreClient(newConf);
+ Assert.fail("should throw connection timeout exception.");
+ } catch (MetaException e) {
+ Assert.assertTrue("unexpected Exception",
e.getMessage().contains("connect timed out"));
+ } finally {
+ if (c != null) {
+ c.close();
+ }
+ }
+ return null;
+ }
+ });
+ future.get(5, TimeUnit.SECONDS);
+ }
}
\ No newline at end of file