diff options
5 files changed, 82 insertions, 105 deletions
diff --git a/container-search/src/main/java/com/yahoo/prelude/cluster/ClusterSearcher.java b/container-search/src/main/java/com/yahoo/prelude/cluster/ClusterSearcher.java index e315bee6040..9af5d5ecd7b 100644 --- a/container-search/src/main/java/com/yahoo/prelude/cluster/ClusterSearcher.java +++ b/container-search/src/main/java/com/yahoo/prelude/cluster/ClusterSearcher.java @@ -107,14 +107,14 @@ public class ClusterSearcher extends Searcher { this.hasher = new Hasher(); this.fs4ResourcePool = listeners; monitor = new ClusterMonitor(this, monitorConfig, vipStatus); - final int searchClusterIndex = clusterConfig.clusterId(); + int searchClusterIndex = clusterConfig.clusterId(); clusterModelName = clusterConfig.clusterName(); - final QrSearchersConfig.Searchcluster searchClusterConfig = getSearchClusterConfigFromClusterName(qrsConfig, clusterModelName); + QrSearchersConfig.Searchcluster searchClusterConfig = getSearchClusterConfigFromClusterName(qrsConfig, clusterModelName); documentTypes = new LinkedHashSet<>(); failoverToRemote = clusterConfig.failoverToRemote(); Dispatcher dispatcher = new Dispatcher(dispatchConfig); - final String eventName = clusterModelName + ".cache_hit_ratio"; + String eventName = clusterModelName + ".cache_hit_ratio"; cacheHitRatio = new Value(eventName, manager, new Value.Parameters() .setNameExtension(false).setLogRaw(false).setLogMean(true)); @@ -122,36 +122,35 @@ public class ClusterSearcher extends Searcher { maxQueryCacheTimeout = ParameterParser.asMilliSeconds(clusterConfig.maxQueryCacheTimeout(), DEFAULT_MAX_QUERY_CACHE_TIMEOUT); - final CacheParams cacheParams = new CacheParams(createCache(clusterConfig, clusterModelName)); - final SummaryParameters docSumParams = new SummaryParameters(qrsConfig + CacheParams cacheParams = new CacheParams(createCache(clusterConfig, clusterModelName)); + SummaryParameters docSumParams = new SummaryParameters(qrsConfig .com().yahoo().prelude().fastsearch().FastSearcher().docsum() .defaultclass()); - for (final DocumentdbInfoConfig.Documentdb docDb : documentDbConfig.documentdb()) { + for (DocumentdbInfoConfig.Documentdb docDb : documentDbConfig.documentdb()) { String docTypeName = docDb.name(); documentTypes.add(docTypeName); - for (final DocumentdbInfoConfig.Documentdb.Rankprofile profile : docDb.rankprofile()) { + for (DocumentdbInfoConfig.Documentdb.Rankprofile profile : docDb.rankprofile()) { addValidRankProfile(profile.name(), docTypeName); } } boolean gotExpectedBackend = false; if (searchClusterConfig.indexingmode() == STREAMING) { - final VdsStreamingSearcher searcher = vdsCluster(searchClusterIndex, - searchClusterConfig, cacheParams, emulationConfig, docSumParams, - documentDbConfig); + VdsStreamingSearcher searcher = vdsCluster(searchClusterIndex, + searchClusterConfig, cacheParams, emulationConfig, docSumParams, + documentDbConfig); addBackendSearcher(searcher); gotExpectedBackend = true; } else { for (int i = 0; i < searchClusterConfig.dispatcher().size(); i++) { - final Backend b = createBackend( - searchClusterConfig.dispatcher(i)); - final FastSearcher searcher = searchDispatch(searchClusterIndex, - searchClusterConfig, cacheParams, emulationConfig, docSumParams, - documentDbConfig, b, dispatcher, i); + Backend b = createBackend(searchClusterConfig.dispatcher(i)); + FastSearcher searcher = searchDispatch(searchClusterIndex, + searchClusterConfig, cacheParams, emulationConfig, docSumParams, + documentDbConfig, b, dispatcher, i); try { - searcher.setLocalDispatching(!isRemote(searchClusterConfig.dispatcher(i).host())); + searcher.setLocalDispatching( ! isRemote(searchClusterConfig.dispatcher(i).host())); } catch (UnknownHostException e) { throw new RuntimeException(e); } diff --git a/container-search/src/main/java/com/yahoo/prelude/cluster/Hasher.java b/container-search/src/main/java/com/yahoo/prelude/cluster/Hasher.java index a78b5d6e1b5..eefa90f63f0 100644 --- a/container-search/src/main/java/com/yahoo/prelude/cluster/Hasher.java +++ b/container-search/src/main/java/com/yahoo/prelude/cluster/Hasher.java @@ -44,6 +44,7 @@ public class Hasher { newNodes[oldNodes.length] = node; return newNodes; } + /** * Make a node available for search. */ @@ -78,15 +79,13 @@ public class Hasher { /** Removes a node */ public void remove(VespaBackEndSearcher node) { - if (allNodes.length == 0) { - return; - } + if (allNodes.length == 0) return; VespaBackEndSearcher[] newNodes = removeNode(node, allNodes); if (newNodes != allNodes) { if (running && newNodes.length == 0) { log.log(LogLevel.WARNING, "No longer any nodes for this cluster when" - + " removing malfunctioning " + node.toString() + "."); + + " removing malfunctioning " + node.toString() + "."); } allNodes = newNodes; } @@ -95,8 +94,8 @@ public class Hasher { if (newNodes != localNodes) { if (running && localNodes.length == 0) { log.log(LogLevel.WARNING, "Removing malfunctioning " + node.toString() - + " from traffic leaves no local dispatchers, performance" - + " degradation is to expected."); + + " from traffic leaves no local dispatchers, performance" + + " degradation is to expected."); } localNodes = newNodes; } @@ -109,26 +108,22 @@ public class Hasher { /** * Return a node, prefer local nodes, try to skip already hit nodes. * - * @param trynum - * hint to skip already used nodes + * @param trynum hint to skip already used nodes * @return the selected node, or null if this hasher has no nodes */ public VespaBackEndSearcher select(int trynum) { VespaBackEndSearcher[] nodes = allNodes; + if (nodes.length == 0) return null; - if (nodes.length == 0) { - return null; - } else { - if (localNodes.length > 0) { - nodes = localNodes; - if (localNodes.length == 1) { - return nodes[0]; - } else { - return nodes[Math.abs(avoidAllQrsHitSameTld.incrementAndGet() % nodes.length)]; - } + if (localNodes.length > 0) { + nodes = localNodes; + if (localNodes.length == 1) { + return nodes[0]; } else { return nodes[Math.abs(avoidAllQrsHitSameTld.incrementAndGet() % nodes.length)]; } + } else { + return nodes[Math.abs(avoidAllQrsHitSameTld.incrementAndGet() % nodes.length)]; } } diff --git a/container-search/src/main/java/com/yahoo/prelude/fastsearch/VespaBackEndSearcher.java b/container-search/src/main/java/com/yahoo/prelude/fastsearch/VespaBackEndSearcher.java index e589f85cc96..ce9a8e6b8c6 100644 --- a/container-search/src/main/java/com/yahoo/prelude/fastsearch/VespaBackEndSearcher.java +++ b/container-search/src/main/java/com/yahoo/prelude/fastsearch/VespaBackEndSearcher.java @@ -644,10 +644,13 @@ public abstract class VespaBackEndSearcher extends PingableSearcher { protected boolean isLoggingFine() { return getLogger().isLoggable(Level.FINE); } + public boolean isLocalDispatching() { return localDispatching; } + public void setLocalDispatching(boolean localDispatching) { this.localDispatching = localDispatching; } + } diff --git a/container-search/src/main/java/com/yahoo/search/cluster/ClusterSearcher.java b/container-search/src/main/java/com/yahoo/search/cluster/ClusterSearcher.java index 67f946f62c6..893d6193bef 100644 --- a/container-search/src/main/java/com/yahoo/search/cluster/ClusterSearcher.java +++ b/container-search/src/main/java/com/yahoo/search/cluster/ClusterSearcher.java @@ -35,19 +35,15 @@ import java.util.concurrent.*; */ public abstract class ClusterSearcher<T> extends PingableSearcher implements NodeManager<T> { - private Hasher<T> hasher = new Hasher<>(); - private ClusterMonitor<T> monitor = new ClusterMonitor<>(this, "dummy"); + private final Hasher<T> hasher; + private final ClusterMonitor<T> monitor = new ClusterMonitor<>(this, "dummy"); /** * Creates a new cluster searcher * - * @param id - * the id of this searcher - * @param connections - * the connections of the cluster - * @param internal - * whether or not this cluster is internal (part of the same - * installation) + * @param id the id of this searcher + * @param connections the connections of the cluster + * @param internal whether or not this cluster is internal (part of the same installation) */ public ClusterSearcher(ComponentId id, List<T> connections, boolean internal) { this(id, connections, new Hasher<T>(), internal); @@ -63,10 +59,10 @@ public abstract class ClusterSearcher<T> extends PingableSearcher implements Nod } /** - * Pinging a node by sending a query NodeManager method, called from - * ClusterMonitor + * Pinging a node by sending a query NodeManager method, called from ClusterMonitor */ - public final @Override void ping(T p, Executor executor) { + @Override + public final void ping(T p, Executor executor) { log(LogLevel.FINE, "Sending ping to: ", p); Pinger pinger = new Pinger(p); FutureTask<Pong> future = new FutureTask<>(pinger); @@ -76,26 +72,22 @@ public abstract class ClusterSearcher<T> extends PingableSearcher implements Nod Throwable logThrowable = null; try { - pong = future.get(monitor.getConfiguration().getFailLimit(), - TimeUnit.MILLISECONDS); + pong = future.get(monitor.getConfiguration().getFailLimit(), TimeUnit.MILLISECONDS); } catch (InterruptedException e) { pong = new Pong(); - pong.addError(ErrorMessage - .createUnspecifiedError("Ping was interrupted: " + p)); + pong.addError(ErrorMessage.createUnspecifiedError("Ping was interrupted: " + p)); logThrowable = e; } catch (ExecutionException e) { pong = new Pong(); - pong.addError(ErrorMessage - .createUnspecifiedError("Execution was interrupted: " + p)); + pong.addError(ErrorMessage.createUnspecifiedError("Execution was interrupted: " + p)); logThrowable = e; } catch (LinkageError e) { // Typically Osgi woes pong = new Pong(); pong.addError(ErrorMessage.createErrorInPluginSearcher("Class loading problem",e)); - logThrowable=e; + logThrowable = e; } catch (TimeoutException e) { pong = new Pong(); - pong.addError(ErrorMessage - .createNoAnswerWhenPingingNode("Ping thread timed out.")); + pong.addError(ErrorMessage.createNoAnswerWhenPingingNode("Ping thread timed out.")); } future.cancel(true); @@ -107,32 +99,24 @@ public abstract class ClusterSearcher<T> extends PingableSearcher implements Nod log(LogLevel.FINE, "Answered ping - ", p); } - if (logThrowable != null) { // This looks strange, but yes - it is - // needed - String logMsg; - if (logThrowable instanceof TimeoutException) { - logMsg = "Ping timed out for " + getId().getName() + "."; - } else { - StackTraceElement[] trace = logThrowable.getStackTrace(); - String traceAsString = null; - if (trace != null) { - StringBuilder b = new StringBuilder(": "); - for (StackTraceElement k : trace) { - if (k == null) { - b.append("null\n"); - } else { - b.append(k.toString()).append('\n'); - } + if (logThrowable != null) { + StackTraceElement[] trace = logThrowable.getStackTrace(); + String traceAsString = null; + if (trace != null) { + StringBuilder b = new StringBuilder(": "); + for (StackTraceElement k : trace) { + if (k == null) { + b.append("null\n"); + } else { + b.append(k.toString()).append('\n'); } - traceAsString = b.toString(); } - logMsg = "Caught " + logThrowable.getClass().getName() - + " exception in " + getId().getName() + " ping" - + (trace == null ? ", no stack trace available." : traceAsString); + traceAsString = b.toString(); } - getLogger().warning(logMsg); + getLogger().warning("Caught " + logThrowable.getClass().getName() + + " exception in " + getId().getName() + " ping" + + (trace == null ? ", no stack trace available." : traceAsString)); } - } /** @@ -162,8 +146,7 @@ public abstract class ClusterSearcher<T> extends PingableSearcher implements Nod Result result; T connection = getFirstConnection(nodes, code, tries, query); do { - // The loop is in case there are other searchers available - // able to produce results + // The loop is in case there are other searchers available able to produce results if (connection == null) return search(query, execution, ErrorMessage .createNoBackendsInService("No in node could handle " + query + " according to " + @@ -298,47 +281,37 @@ public abstract class ClusterSearcher<T> extends PingableSearcher implements Nod * Perform the fill against the given connection. Add an error to the result * or throw an exception on failures. */ - protected abstract void fill(Result result, String summaryClass, - Execution execution, T connection); + protected abstract void fill(Result result, String summaryClass, Execution execution, T connection); /** NodeManager method, called from ClusterMonitor */ - public @Override - void working(T node) { + @Override + public void working(T node) { getHasher().add(node); } /** NodeManager method, called from ClusterMonitor */ - public @Override - void failed(T node) { + @Override + public void failed(T node) { getHasher().remove(node); } - /** - * Returns the hasher used internally in this. Do not mutate this hasher - * while in use. - */ - public Hasher<T> getHasher() { - return hasher; - } + /** Returns the hasher used internally in this. Do not mutate this hasher while in use. */ + public Hasher<T> getHasher() { return hasher; } /** Returns the monitor of these nodes */ - public ClusterMonitor<T> getMonitor() { - return monitor; - } + public ClusterMonitor<T> getMonitor() { return monitor; } /** Returns true if this query has timed out now */ protected boolean timedOut(Query query) { - long duration = query.getDurationTime(); - return duration >= query.getTimeout(); + return query.getDurationTime() >= query.getTimeout(); } protected void log(java.util.logging.Level level, Object... objects) { - if (!getLogger().isLoggable(level)) - return; + if ( ! getLogger().isLoggable(level)) return; + StringBuilder sb = new StringBuilder(); - for (Object object : objects) { + for (Object object : objects) sb.append(object); - } getLogger().log(level, sb.toString()); } diff --git a/container-search/src/main/java/com/yahoo/search/cluster/Hasher.java b/container-search/src/main/java/com/yahoo/search/cluster/Hasher.java index 7ef71a7968d..dd238e4fccf 100644 --- a/container-search/src/main/java/com/yahoo/search/cluster/Hasher.java +++ b/container-search/src/main/java/com/yahoo/search/cluster/Hasher.java @@ -12,20 +12,26 @@ public class Hasher<T> { public static class NodeFactor<T> { private final T node; + /** * The relative weight of the different nodes. * Hashing are based on the proportions of the weights. */ private final int load; + public NodeFactor(T node, int load) { this.node = node; this.load = load; } + public final T getNode() { return node; } - public final int getLoad() { return load; } + + public final int getLoad() { return load; } + } public static class NodeList<T> { + private final NodeFactor<T>[] nodes; private int totalLoadFactor; @@ -44,18 +50,19 @@ public class Hasher<T> { return nodes.length; } - public T select(int code, int trynum) { + public T select(int code, int trynum) { if (totalLoadFactor <= 0) return null; // Multiply by a prime number much bigger than the likely number of hosts int hashValue=(Math.abs(code*76103)) % totalLoadFactor; int sumLoad=0; - int targetNode=0; + int targetNode; for (targetNode=0; targetNode<nodes.length; targetNode++) { sumLoad +=nodes[targetNode].getLoad(); if (sumLoad > hashValue) break; } + // Skip the ones we have tried before. targetNode += trynum; targetNode %= nodes.length; @@ -63,7 +70,7 @@ public class Hasher<T> { } public boolean hasNode(T node) { - for(int i = 0;i<nodes.length;i++) { + for (int i = 0;i<nodes.length;i++) { if(node == nodes[i].getNode()) { return true; } |