This is an automated email from the ASF dual-hosted git repository. ishan pushed a commit to branch jira/SOLR15694 in repository https://gitbox.apache.org/repos/asf/solr.git
commit 1309a25135ae94ecae84b41a07b609465a7d72d5 Author: Noble Paul <[email protected]> AuthorDate: Wed Nov 17 22:12:44 2021 +1100 tests were failing intermittently --- .../org/apache/solr/cloud/OverseerNodePrioritizer.java | 18 ++++++++++++++---- .../src/java/org/apache/solr/cloud/ZkController.java | 9 +++------ .../solr/cloud/api/collections/OverseerRoleCmd.java | 11 ++++++++++- .../src/java/org/apache/solr/core/CoreContainer.java | 8 ++++++++ .../src/java/org/apache/solr/handler/ClusterAPI.java | 13 +++++++++---- .../src/test/org/apache/solr/cloud/NodeRolesTest.java | 17 +++++++++++++++++ 6 files changed, 61 insertions(+), 15 deletions(-) diff --git a/solr/core/src/java/org/apache/solr/cloud/OverseerNodePrioritizer.java b/solr/core/src/java/org/apache/solr/cloud/OverseerNodePrioritizer.java index c02403e..9a423a2 100644 --- a/solr/core/src/java/org/apache/solr/cloud/OverseerNodePrioritizer.java +++ b/solr/core/src/java/org/apache/solr/cloud/OverseerNodePrioritizer.java @@ -17,15 +17,18 @@ package org.apache.solr.cloud; import java.lang.invoke.MethodHandles; +import java.util.ArrayList; import java.util.List; import java.util.Map; +import org.apache.solr.client.solrj.impl.ZkDistribStateManager; import org.apache.solr.common.cloud.SolrZkClient; import org.apache.solr.common.cloud.ZkStateReader; import org.apache.solr.common.params.CoreAdminParams; import org.apache.solr.common.params.CoreAdminParams.CoreAdminAction; import org.apache.solr.common.params.ModifiableSolrParams; import org.apache.solr.common.util.Utils; +import org.apache.solr.handler.ClusterAPI; import org.apache.solr.handler.component.ShardHandler; import org.apache.solr.handler.component.ShardHandlerFactory; import org.apache.solr.handler.component.ShardRequest; @@ -59,11 +62,18 @@ public class OverseerNodePrioritizer { public synchronized void prioritizeOverseerNodes(String overseerId) throws Exception { SolrZkClient zk = zkStateReader.getZkClient(); - if(!zk.exists(ZkStateReader.ROLES,true))return; - Map<?,?> m = (Map<?,?>) Utils.fromJSON(zk.getData(ZkStateReader.ROLES, null, new Stat(), true)); + List<String> overseerDesignates = new ArrayList<>(); + if(zk.exists(ZkStateReader.ROLES,true)) { + Map<?,?> m = (Map<?,?>) Utils.fromJSON(zk.getData(ZkStateReader.ROLES, null, new Stat(), true)); + @SuppressWarnings("unchecked") + List<String> l = (List<String>) m.get("overseer"); + if(l != null) { + overseerDesignates.addAll(l); + } + } - List<?> overseerDesignates = (List<?>) m.get("overseer"); - if(overseerDesignates==null || overseerDesignates.isEmpty()) return; + overseerDesignates.addAll(ClusterAPI.getNodesByRole("overseer", new ZkDistribStateManager(zkStateReader.getZkClient()))); + if(overseerDesignates.isEmpty()) return; String ldr = OverseerTaskProcessor.getLeaderNode(zk); if(overseerDesignates.contains(ldr)) return; log.info("prioritizing overseer nodes at {} overseer designates are {}", overseerId, overseerDesignates); diff --git a/solr/core/src/java/org/apache/solr/cloud/ZkController.java b/solr/core/src/java/org/apache/solr/cloud/ZkController.java index 00274aa..c955497 100644 --- a/solr/core/src/java/org/apache/solr/cloud/ZkController.java +++ b/solr/core/src/java/org/apache/solr/cloud/ZkController.java @@ -2198,10 +2198,6 @@ public class ZkController implements Closeable { public void checkOverseerDesignate() { try { - if(cc.nodeRole.role() == NodeRole.Type.overseer) { - setPreferredOverseer(); - return; - } byte[] data = zkClient.getData(ZkStateReader.ROLES, null, new Stat(), true); if (data == null) return; Map<?,?> roles = (Map<?,?>) Utils.fromJSON(data); @@ -2218,10 +2214,11 @@ public class ZkController implements Closeable { } } - private void setPreferredOverseer() throws KeeperException, InterruptedException { + public void setPreferredOverseer() throws KeeperException, InterruptedException { ZkNodeProps props = new ZkNodeProps(Overseer.QUEUE_OPERATION, ADDROLE.toString().toLowerCase(Locale.ROOT), "node", getNodeName(), - "role", "overseer"); + "role", "overseer", + "persist", "false"); log.info("Going to add role {} ", props); getOverseerCollectionQueue().offer(Utils.toJSON(props)); } diff --git a/solr/core/src/java/org/apache/solr/cloud/api/collections/OverseerRoleCmd.java b/solr/core/src/java/org/apache/solr/cloud/api/collections/OverseerRoleCmd.java index e0766e6..409c480 100644 --- a/solr/core/src/java/org/apache/solr/cloud/api/collections/OverseerRoleCmd.java +++ b/solr/core/src/java/org/apache/solr/cloud/api/collections/OverseerRoleCmd.java @@ -64,6 +64,10 @@ public class OverseerRoleCmd implements CollApiCmds.CollectionApiCommand { SolrZkClient zkClient = zkStateReader.getZkClient(); Map<String, List<String>> roles = null; String node = message.getStr("node"); + if("false".equals(message.getStr("persist"))) {// no need to persist to roles.json + runPrioritizer(); + return; + } String roleName = message.getStr("role"); boolean nodeExists = false; @@ -89,16 +93,21 @@ public class OverseerRoleCmd implements CollApiCmds.CollectionApiCommand { } else { zkClient.create(ZkStateReader.ROLES, Utils.toJSON(roles), CreateMode.PERSISTENT, true); } + runPrioritizer(); + + } + + private void runPrioritizer() { //if there are too many nodes this command may time out. And most likely dedicated // overseers are created when there are too many nodes . So , do this operation in a separate thread new Thread(() -> { try { + log.info("prioritizeOverseerNodes()"); overseerPrioritizer.prioritizeOverseerNodes(ccc.getOverseerId()); } catch (Exception e) { log.error("Error in prioritizing Overseer", e); } }, "OverseerPrioritizationThread").start(); - } } diff --git a/solr/core/src/java/org/apache/solr/core/CoreContainer.java b/solr/core/src/java/org/apache/solr/core/CoreContainer.java index f85f3d7..40d5f89 100644 --- a/solr/core/src/java/org/apache/solr/core/CoreContainer.java +++ b/solr/core/src/java/org/apache/solr/core/CoreContainer.java @@ -947,6 +947,14 @@ public class CoreContainer { }); clusterSingletons.setReady(); + if(nodeRole.role() == NodeRole.Type.overseer) { + try { + log.info("This node is started as an overseer"); + zkSys.getZkController().setPreferredOverseer(); + } catch (KeeperException | InterruptedException e) { + throw new SolrException(ErrorCode.SERVER_ERROR, e); + } + } if (!distributedCollectionCommandRunner.isPresent()) { zkSys.getZkController().checkOverseerDesignate(); } diff --git a/solr/core/src/java/org/apache/solr/handler/ClusterAPI.java b/solr/core/src/java/org/apache/solr/handler/ClusterAPI.java index 74b221f..9541191 100644 --- a/solr/core/src/java/org/apache/solr/handler/ClusterAPI.java +++ b/solr/core/src/java/org/apache/solr/handler/ClusterAPI.java @@ -17,12 +17,14 @@ package org.apache.solr.handler; +import java.io.IOException; import java.util.*; import com.google.common.collect.Maps; import org.apache.solr.api.Command; import org.apache.solr.api.EndPoint; import org.apache.solr.api.PayloadObj; +import org.apache.solr.client.solrj.cloud.DistribStateManager; import org.apache.solr.client.solrj.request.beans.ClusterPropPayload; import org.apache.solr.client.solrj.request.beans.CreateConfigPayload; import org.apache.solr.client.solrj.request.beans.RateLimiterPayload; @@ -43,6 +45,7 @@ import org.apache.solr.handler.admin.CollectionsHandler; import org.apache.solr.handler.admin.ConfigSetsHandler; import org.apache.solr.request.SolrQueryRequest; import org.apache.solr.response.SolrQueryResponse; +import org.apache.zookeeper.KeeperException; import static org.apache.solr.client.solrj.SolrRequest.METHOD.DELETE; import static org.apache.solr.client.solrj.SolrRequest.METHOD.GET; @@ -92,11 +95,13 @@ public class ClusterAPI { permission = COLL_READ_PERM) public void nodesWithRole(SolrQueryRequest req, SolrQueryResponse rsp) throws Exception { String role = req.getPathTemplateValues().get("role"); + rsp.add("nodes", + getNodesByRole(role, collectionsHandler.getCoreContainer().getZkController().getSolrCloudManager().getDistribStateManager())); + } + public static List<String> getNodesByRole(String role, DistribStateManager zk) throws InterruptedException, IOException, KeeperException { List<String> result = new ArrayList<>(); - collectionsHandler.getCoreContainer().getZkController().getSolrCloudManager().getDistribStateManager(). - forEachChild(ZkStateReader.NODE_ROLES, (node, data) -> { - + zk.forEachChild(ZkStateReader.NODE_ROLES, (node, data) -> { if(data != null && data.getData() != null) { @SuppressWarnings("unchecked") Map<String, Object> roleData = (Map<String, Object>) Utils.fromJSON(data.getData()); @@ -105,7 +110,7 @@ public class ClusterAPI { } } }); - rsp.add("nodes", result); + return result; } diff --git a/solr/core/src/test/org/apache/solr/cloud/NodeRolesTest.java b/solr/core/src/test/org/apache/solr/cloud/NodeRolesTest.java index 70ab96b..42c5a0f 100644 --- a/solr/core/src/test/org/apache/solr/cloud/NodeRolesTest.java +++ b/solr/core/src/test/org/apache/solr/cloud/NodeRolesTest.java @@ -1,3 +1,20 @@ +/* + * 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.solr.cloud; import java.lang.invoke.MethodHandles;
