Revert "Merge branch 'feature/SEARCH-1738_ShardingParams' into 'master'"

This reverts commit 0b375ed23afd377dd36c6a20bf74d384b2f35f91, reversing
changes made to 558925e169cbaa93b3d44ae89e3c49dbb12ab830.
This commit is contained in:
Tom Page
2019-07-26 16:25:27 +01:00
parent 43b1639ce6
commit 2e36156138
7 changed files with 66 additions and 120 deletions
@@ -18,15 +18,11 @@
*/
package org.alfresco.solr.tracker;
import java.util.Map;
import org.alfresco.solr.client.Node;
import org.alfresco.solr.client.Acl;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicLong;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import org.alfresco.service.namespace.QName;
import org.alfresco.solr.client.Acl;
import org.alfresco.solr.client.Node;
/**
* This routes documents within specific DBID ranges to specific shards.
@@ -108,13 +104,4 @@ public class DBIDRangeRouter implements DocRouter
long dbid = node.getId();
return dbid >= startRange && dbid < expandableRange.longValue();
}
@Override
public Map<String, String> getProperties(QName shardProperty)
{
return Stream.of(new String[][] {
{ DocRouterFactory.SHARD_RANGE_KEY, startRange + "-" + expandableRange },
}).collect(Collectors.toMap(data -> data[0], data -> data[1]));
}
}
@@ -20,7 +20,6 @@ package org.alfresco.solr.tracker;
import org.alfresco.util.ISO8601DateFormat;
import org.alfresco.solr.client.Node;
import org.alfresco.service.namespace.QName;
import org.alfresco.solr.client.Acl;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -28,9 +27,6 @@ import org.slf4j.LoggerFactory;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.Map;
import java.util.stream.Collectors;
import java.util.stream.Stream;
/**
* The date-based sharding assigns dates sequentially through shards based on the month.
@@ -120,14 +116,4 @@ public class DateMonthRouter implements DocRouter
return dbidRouter.routeNode(numShards, shardInstance, node);
}
}
@Override
public Map<String, String> getProperties(QName shardProperty)
{
return Stream.of(new String[][] {
{ DocRouterFactory.SHARD_KEY_KEY, shardProperty.getPrefixString() },
{ DocRouterFactory.SHARD_DATE_GROUPING_KEY, String.valueOf(grouping) },
}).collect(Collectors.toMap(data -> data[0], data -> data[1]));
}
}
@@ -19,11 +19,6 @@
package org.alfresco.solr.tracker;
import org.alfresco.solr.client.Node;
import java.util.Collections;
import java.util.Map;
import org.alfresco.service.namespace.QName;
import org.alfresco.solr.client.Acl;
/**
@@ -63,15 +58,4 @@ public interface DocRouter
* @return true if the {@link Node} instance must be indexed in the shard which owns this {@link DocRouter} instance, false otherwise.
*/
Boolean routeNode(int shardCount, int shardInstance, Node node);
/**
* Get additional properties to "shardProperty" depending on the Shard Method
* @param shardProperty custom property used to configure the Router
* @return pair of key, value
*/
default public Map<String, String> getProperties(QName shardProperty) {
return Collections.emptyMap();
}
}
}
@@ -24,60 +24,59 @@ import org.slf4j.LoggerFactory;
import java.util.Properties;
/*
/**
* Routing strategy Factory.
*
* @author Joel
*/
public class DocRouterFactory
{
protected final static Logger log = LoggerFactory.getLogger(DocRouterFactory.class);
public static final String SHARD_KEY_KEY = "shard.key";
public static final String SHARD_RANGE_KEY = "shard.range";
public static final String SHARD_DATE_GROUPING_KEY = "shard.date.grouping";
public static final String SHARD_REGEX_KEY = "shard.regex";
private final static Logger LOGGER = LoggerFactory.getLogger(DocRouterFactory.class);
public static DocRouter getRouter(Properties properties, ShardMethodEnum method) {
switch(method) {
public static DocRouter getRouter(Properties properties, ShardMethodEnum method)
{
switch(method)
{
case DB_ID:
log.info("Sharding via DB_ID");
LOGGER.info("Sharding via DB_ID");
return new DBIDRouter();
case DB_ID_RANGE:
//
if(properties.containsKey(SHARD_RANGE_KEY))
if(properties.containsKey("shard.range"))
{
log.info("Sharding via DB_ID_RANGE");
String[] pair =properties.getProperty(SHARD_RANGE_KEY).split("-");
LOGGER.info("Sharding via DB_ID_RANGE");
String[] pair =properties.getProperty("shard.range").split("-");
long start = Long.parseLong(pair[0]);
long end = Long.parseLong(pair[1]);
return new DBIDRangeRouter(start, end);
}
case ACL_ID:
log.info("Sharding via ACL_ID");
LOGGER.info("Sharding via ACL_ID");
return new ACLIDMurmurRouter();
case MOD_ACL_ID:
log.info("Sharding via MOD_ACL_ID");
LOGGER.info("Sharding via MOD_ACL_ID");
return new ACLIDModRouter();
case DATE:
log.info("Sharding via DATE");
return new DateMonthRouter(properties.getProperty(SHARD_DATE_GROUPING_KEY, "1"));
LOGGER.info("Sharding via DATE");
return new DateMonthRouter(properties.getProperty("shard.date.grouping", "1"));
case PROPERTY:
log.info("Sharding via PROPERTY");
return new PropertyRouter(properties.getProperty(SHARD_REGEX_KEY, ""));
LOGGER.info("Sharding via PROPERTY");
return new PropertyRouter(properties.getProperty("shard.regex", ""));
case LAST_REGISTERED_INDEXING_SHARD:
log.info("Sharding via LAST_REGISTERED_INDEXING_SHARD");
return new LastRegisteredShardRouter();
LOGGER.info("Sharding via LAST_REGISTERED_INDEXING_SHARD");
return new ExplicitShardIdWithStaticPropertyRouter();
case EXPLICIT_ID_FALLBACK_LRIS:
log.info("Sharding via EXPLICIT_ID_FALLBACK_LRIS");
return new ExplicitRouter(new LastRegisteredShardRouter());
LOGGER.info("Sharding via EXPLICIT_ID_FALLBACK_LRIS");
return new DocRouterWithFallback(
new ExplicitShardIdWithDynamicPropertyRouter(false),
new ExplicitShardIdWithStaticPropertyRouter());
case EXPLICIT_ID:
log.info("Sharding via EXPLICIT_ID");
return new ExplicitRouter(new DBIDRouter());
LOGGER.info("Sharding via EXPLICIT_ID");
return new DocRouterWithFallback(
new ExplicitShardIdWithDynamicPropertyRouter(false),
new DBIDRouter());
default:
log.info("Sharding via DB_ID (default)");
LOGGER.warn("WARNING! Unknown/unsupported sharding method ({}). System will fallback to DB_ID", method);
return new DBIDRouter();
}
}
}
@@ -18,11 +18,6 @@
*/
package org.alfresco.solr.tracker;
import java.util.Map;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import org.alfresco.service.namespace.QName;
import org.alfresco.solr.client.Acl;
import org.alfresco.solr.client.Node;
@@ -77,13 +72,4 @@ public class ExplicitShardIdWithDynamicPropertyRouter extends ComposableDocRoute
return negativeReturnValue();
}
}
@Override
public Map<String, String> getProperties(QName shardProperty)
{
return Stream.of(new String[][] {
{ DocRouterFactory.SHARD_KEY_KEY, shardProperty.getPrefixString() },
}).collect(Collectors.toMap(data -> data[0], data -> data[1]));
}
}
@@ -86,10 +86,11 @@ public class MetadataTracker extends AbstractTracker implements Tracker
super(p, client, coreName, informationServer, Tracker.Type.MetaData);
transactionDocsBatchSize = Integer.parseInt(p.getProperty("alfresco.transactionDocsBatchSize", "100"));
shardMethod = p.getProperty("shard.method", SHARD_METHOD_DBID);
String shardKey = p.getProperty(DocRouterFactory.SHARD_KEY_KEY);
String shardKey = p.getProperty("shard.key");
if(shardKey != null) {
shardProperty = getShardProperty(shardKey);
}
docRouter = DocRouterFactory.getRouter(p, ShardMethodEnum.getShardMethod(shardMethod));
nodeBatchSize = Integer.parseInt(p.getProperty("alfresco.nodeBatchSize", "10"));
threadHandler = new ThreadHandler(p, coreName, "MetadataTracker");
@@ -223,8 +224,7 @@ public class MetadataTracker extends AbstractTracker implements Tracker
HashMap<String, String> propertyBag = new HashMap<>();
propertyBag.put("coreName", coreName);
propertyBag.putAll(docRouter.getProperties(shardProperty));
return ShardStateBuilder.shardState()
.withMaster(isMaster)
.withLastUpdated(System.currentTimeMillis())
@@ -19,58 +19,72 @@
package org.alfresco.solr.tracker;
import org.alfresco.repo.index.shard.ShardMethodEnum;
import org.alfresco.service.namespace.QName;
import org.alfresco.solr.client.Acl;
import org.alfresco.solr.client.Node;
import org.apache.solr.common.util.Hash;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
import java.util.stream.Stream;
/**
* Routes based on a text property field.
* In this method, the value of some property is hashed and this hash is used to assign the node to a random shard.
* All nodes with the same property value will be assigned to the same shard.
* Each shard will duplicate all the ACL information.
*
* To use this method, when creating a shard add the new configuration properties:
*
* <ul>
* <li>shard.key=cm:creator</li>
* <li>shard.method=PROPERTY</li>
* <li>shard.instance=&lt;shard.instance></li>
* <li>shard.count=&lt;shard.count></li>
* </ul>
*
* It is possible to extract a part of the property value to use for sharding using a regular expression,
* for example, a year at the start of a string:
*
* <ul>
* <li>shard.regex=^\d{4}</li>
* </ul>
*
* @author Gethin James
* @see <a href="https://docs.alfresco.com/search-enterprise/concepts/solr-shard-approaches.html">Search Services sharding methods</a>
*/
public class PropertyRouter implements DocRouter
{
protected final static Logger log = LoggerFactory.getLogger(PropertyRouter.class);
private final static Logger LOGGER = LoggerFactory.getLogger(PropertyRouter.class);
Pattern pattern = null;
private String propertyRegEx;
Pattern pattern;
//Fallback to DB_ID routing
private DocRouter fallback = DocRouterFactory.getRouter(null, ShardMethodEnum.DB_ID);
DocRouter fallback = DocRouterFactory.getRouter(null, ShardMethodEnum.DB_ID);
public PropertyRouter(String propertyRegEx)
{
if (propertyRegEx != null && !propertyRegEx.isEmpty())
if (propertyRegEx != null && propertyRegEx.trim().length() > 0)
{
this.propertyRegEx = propertyRegEx;
pattern = Pattern.compile(propertyRegEx);
pattern = Pattern.compile(propertyRegEx.trim());
}
}
@Override
public boolean routeAcl(int shardCount, int shardInstance, Acl acl)
public Boolean routeAcl(int shardCount, int shardInstance, Acl acl)
{
return true;
}
@Override
public boolean routeNode(int shardCount, int shardInstance, Node node)
public Boolean routeNode(int shardCount, int shardInstance, Node node)
{
if(shardCount <= 1)
{
return true;
}
String shardBy = node.getShardPropertyValue();
String shardBy = node.getShardPropertyValue();
if (shardBy !=null && pattern != null)
{
try
@@ -88,27 +102,17 @@ public class PropertyRouter implements DocRouter
}
catch (IndexOutOfBoundsException | NullPointerException exc)
{
log.debug("Regex matched, but group 1 not found, so falling back to DBID sharding.");
LOGGER.debug("Regex matched, but group 1 not found, so falling back to DBID sharding.");
shardBy = null;
}
}
if (shardBy == null || shardBy.isEmpty())
{
log.debug("Property not found or regex not matched, so falling back to DBID sharding.");
LOGGER.debug("Property not found or regex not matched, so falling back to DBID sharding.");
return fallback.routeNode(shardCount,shardInstance,node);
}
return (Math.abs(Hash.murmurhash3_x86_32(shardBy, 0, shardBy.length(), 66)) % shardCount) == shardInstance;
}
@Override
public Map<String, String> getProperties(QName shardProperty)
{
return Stream.of(new String[][] {
{ DocRouterFactory.SHARD_KEY_KEY, shardProperty.getPrefixString() },
{ DocRouterFactory.SHARD_REGEX_KEY, propertyRegEx },
}).collect(Collectors.toMap(data -> data[0], data -> data[1]));
}
}