This is an automated email from the ASF dual-hosted git repository.
vjasani pushed a commit to branch 5.3
in repository https://gitbox.apache.org/repos/asf/phoenix.git
The following commit(s) were added to refs/heads/5.3 by this push:
new 13e0d17aa9 PHOENIX-7370 Server to server system table RPC calls should
use separate RPC handler pool (#2301)
13e0d17aa9 is described below
commit 13e0d17aa98368ed1282d13526224661921018d6
Author: Viraj Jasani <[email protected]>
AuthorDate: Mon Nov 3 13:17:39 2025 -0800
PHOENIX-7370 Server to server system table RPC calls should use separate
RPC handler pool (#2301)
---
.../hbase/ipc/controller/ServerRpcController.java | 71 ++++++++++++++
.../ipc/controller/ServerRpcControllerFactory.java | 11 +--
.../phoenix/query/ConnectionQueryServicesImpl.java | 12 ++-
.../apache/phoenix/query/QueryServicesOptions.java | 2 +-
.../org/apache/phoenix/schema/MetaDataClient.java | 6 +-
.../ipc/controller/ServerRpcControllerFactory.java | 36 -------
.../phoenix/end2end/SingleMetadataHandlerIT.java | 105 +++++++++++++++++++++
7 files changed, 196 insertions(+), 47 deletions(-)
diff --git
a/phoenix-core-client/src/main/java/org/apache/hadoop/hbase/ipc/controller/ServerRpcController.java
b/phoenix-core-client/src/main/java/org/apache/hadoop/hbase/ipc/controller/ServerRpcController.java
new file mode 100644
index 0000000000..737aa8ee06
--- /dev/null
+++
b/phoenix-core-client/src/main/java/org/apache/hadoop/hbase/ipc/controller/ServerRpcController.java
@@ -0,0 +1,71 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.hadoop.hbase.ipc.controller;
+
+import com.google.protobuf.RpcController;
+import java.util.List;
+import org.apache.hadoop.conf.Configuration;
+import org.apache.hadoop.hbase.TableName;
+import org.apache.hadoop.hbase.ipc.DelegatingHBaseRpcController;
+import org.apache.hadoop.hbase.ipc.HBaseRpcController;
+import org.apache.phoenix.jdbc.PhoenixDatabaseMetaData;
+import org.apache.phoenix.util.IndexUtil;
+import org.apache.phoenix.util.SchemaUtil;
+
+import org.apache.phoenix.thirdparty.com.google.common.collect.ImmutableList;
+
+/**
+ * {@link RpcController} that sets the appropriate priority of server-server
RPC calls destined for
+ * Phoenix SYSTEM tables.
+ */
+class ServerRpcController extends DelegatingHBaseRpcController {
+
+ private final int priority;
+
+ private static final List<String> SYSTEM_TABLE_NAMES = new
ImmutableList.Builder<String>()
+
.add(PhoenixDatabaseMetaData.SYSTEM_CATALOG_NAME).add(PhoenixDatabaseMetaData.SYSTEM_STATS_NAME)
+ .add(PhoenixDatabaseMetaData.SYSTEM_SEQUENCE_NAME)
+ .add(PhoenixDatabaseMetaData.SYSTEM_FUNCTION_NAME)
+ .add(PhoenixDatabaseMetaData.SYSTEM_CHILD_LINK_NAME)
+
.add(SchemaUtil.getPhysicalTableName(PhoenixDatabaseMetaData.SYSTEM_CATALOG_NAME_BYTES,
true)
+ .getNameAsString())
+
.add(SchemaUtil.getPhysicalTableName(PhoenixDatabaseMetaData.SYSTEM_STATS_NAME_BYTES,
true)
+ .getNameAsString())
+
.add(SchemaUtil.getPhysicalTableName(PhoenixDatabaseMetaData.SYSTEM_SEQUENCE_NAME_BYTES,
true)
+ .getNameAsString())
+
.add(SchemaUtil.getPhysicalTableName(PhoenixDatabaseMetaData.SYSTEM_FUNCTION_NAME_BYTES,
true)
+ .getNameAsString())
+
.add(SchemaUtil.getPhysicalTableName(PhoenixDatabaseMetaData.SYSTEM_CHILD_LINK_NAME_BYTES,
true)
+ .getNameAsString())
+ .build();
+
+ ServerRpcController(HBaseRpcController delegate, Configuration conf) {
+ super(delegate);
+ this.priority = IndexUtil.getServerSidePriority(conf);
+ }
+
+ @Override
+ public void setPriority(final TableName tn) {
+ if (SYSTEM_TABLE_NAMES.contains(tn.getNameAsString())) {
+ setPriority(this.priority);
+ } else {
+ super.setPriority(tn);
+ }
+ }
+
+}
diff --git
a/phoenix-core-server/src/main/java/org/apache/hadoop/hbase/ipc/controller/InterRegionServerMetadataRpcControllerFactory.java
b/phoenix-core-client/src/main/java/org/apache/hadoop/hbase/ipc/controller/ServerRpcControllerFactory.java
similarity index 79%
rename from
phoenix-core-server/src/main/java/org/apache/hadoop/hbase/ipc/controller/InterRegionServerMetadataRpcControllerFactory.java
rename to
phoenix-core-client/src/main/java/org/apache/hadoop/hbase/ipc/controller/ServerRpcControllerFactory.java
index 9bb6be0bf4..afbd77c65b 100644
---
a/phoenix-core-server/src/main/java/org/apache/hadoop/hbase/ipc/controller/InterRegionServerMetadataRpcControllerFactory.java
+++
b/phoenix-core-client/src/main/java/org/apache/hadoop/hbase/ipc/controller/ServerRpcControllerFactory.java
@@ -25,12 +25,12 @@ import org.apache.hadoop.hbase.ipc.HBaseRpcController;
import org.apache.hadoop.hbase.ipc.RpcControllerFactory;
/**
- * {@link RpcControllerFactory} that should only be used when creating Table
for making remote RPCs
- * to the region servers hosting Phoenix SYSTEM tables.
+ * {@link RpcControllerFactory} that sets the appropriate priority of
server-server RPC calls
+ * destined for Phoenix SYSTEM tables.
*/
-public class InterRegionServerMetadataRpcControllerFactory extends
RpcControllerFactory {
+public class ServerRpcControllerFactory extends RpcControllerFactory {
- public InterRegionServerMetadataRpcControllerFactory(Configuration conf) {
+ public ServerRpcControllerFactory(Configuration conf) {
super(conf);
}
@@ -53,8 +53,7 @@ public class InterRegionServerMetadataRpcControllerFactory
extends RpcController
}
private HBaseRpcController getController(HBaseRpcController delegate) {
- // construct a chain of controllers: metadata and delegate controller
- return new MetadataRpcController(delegate, conf);
+ return new ServerRpcController(delegate, conf);
}
}
diff --git
a/phoenix-core-client/src/main/java/org/apache/phoenix/query/ConnectionQueryServicesImpl.java
b/phoenix-core-client/src/main/java/org/apache/phoenix/query/ConnectionQueryServicesImpl.java
index 311a16e49f..8e867842bc 100644
---
a/phoenix-core-client/src/main/java/org/apache/phoenix/query/ConnectionQueryServicesImpl.java
+++
b/phoenix-core-client/src/main/java/org/apache/phoenix/query/ConnectionQueryServicesImpl.java
@@ -188,6 +188,7 @@ import org.apache.hadoop.hbase.ipc.HBaseRpcController;
import org.apache.hadoop.hbase.ipc.RpcControllerFactory;
import org.apache.hadoop.hbase.ipc.ServerRpcController;
import
org.apache.hadoop.hbase.ipc.controller.InvalidateMetadataCacheControllerFactory;
+import org.apache.hadoop.hbase.ipc.controller.ServerRpcControllerFactory;
import org.apache.hadoop.hbase.ipc.controller.ServerSideRPCControllerFactory;
import org.apache.hadoop.hbase.ipc.controller.ServerToServerRpcController;
import org.apache.hadoop.hbase.protobuf.generated.ClientProtos.MutationProto;
@@ -4136,7 +4137,16 @@ public class ConnectionQueryServicesImpl extends
DelegateQueryServices
try {
GLOBAL_QUERY_SERVICES_COUNTER.increment();
LOGGER.info("An instance of ConnectionQueryServices was
created.");
- connection = openConnection(config);
+ boolean isServerSideConnection =
+ config.getBoolean(QueryUtil.IS_SERVER_CONNECTION, false);
+ if (isServerSideConnection) {
+ Configuration clonedConfiguration =
PropertiesUtil.cloneConfig(config);
+ clonedConfiguration.setClass(CUSTOM_CONTROLLER_CONF_KEY,
+ ServerRpcControllerFactory.class,
RpcControllerFactory.class);
+ connection = openConnection(clonedConfiguration);
+ } else {
+ connection = openConnection(config);
+ }
hConnectionEstablished = true;
boolean lastDDLTimestampValidationEnabled =
getProps().getBoolean(QueryServices.LAST_DDL_TIMESTAMP_VALIDATION_ENABLED,
diff --git
a/phoenix-core-client/src/main/java/org/apache/phoenix/query/QueryServicesOptions.java
b/phoenix-core-client/src/main/java/org/apache/phoenix/query/QueryServicesOptions.java
index d398f4b240..5e345f4901 100644
---
a/phoenix-core-client/src/main/java/org/apache/phoenix/query/QueryServicesOptions.java
+++
b/phoenix-core-client/src/main/java/org/apache/phoenix/query/QueryServicesOptions.java
@@ -255,7 +255,7 @@ public class QueryServicesOptions {
* HConstants#HIGH_QOS is the max we will see to a standard table. We go
higher to differentiate
* and give some room for things in the middle
*/
- public static final int DEFAULT_SERVER_SIDE_PRIORITY = 500;
+ public static final int DEFAULT_SERVER_SIDE_PRIORITY = 5000;
public static final int DEFAULT_INDEX_PRIORITY = 1000;
public static final int DEFAULT_METADATA_PRIORITY = 2000;
public static final int DEFAULT_INVALIDATE_METADATA_CACHE_PRIORITY = 3000;
diff --git
a/phoenix-core-client/src/main/java/org/apache/phoenix/schema/MetaDataClient.java
b/phoenix-core-client/src/main/java/org/apache/phoenix/schema/MetaDataClient.java
index f5be406566..99ffe14156 100644
---
a/phoenix-core-client/src/main/java/org/apache/phoenix/schema/MetaDataClient.java
+++
b/phoenix-core-client/src/main/java/org/apache/phoenix/schema/MetaDataClient.java
@@ -4729,9 +4729,9 @@ public class MetaDataClient {
/**
* To check if TTL is defined at any of the child below we are
checking it at
* {@link
org.apache.phoenix.coprocessor.MetaDataEndpointImpl#mutateColumn(List,
ColumnMutator, int, PTable, PTable, boolean)}
- * level where in function {@link
org.apache.phoenix.coprocessor.MetaDataEndpointImpl#
- * validateIfMutationAllowedOnParent(PTable, List, PTableType, long,
byte[], byte[],
- * byte[], List, int)} we are already traversing through
allDescendantViews.
+ * level where in function
+ * {@link org.apache.phoenix.coprocessor.MetaDataEndpointImpl#
validateIfMutationAllowedOnParent(PTable, List, PTableType, long, byte[],
byte[], byte[], List, int)}
+ * we are already traversing through allDescendantViews.
*/
}
diff --git
a/phoenix-core-server/src/main/java/org/apache/hadoop/hbase/ipc/controller/ServerRpcControllerFactory.java
b/phoenix-core-server/src/main/java/org/apache/hadoop/hbase/ipc/controller/ServerRpcControllerFactory.java
deleted file mode 100644
index 78f5ac357a..0000000000
---
a/phoenix-core-server/src/main/java/org/apache/hadoop/hbase/ipc/controller/ServerRpcControllerFactory.java
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.hadoop.hbase.ipc.controller;
-
-import org.apache.hadoop.conf.Configuration;
-import org.apache.hadoop.hbase.ipc.RpcControllerFactory;
-
-/**
- * {@link RpcControllerFactory} that sets the priority of metadata rpc calls
so that they get
- * processed in their own queue. This controller factory should only be
configured on the region
- * servers. It is meant to control inter region server RPCs destined for
Phoenix SYSTEM tables.
- * <p>
- * This class is left here only for legacy reasons so as to not break users
who have configured this
- * {@link RpcControllerFactory} in their hbase-site.xml.
- */
-@Deprecated
-public class ServerRpcControllerFactory extends
InterRegionServerMetadataRpcControllerFactory {
- public ServerRpcControllerFactory(Configuration conf) {
- super(conf);
- }
-}
diff --git
a/phoenix-core/src/it/java/org/apache/phoenix/end2end/SingleMetadataHandlerIT.java
b/phoenix-core/src/it/java/org/apache/phoenix/end2end/SingleMetadataHandlerIT.java
new file mode 100644
index 0000000000..d4fcf080de
--- /dev/null
+++
b/phoenix-core/src/it/java/org/apache/phoenix/end2end/SingleMetadataHandlerIT.java
@@ -0,0 +1,105 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.phoenix.end2end;
+
+import static org.apache.phoenix.util.TestUtil.TEST_PROPERTIES;
+
+import java.sql.Connection;
+import java.sql.DriverManager;
+import java.sql.SQLException;
+import java.util.Map;
+import java.util.Properties;
+import org.apache.phoenix.coprocessorclient.BaseScannerRegionObserverConstants;
+import org.apache.phoenix.query.BaseTest;
+import org.apache.phoenix.query.QueryServices;
+import org.apache.phoenix.util.PropertiesUtil;
+import org.apache.phoenix.util.QueryUtil;
+import org.apache.phoenix.util.ReadOnlyProps;
+import org.apache.phoenix.util.StringUtil;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.junit.experimental.categories.Category;
+
+import org.apache.phoenix.thirdparty.com.google.common.collect.Maps;
+
+/**
+ * Test to verify that metadata operations work correctly with a single
metadata handler and a
+ * single server-to-server handler.
+ */
+@Category(NeedsOwnMiniClusterTest.class)
+public class SingleMetadataHandlerIT extends BaseTest {
+
+ private Properties props = PropertiesUtil.deepCopy(TEST_PROPERTIES);
+
+ @BeforeClass
+ public static synchronized void doSetup() throws Exception {
+ Map<String, String> props = Maps.newConcurrentMap();
+ props.put(QueryServices.DROP_METADATA_ATTRIB, Boolean.TRUE.toString());
+
props.put(BaseScannerRegionObserverConstants.PHOENIX_MAX_LOOKBACK_AGE_CONF_KEY,
+ Integer.toString(60 * 60 * 1000));
+ // single metadata rpc handler thread
+ props.put(QueryServices.METADATA_HANDLER_COUNT_ATTRIB,
Integer.toString(1));
+ // single server-to-server rpc handler thread
+ props.put(QueryServices.SERVER_SIDE_HANDLER_COUNT_ATTRIB,
Integer.toString(1));
+ setUpTestDriver(new ReadOnlyProps(props.entrySet().iterator()));
+ }
+
+ private Connection getConnection(Properties props) throws Exception {
+ props.setProperty(QueryServices.DROP_METADATA_ATTRIB,
Boolean.toString(true));
+ props.setProperty(QueryServices.EXTRA_JDBC_ARGUMENTS_ATTRIB,
StringUtil.EMPTY_STRING);
+ String url = QueryUtil.getConnectionUrl(props, config, "PRINCIPAL");
+ return DriverManager.getConnection(url, props);
+ }
+
+ private void createTable(Connection conn, String tableName) throws Exception
{
+ String createTableSql =
+ "CREATE TABLE " + tableName + " (PK1 VARCHAR NOT NULL, V1 VARCHAR, V2
INTEGER, V3 INTEGER "
+ + "CONSTRAINT NAME_PK PRIMARY KEY(PK1)) COLUMN_ENCODED_BYTES=0";
+ conn.createStatement().execute(createTableSql);
+ }
+
+ private void createIndexOnTable(Connection conn, String tableName, String
indexName)
+ throws SQLException {
+ String createIndexSql =
+ "CREATE INDEX " + indexName + " ON " + tableName + " (V1) INCLUDE (V2,
V3) ";
+ conn.createStatement().execute(createIndexSql);
+ }
+
+ /**
+ * Test that verifies metadata operations work correctly with a single
metadata handler and single
+ * server side handler.
+ */
+ @Test
+ public void testSingleMetadataHandler() throws Exception {
+ try (Connection conn = getConnection(props)) {
+ String tableName = "TBL_" + generateUniqueName();
+
+ conn.setAutoCommit(true);
+ createTable(conn, tableName);
+ createIndexOnTable(conn, tableName, "IDX_" + generateUniqueName());
+
+ String view1DDL = "CREATE VIEW IF NOT EXISTS VIEW1"
+ + " ( VIEW_COL1 VARCHAR, VIEW_COL2 VARCHAR) AS SELECT * FROM " +
tableName;
+ conn.createStatement().execute(view1DDL);
+ String indexDDL =
+ "CREATE INDEX IF NOT EXISTS V1IDX1" + " ON VIEW1" + " (V1) include
(V2, V3, VIEW_COL2) ";
+ conn.createStatement().execute(indexDDL);
+ conn.commit();
+ }
+ }
+}