You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@lucene.apache.org by da...@apache.org on 2017/06/09 11:23:03 UTC

lucene-solr:feature/autoscaling: SOLR-10397: Port 'autoAddReplicas' feature to the policy rules framework and make it work with non-shared filesystems

Repository: lucene-solr
Updated Branches:
  refs/heads/feature/autoscaling d158f694b -> d609137a6


SOLR-10397: Port 'autoAddReplicas' feature to the policy rules framework and make it work with non-shared filesystems


Project: http://git-wip-us.apache.org/repos/asf/lucene-solr/repo
Commit: http://git-wip-us.apache.org/repos/asf/lucene-solr/commit/d609137a
Tree: http://git-wip-us.apache.org/repos/asf/lucene-solr/tree/d609137a
Diff: http://git-wip-us.apache.org/repos/asf/lucene-solr/diff/d609137a

Branch: refs/heads/feature/autoscaling
Commit: d609137a60ee4c0f1d84f4004a8da52b9b7586cf
Parents: d158f69
Author: Cao Manh Dat <da...@apache.org>
Authored: Fri Jun 9 18:22:52 2017 +0700
Committer: Cao Manh Dat <da...@apache.org>
Committed: Fri Jun 9 18:22:52 2017 +0700

----------------------------------------------------------------------
 .../org/apache/solr/cloud/AddReplicaCmd.java    |  4 ++
 .../apache/solr/cloud/CreateCollectionCmd.java  | 10 +++++
 .../org/apache/solr/cloud/MoveReplicaCmd.java   |  8 ++--
 .../cloud/OverseerCollectionMessageHandler.java | 24 +++++++++++
 .../autoscaling/AutoAddReplicasPlanAction.java  | 21 ++++++++++
 .../solr/cloud/autoscaling/AutoScaling.java     | 24 +++++++++++
 .../cloud/autoscaling/AutoScalingHandler.java   |  4 ++
 .../autoscaling/AutoScalingHandlerTest.java     | 44 ++++++++++++++++++++
 8 files changed, 136 insertions(+), 3 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/d609137a/solr/core/src/java/org/apache/solr/cloud/AddReplicaCmd.java
----------------------------------------------------------------------
diff --git a/solr/core/src/java/org/apache/solr/cloud/AddReplicaCmd.java b/solr/core/src/java/org/apache/solr/cloud/AddReplicaCmd.java
index 63acdd1..a3470ec 100644
--- a/solr/core/src/java/org/apache/solr/cloud/AddReplicaCmd.java
+++ b/solr/core/src/java/org/apache/solr/cloud/AddReplicaCmd.java
@@ -139,6 +139,7 @@ public class AddReplicaCmd implements OverseerCollectionMessageHandler.Cmd {
     String configName = zkStateReader.readConfigName(collection);
     String routeKey = message.getStr(ShardParams._ROUTE_);
     String dataDir = message.getStr(CoreAdminParams.DATA_DIR);
+    String ulogDir = message.getStr(CoreAdminParams.ULOG_DIR);
     String instanceDir = message.getStr(CoreAdminParams.INSTANCE_DIR);
 
     params.set(CoreAdminParams.ACTION, CoreAdminParams.CoreAdminAction.CREATE.toString());
@@ -161,6 +162,9 @@ public class AddReplicaCmd implements OverseerCollectionMessageHandler.Cmd {
     if (dataDir != null) {
       params.set(CoreAdminParams.DATA_DIR, dataDir);
     }
+    if (ulogDir != null) {
+      params.set(CoreAdminParams.ULOG_DIR, ulogDir);
+    }
     if (instanceDir != null) {
       params.set(CoreAdminParams.INSTANCE_DIR, instanceDir);
     }

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/d609137a/solr/core/src/java/org/apache/solr/cloud/CreateCollectionCmd.java
----------------------------------------------------------------------
diff --git a/solr/core/src/java/org/apache/solr/cloud/CreateCollectionCmd.java b/solr/core/src/java/org/apache/solr/cloud/CreateCollectionCmd.java
index d6a82a7..3d89fd2 100644
--- a/solr/core/src/java/org/apache/solr/cloud/CreateCollectionCmd.java
+++ b/solr/core/src/java/org/apache/solr/cloud/CreateCollectionCmd.java
@@ -28,7 +28,9 @@ import java.util.Map;
 import java.util.Properties;
 import java.util.concurrent.TimeUnit;
 
+import org.apache.solr.client.solrj.request.V2Request;
 import org.apache.solr.cloud.OverseerCollectionMessageHandler.Cmd;
+import org.apache.solr.cloud.autoscaling.AutoScaling;
 import org.apache.solr.cloud.overseer.ClusterStateMutator;
 import org.apache.solr.cloud.rule.ReplicaAssigner;
 import org.apache.solr.common.SolrException;
@@ -44,11 +46,15 @@ import org.apache.solr.common.cloud.ZkStateReader;
 import org.apache.solr.common.cloud.ZooKeeperException;
 import org.apache.solr.common.params.CoreAdminParams;
 import org.apache.solr.common.params.ModifiableSolrParams;
+import org.apache.solr.common.params.SolrParams;
+import org.apache.solr.common.util.ContentStreamBase;
 import org.apache.solr.common.util.NamedList;
 import org.apache.solr.common.util.SimpleOrderedMap;
 import org.apache.solr.common.util.Utils;
 import org.apache.solr.handler.component.ShardHandler;
 import org.apache.solr.handler.component.ShardRequest;
+import org.apache.solr.request.LocalSolrQueryRequest;
+import org.apache.solr.response.SolrQueryResponse;
 import org.apache.solr.util.TimeOut;
 import org.apache.zookeeper.CreateMode;
 import org.apache.zookeeper.KeeperException;
@@ -98,6 +104,7 @@ public class CreateCollectionCmd implements Cmd {
       int numTlogReplicas = message.getInt(TLOG_REPLICAS, 0);
       int numNrtReplicas = message.getInt(NRT_REPLICAS, message.getInt(REPLICATION_FACTOR, numTlogReplicas>0?0:1));
       int numPullReplicas = message.getInt(PULL_REPLICAS, 0);
+      boolean autoAddReplicas = message.getBool(AUTO_ADD_REPLICAS, false);
 
       ShardHandler shardHandler = ocmh.shardHandlerFactory.getShardHandler();
       final String async = message.getStr(ASYNC);
@@ -280,6 +287,9 @@ public class CreateCollectionCmd implements Cmd {
         ocmh.cleanupCollection(collectionName, new NamedList());
         log.info("Cleaned up artifacts for failed create collection for [{}]", collectionName);
       } else {
+        if (autoAddReplicas) {
+          ocmh.forwardToAutoScaling(AutoScaling.AUTO_ADD_REPLICAS_TRIGGER_DSL);
+        }
         log.debug("Finished create command on all shards for collection: {}", collectionName);
       }
     } catch (SolrException ex) {

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/d609137a/solr/core/src/java/org/apache/solr/cloud/MoveReplicaCmd.java
----------------------------------------------------------------------
diff --git a/solr/core/src/java/org/apache/solr/cloud/MoveReplicaCmd.java b/solr/core/src/java/org/apache/solr/cloud/MoveReplicaCmd.java
index fed1398..cd7d248 100644
--- a/solr/core/src/java/org/apache/solr/cloud/MoveReplicaCmd.java
+++ b/solr/core/src/java/org/apache/solr/cloud/MoveReplicaCmd.java
@@ -102,14 +102,15 @@ public class MoveReplicaCmd implements Cmd{
     }
     assert slice != null;
     Object dataDir = replica.get("dataDir");
+    final String ulogDir = replica.getStr("ulogDir");
     if (dataDir != null && dataDir.toString().startsWith("hdfs:/")) {
-      moveHdfsReplica(clusterState, results, dataDir.toString(), targetNode, async, coll, replica, slice);
+      moveHdfsReplica(clusterState, results, dataDir.toString(), ulogDir, targetNode, async, coll, replica, slice);
     } else {
       moveNormalReplica(clusterState, results, targetNode, async, coll, replica, slice);
     }
   }
 
-  private void moveHdfsReplica(ClusterState clusterState, NamedList results, String dataDir, String targetNode, String async,
+  private void moveHdfsReplica(ClusterState clusterState, NamedList results, String dataDir, String ulogDir, String targetNode, String async,
                                  DocCollection coll, Replica replica, Slice slice) throws Exception {
     String newCoreName = Assign.buildCoreName(coll, slice.getName(), replica.getType());
 
@@ -136,7 +137,8 @@ public class MoveReplicaCmd implements Cmd{
         SHARD_ID_PROP, slice.getName(),
         CoreAdminParams.NODE, targetNode,
         CoreAdminParams.NAME, newCoreName,
-        CoreAdminParams.DATA_DIR, dataDir);
+        CoreAdminParams.DATA_DIR, dataDir,
+        CoreAdminParams.ULOG_DIR, ulogDir);
     if(async!=null) addReplicasProps.getProperties().put(ASYNC, async);
     NamedList addResult = new NamedList();
     ocmh.addReplica(clusterState, addReplicasProps, addResult, null);

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/d609137a/solr/core/src/java/org/apache/solr/cloud/OverseerCollectionMessageHandler.java
----------------------------------------------------------------------
diff --git a/solr/core/src/java/org/apache/solr/cloud/OverseerCollectionMessageHandler.java b/solr/core/src/java/org/apache/solr/cloud/OverseerCollectionMessageHandler.java
index a055033..5e16b5d 100644
--- a/solr/core/src/java/org/apache/solr/cloud/OverseerCollectionMessageHandler.java
+++ b/solr/core/src/java/org/apache/solr/cloud/OverseerCollectionMessageHandler.java
@@ -42,6 +42,8 @@ import org.apache.solr.client.solrj.impl.HttpSolrClient.RemoteSolrException;
 import org.apache.solr.client.solrj.request.AbstractUpdateRequest;
 import org.apache.solr.client.solrj.request.UpdateRequest;
 import org.apache.solr.client.solrj.response.UpdateResponse;
+import org.apache.solr.cloud.autoscaling.AutoScaling;
+import org.apache.solr.cloud.autoscaling.AutoScalingHandler;
 import org.apache.solr.cloud.autoscaling.Policy;
 import org.apache.solr.cloud.overseer.OverseerAction;
 import org.apache.solr.cloud.rule.ReplicaAssigner;
@@ -64,6 +66,8 @@ import org.apache.solr.common.params.CollectionParams.CollectionAction;
 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.params.SolrParams;
+import org.apache.solr.common.util.ContentStreamBase;
 import org.apache.solr.common.util.ExecutorUtil;
 import org.apache.solr.common.util.NamedList;
 import org.apache.solr.common.util.SimpleOrderedMap;
@@ -74,6 +78,10 @@ import org.apache.solr.handler.component.ShardHandler;
 import org.apache.solr.handler.component.ShardHandlerFactory;
 import org.apache.solr.handler.component.ShardRequest;
 import org.apache.solr.handler.component.ShardResponse;
+import org.apache.solr.request.LocalSolrQueryRequest;
+import org.apache.solr.request.SolrQueryRequest;
+import org.apache.solr.request.SolrRequestInfo;
+import org.apache.solr.response.SolrQueryResponse;
 import org.apache.solr.util.DefaultSolrThreadFactory;
 import org.apache.solr.util.RTimer;
 import org.apache.solr.util.TimeOut;
@@ -692,6 +700,11 @@ public class OverseerCollectionMessageHandler implements OverseerMessageHandler
       if (areChangesVisible) break;
       Thread.sleep(100);
     }
+
+    if (message.getBool(ZkStateReader.AUTO_ADD_REPLICAS, false)) {
+      forwardToAutoScaling(AutoScaling.AUTO_ADD_REPLICAS_TRIGGER_DSL);
+    }
+
     if (!areChangesVisible)
       throw new SolrException(SolrException.ErrorCode.SERVER_ERROR, "Could not modify collection " + message);
   }
@@ -951,6 +964,17 @@ public class OverseerCollectionMessageHandler implements OverseerMessageHandler
     }
   }
 
+  void forwardToAutoScaling(String command) {
+    LocalSolrQueryRequest request = new LocalSolrQueryRequest(null, new ModifiableSolrParams());
+    request.getContext().put("httpMethod", "POST");
+    request.setContentStreams(Collections.singleton(new ContentStreamBase.StringStream(command)));
+    SolrQueryResponse response = new SolrQueryResponse();
+    overseer.getZkController().getCoreContainer().getRequestHandler(AutoScalingHandler.HANDLER_PATH).handleRequest(request, response);
+    if (!"success".equals(response.getValues().get("result"))) {
+      throw new SolrException(ErrorCode.SERVER_ERROR, "Failed when execute command on autoScalingHandler, return " + response);
+    }
+  }
+
   private NamedList waitForCoreAdminAsyncCallToComplete(String nodeName, String requestId) {
     ShardHandler shardHandler = shardHandlerFactory.getShardHandler();
     ModifiableSolrParams params = new ModifiableSolrParams();

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/d609137a/solr/core/src/java/org/apache/solr/cloud/autoscaling/AutoAddReplicasPlanAction.java
----------------------------------------------------------------------
diff --git a/solr/core/src/java/org/apache/solr/cloud/autoscaling/AutoAddReplicasPlanAction.java b/solr/core/src/java/org/apache/solr/cloud/autoscaling/AutoAddReplicasPlanAction.java
new file mode 100644
index 0000000..a9fc6e2
--- /dev/null
+++ b/solr/core/src/java/org/apache/solr/cloud/autoscaling/AutoAddReplicasPlanAction.java
@@ -0,0 +1,21 @@
+/*
+ * 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.autoscaling;
+
+public class AutoAddReplicasPlanAction extends ComputePlanAction {
+}

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/d609137a/solr/core/src/java/org/apache/solr/cloud/autoscaling/AutoScaling.java
----------------------------------------------------------------------
diff --git a/solr/core/src/java/org/apache/solr/cloud/autoscaling/AutoScaling.java b/solr/core/src/java/org/apache/solr/cloud/autoscaling/AutoScaling.java
index 2236291..f1f2a26 100644
--- a/solr/core/src/java/org/apache/solr/cloud/autoscaling/AutoScaling.java
+++ b/solr/core/src/java/org/apache/solr/cloud/autoscaling/AutoScaling.java
@@ -164,4 +164,28 @@ public class AutoScaling {
       }
     }
   }
+
+  public static final String AUTO_ADD_REPLICAS_TRIGGER_DSL =
+      "{" +
+      "    'set-trigger' : {" +
+      "        'name' : '.auto_add_replicas'," +
+      "        'event' : 'nodeLost'," +
+      "        'waitFor' : '5s'," +
+      "        'enabled' : true," +
+      "        'actions' : [" +
+      "            {" +
+      "                'name':'auto_add_replicas_plan'," +
+      "                'class':'solr.AutoAddReplicasPlanAction'" +
+      "            }," +
+      "            {" +
+      "                'name':'execute_plan'," +
+      "                'class':'solr.ExecutePlanAction'" +
+      "            }," +
+      "            {" +
+      "                'name':'log_plan'," +
+      "                'class':'solr.LogPlanAction'" +
+      "            }" +
+      "        ]" +
+      "    }" +
+      "}";
 }

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/d609137a/solr/core/src/java/org/apache/solr/cloud/autoscaling/AutoScalingHandler.java
----------------------------------------------------------------------
diff --git a/solr/core/src/java/org/apache/solr/cloud/autoscaling/AutoScalingHandler.java b/solr/core/src/java/org/apache/solr/cloud/autoscaling/AutoScalingHandler.java
index f1effd3..c349a3c 100644
--- a/solr/core/src/java/org/apache/solr/cloud/autoscaling/AutoScalingHandler.java
+++ b/solr/core/src/java/org/apache/solr/cloud/autoscaling/AutoScalingHandler.java
@@ -86,6 +86,10 @@ public class AutoScalingHandler extends RequestHandlerBase implements Permission
     map.put(NAME, "log_plan");
     map.put(CLASS, "solr.LogPlanAction");
     DEFAULT_ACTIONS.add(map);
+    map = new HashMap<>(2);
+    map.put(NAME, "auto_add_replicas_plan");
+    map.put(CLASS, "solr.AutoAddReplicasPlanAction");
+    DEFAULT_ACTIONS.add(map);
   }
 
   @Override

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/d609137a/solr/core/src/test/org/apache/solr/cloud/autoscaling/AutoScalingHandlerTest.java
----------------------------------------------------------------------
diff --git a/solr/core/src/test/org/apache/solr/cloud/autoscaling/AutoScalingHandlerTest.java b/solr/core/src/test/org/apache/solr/cloud/autoscaling/AutoScalingHandlerTest.java
index 25e42eb..ff493fc 100644
--- a/solr/core/src/test/org/apache/solr/cloud/autoscaling/AutoScalingHandlerTest.java
+++ b/solr/core/src/test/org/apache/solr/cloud/autoscaling/AutoScalingHandlerTest.java
@@ -32,8 +32,11 @@ import org.apache.solr.client.solrj.impl.HttpSolrClient;
 import org.apache.solr.client.solrj.request.CollectionAdminRequest;
 import org.apache.solr.client.solrj.request.V2Request;
 import org.apache.solr.client.solrj.response.CollectionAdminResponse;
+import org.apache.solr.cloud.CreateCollectionCmd;
 import org.apache.solr.cloud.SolrCloudTestCase;
 import org.apache.solr.common.cloud.ZkNodeProps;
+import org.apache.solr.common.params.CollectionParams;
+import org.apache.solr.common.params.ModifiableSolrParams;
 import org.apache.solr.common.params.SolrParams;
 import org.apache.solr.common.util.ContentStream;
 import org.apache.solr.common.util.ContentStreamBase;
@@ -63,6 +66,47 @@ public class AutoScalingHandlerTest extends SolrCloudTestCase {
   }
 
   @Test
+  public void testAutoAddReplicas() throws Exception {
+    String collection = "test-collection";
+    CollectionAdminRequest
+        .createCollection(collection, 1, 1)
+        .setAutoAddReplicas(true)
+        .process(cluster.getSolrClient());
+    byte[] data = zkClient().getData(SOLR_AUTOSCALING_CONF_PATH, null, null, true);
+    ZkNodeProps loaded = ZkNodeProps.load(data);
+    assertNotNull(loaded.get("triggers"));
+    assertEquals("auto add replicas trigger did not created", ((Map)loaded.get("triggers")).size(), 1);
+
+    zkClient().setData(SOLR_AUTOSCALING_CONF_PATH, Utils.toJSON(new ZkNodeProps()), true);
+    new CollectionAdminRequest.AsyncCollectionAdminRequest(CollectionParams.CollectionAction.MODIFYCOLLECTION) {
+      @Override
+      public SolrParams getParams() {
+        ModifiableSolrParams params = (ModifiableSolrParams) super.getParams();
+        params.set("collection", collection);
+        params.set("autoAddReplicas", false);
+        return params;
+      }
+    }.process(cluster.getSolrClient());
+    data = zkClient().getData(SOLR_AUTOSCALING_CONF_PATH, null, null, true);
+    loaded = ZkNodeProps.load(data);
+    assertNull(loaded.get("triggers"));
+
+    new CollectionAdminRequest.AsyncCollectionAdminRequest(CollectionParams.CollectionAction.MODIFYCOLLECTION) {
+      @Override
+      public SolrParams getParams() {
+        ModifiableSolrParams params = (ModifiableSolrParams) super.getParams();
+        params.set("collection", collection);
+        params.set("autoAddReplicas", true);
+        return params;
+      }
+    }.process(cluster.getSolrClient());
+    data = zkClient().getData(SOLR_AUTOSCALING_CONF_PATH, null, null, true);
+    loaded = ZkNodeProps.load(data);
+    assertNotNull(loaded.get("triggers"));
+    assertEquals("auto add replicas trigger did not created", ((Map)loaded.get("triggers")).size(), 1);
+  }
+
+  @Test
   public void testSuspendTrigger() throws Exception {
     CloudSolrClient solrClient = cluster.getSolrClient();
     String suspendEachCommand = "{\n" +