summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHenning Baldersheim <balder@yahoo-inc.com>2020-06-30 22:13:14 +0000
committerHenning Baldersheim <balder@yahoo-inc.com>2020-06-30 22:13:14 +0000
commit2ef3ab5fa7017e5fea5cdec223bcf98a9edf7550 (patch)
tree45bf1600236c9e14d12d3c1c3f18121c1153d927
parentaac7958354aab414dc036a82dcf493a749d6f1d5 (diff)
Add support for serializing and compressing once, instead of once per backend node.
-rw-r--r--container-disc/src/main/java/com/yahoo/container/jdisc/metric/MetricUpdater.java1
-rw-r--r--container-search/src/main/java/com/yahoo/search/dispatch/InterleavedSearchInvoker.java6
-rw-r--r--container-search/src/main/java/com/yahoo/search/dispatch/SearchErrorInvoker.java5
-rw-r--r--container-search/src/main/java/com/yahoo/search/dispatch/SearchInvoker.java12
-rw-r--r--container-search/src/main/java/com/yahoo/search/dispatch/rpc/ProtobufSerialization.java3
-rw-r--r--container-search/src/main/java/com/yahoo/search/dispatch/rpc/RpcSearchInvoker.java28
-rw-r--r--container-search/src/test/java/com/yahoo/search/dispatch/MockInvoker.java3
-rw-r--r--container-search/src/test/java/com/yahoo/search/dispatch/rpc/RpcSearchInvokerTest.java13
-rw-r--r--container-search/src/test/java/com/yahoo/search/searchchain/config/test/SearchChainConfigurerTestCase.java40
-rw-r--r--processing/src/main/java/com/yahoo/processing/request/CompoundName.java6
10 files changed, 85 insertions, 32 deletions
diff --git a/container-disc/src/main/java/com/yahoo/container/jdisc/metric/MetricUpdater.java b/container-disc/src/main/java/com/yahoo/container/jdisc/metric/MetricUpdater.java
index e11622b1fa3..05c3b88b788 100644
--- a/container-disc/src/main/java/com/yahoo/container/jdisc/metric/MetricUpdater.java
+++ b/container-disc/src/main/java/com/yahoo/container/jdisc/metric/MetricUpdater.java
@@ -97,7 +97,6 @@ public class MetricUpdater extends AbstractComponent {
this.jrtMetrics = new JrtMetrics(metric);
}
- @SuppressWarnings("deprecation")
@Override
public void run() {
long freeMemory = runtime.freeMemory();
diff --git a/container-search/src/main/java/com/yahoo/search/dispatch/InterleavedSearchInvoker.java b/container-search/src/main/java/com/yahoo/search/dispatch/InterleavedSearchInvoker.java
index e62848a7f9e..d8fb7b46440 100644
--- a/container-search/src/main/java/com/yahoo/search/dispatch/InterleavedSearchInvoker.java
+++ b/container-search/src/main/java/com/yahoo/search/dispatch/InterleavedSearchInvoker.java
@@ -74,7 +74,7 @@ public class InterleavedSearchInvoker extends SearchInvoker implements ResponseM
* will be adjusted accordingly.
*/
@Override
- protected void sendSearchRequest(Query query) throws IOException {
+ protected Object sendSearchRequest(Query query, Object unusedContext) throws IOException {
this.query = query;
invokers.forEach(invoker -> invoker.setMonitor(this));
deadline = currentTime() + query.getTimeLeft();
@@ -89,13 +89,15 @@ public class InterleavedSearchInvoker extends SearchInvoker implements ResponseM
query.setHits(q);
query.setOffset(0);
+ Object context = null;
for (SearchInvoker invoker : invokers) {
- invoker.sendSearchRequest(query);
+ context = invoker.sendSearchRequest(query, context);
askedNodes++;
}
query.setHits(originalHits);
query.setOffset(originalOffset);
+ return null;
}
@Override
diff --git a/container-search/src/main/java/com/yahoo/search/dispatch/SearchErrorInvoker.java b/container-search/src/main/java/com/yahoo/search/dispatch/SearchErrorInvoker.java
index a32931c43c8..256759360f7 100644
--- a/container-search/src/main/java/com/yahoo/search/dispatch/SearchErrorInvoker.java
+++ b/container-search/src/main/java/com/yahoo/search/dispatch/SearchErrorInvoker.java
@@ -35,11 +35,12 @@ public class SearchErrorInvoker extends SearchInvoker {
}
@Override
- protected void sendSearchRequest(Query query) throws IOException {
+ protected Object sendSearchRequest(Query query, Object context) throws IOException {
this.query = query;
- if(monitor != null) {
+ if (monitor != null) {
monitor.responseAvailable(this);
}
+ return context;
}
@Override
diff --git a/container-search/src/main/java/com/yahoo/search/dispatch/SearchInvoker.java b/container-search/src/main/java/com/yahoo/search/dispatch/SearchInvoker.java
index 45ed1b87746..9fd6ae9063c 100644
--- a/container-search/src/main/java/com/yahoo/search/dispatch/SearchInvoker.java
+++ b/container-search/src/main/java/com/yahoo/search/dispatch/SearchInvoker.java
@@ -32,14 +32,22 @@ public abstract class SearchInvoker extends CloseableInvoker {
* for correct result windowing.
*/
public Result search(Query query, Execution execution) throws IOException {
- sendSearchRequest(query);
+ sendSearchRequest(query, null);
InvokerResult result = getSearchResult(execution);
setFinalStatus(result.getResult().hits().getError() == null);
result.complete();
return result.getResult();
}
- protected abstract void sendSearchRequest(Query query) throws IOException;
+ /**
+ *
+ * @param query The query to send
+ * @param context A context object that can be used to pass context among different
+ * invokers. Fx for reuse of preserialized data.
+ * @return An object that can be passed to the next invocation of sendSearchRequest
+ * @throws IOException
+ */
+ protected abstract Object sendSearchRequest(Query query, Object context) throws IOException;
protected abstract InvokerResult getSearchResult(Execution execution) throws IOException;
diff --git a/container-search/src/main/java/com/yahoo/search/dispatch/rpc/ProtobufSerialization.java b/container-search/src/main/java/com/yahoo/search/dispatch/rpc/ProtobufSerialization.java
index 51290c245ac..d13f04ea85e 100644
--- a/container-search/src/main/java/com/yahoo/search/dispatch/rpc/ProtobufSerialization.java
+++ b/container-search/src/main/java/com/yahoo/search/dispatch/rpc/ProtobufSerialization.java
@@ -91,7 +91,8 @@ public class ProtobufSerialization {
return traceLevel;
}
- private static void mergeToSearchRequestFromRanking(Ranking ranking, SearchProtocol.SearchRequest.Builder builder) {
+ private static void
+ mergeToSearchRequestFromRanking(Ranking ranking, SearchProtocol.SearchRequest.Builder builder) {
builder.setRankProfile(ranking.getProfile());
if (ranking.getQueryCache()) {
diff --git a/container-search/src/main/java/com/yahoo/search/dispatch/rpc/RpcSearchInvoker.java b/container-search/src/main/java/com/yahoo/search/dispatch/rpc/RpcSearchInvoker.java
index 76240e55c98..e1e3389eb5a 100644
--- a/container-search/src/main/java/com/yahoo/search/dispatch/rpc/RpcSearchInvoker.java
+++ b/container-search/src/main/java/com/yahoo/search/dispatch/rpc/RpcSearchInvoker.java
@@ -44,22 +44,40 @@ public class RpcSearchInvoker extends SearchInvoker implements Client.ResponseRe
this.maxHits = maxHits;
}
+ static class Context {
+ final Compressor.Compression compressionResult;
+ final int payloadLength;
+ Context(RpcResourcePool resourcePool, Query query, byte [] payload) {
+ this.payloadLength = payload.length;
+ compressionResult = resourcePool.compress(query, payload);
+ }
+ }
+
@Override
- protected void sendSearchRequest(Query query) {
+ protected Object sendSearchRequest(Query query, Object context_in) {
this.query = query;
Client.NodeConnection nodeConnection = resourcePool.getConnection(node.key());
if (nodeConnection == null) {
responses.add(Client.ResponseOrError.fromError("Could not send search to unknown node " + node.key()));
responseAvailable();
- return;
+ return context_in;
}
query.trace(false, 5, "Sending search request with jrt/protobuf to node with dist key ", node.key());
- var payload = ProtobufSerialization.serializeSearchRequest(query, Math.min(query.getHits(), maxHits), searcher.getServerId());
+ Context context;
+ if (context_in instanceof Context) {
+ context = (Context) context_in;
+ } else {
+ context = new Context(resourcePool, query,
+ ProtobufSerialization.serializeSearchRequest(query,
+ Math.min(query.getHits(), maxHits),
+ searcher.getServerId()));
+ }
double timeoutSeconds = ((double) query.getTimeLeft() - 3.0) / 1000.0;
- Compressor.Compression compressionResult = resourcePool.compress(query, payload);
- nodeConnection.request(RPC_METHOD, compressionResult.type(), payload.length, compressionResult.data(), this, timeoutSeconds);
+ nodeConnection.request(RPC_METHOD, context.compressionResult.type(), context.payloadLength,
+ context.compressionResult.data(), this, timeoutSeconds);
+ return context;
}
@Override
diff --git a/container-search/src/test/java/com/yahoo/search/dispatch/MockInvoker.java b/container-search/src/test/java/com/yahoo/search/dispatch/MockInvoker.java
index c159293d7d9..459dcc83ab0 100644
--- a/container-search/src/test/java/com/yahoo/search/dispatch/MockInvoker.java
+++ b/container-search/src/test/java/com/yahoo/search/dispatch/MockInvoker.java
@@ -34,9 +34,10 @@ class MockInvoker extends SearchInvoker {
}
@Override
- protected void sendSearchRequest(Query query) throws IOException {
+ protected Object sendSearchRequest(Query query, Object context) throws IOException {
this.query = query;
hitsRequested = query.getHits();
+ return context;
}
@Override
diff --git a/container-search/src/test/java/com/yahoo/search/dispatch/rpc/RpcSearchInvokerTest.java b/container-search/src/test/java/com/yahoo/search/dispatch/rpc/RpcSearchInvokerTest.java
index ce19224b35f..153e462a410 100644
--- a/container-search/src/test/java/com/yahoo/search/dispatch/rpc/RpcSearchInvokerTest.java
+++ b/container-search/src/test/java/com/yahoo/search/dispatch/rpc/RpcSearchInvokerTest.java
@@ -20,6 +20,7 @@ import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicReference;
import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertSame;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
@@ -38,7 +39,9 @@ public class RpcSearchInvokerTest {
var invoker = new RpcSearchInvoker(mockSearcher(), new Node(7, "seven", 1), mockPool, 1000);
Query q = new Query("search/?query=test&hits=10&offset=3");
- invoker.sendSearchRequest(q);
+ RpcSearchInvoker.Context context = (RpcSearchInvoker.Context) invoker.sendSearchRequest(q, null);
+ assertTrue( context.payloadLength == lengthHolder.get());
+ assertSame(context.compressionResult.data(), payloadHolder.get());
var bytes = mockPool.compressor().decompress(payloadHolder.get(), compressionTypeHolder.get(), lengthHolder.get());
var request = SearchProtocol.SearchRequest.newBuilder().mergeFrom(bytes).build();
@@ -46,6 +49,12 @@ public class RpcSearchInvokerTest {
assertEquals(10, request.getHits());
assertEquals(3, request.getOffset());
assertTrue(request.getQueryTreeBlob().size() > 0);
+
+ var invoker2 = new RpcSearchInvoker(mockSearcher(), new Node(8, "eight", 1), mockPool, 1000);
+ RpcSearchInvoker.Context context2 = (RpcSearchInvoker.Context)invoker2.sendSearchRequest(q, context);
+ assertSame(context, context2);
+ assertTrue( context.payloadLength == lengthHolder.get());
+ assertSame(context.compressionResult.data(), payloadHolder.get());
}
@Test
@@ -59,7 +68,7 @@ public class RpcSearchInvokerTest {
var invoker = new RpcSearchInvoker(mockSearcher(), new Node(7, "seven", 1), mockPool, maxHits);
Query q = new Query("search/?query=test&hits=10&offset=3");
- invoker.sendSearchRequest(q);
+ invoker.sendSearchRequest(q, null);
var bytes = mockPool.compressor().decompress(payloadHolder.get(), compressionTypeHolder.get(), lengthHolder.get());
var request = SearchProtocol.SearchRequest.newBuilder().mergeFrom(bytes).build();
diff --git a/container-search/src/test/java/com/yahoo/search/searchchain/config/test/SearchChainConfigurerTestCase.java b/container-search/src/test/java/com/yahoo/search/searchchain/config/test/SearchChainConfigurerTestCase.java
index a57ed07017f..5b16802a65e 100644
--- a/container-search/src/test/java/com/yahoo/search/searchchain/config/test/SearchChainConfigurerTestCase.java
+++ b/container-search/src/test/java/com/yahoo/search/searchchain/config/test/SearchChainConfigurerTestCase.java
@@ -18,13 +18,29 @@ import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Test;
-import java.io.*;
-import java.util.*;
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.OutputStream;
+import java.io.OutputStreamWriter;
+import java.io.Writer;
+import java.nio.charset.StandardCharsets;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+import java.util.Random;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import static org.hamcrest.CoreMatchers.*;
-import static org.junit.Assert.*;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.assertThat;
/**
* @author bratseth
@@ -32,8 +48,8 @@ import static org.junit.Assert.*;
*/
public class SearchChainConfigurerTestCase {
- private static Random random = new Random(1);
- private static String topCfgDir = System.getProperty("java.io.tmpdir") + File.separator +
+ private static final Random random = new Random(1);
+ private static final String topCfgDir = System.getProperty("java.io.tmpdir") + File.separator +
"SearchChainConfigurerTestCase" + File.separator;
private static final String testDir = "src/test/java/com/yahoo/search/searchchain/config/test/";
@@ -132,7 +148,7 @@ public class SearchChainConfigurerTestCase {
* that does not contain any bootstrap configs.
*/
@Test
- public void testSearcherConfigUpdate() throws IOException, InterruptedException {
+ public void testSearcherConfigUpdate() throws IOException {
File cfgDir = getCfgDir();
copyFile(testDir + "handlers.cfg", cfgDir + "/handlers.cfg");
copyFile(testDir + "qr-search.cfg", cfgDir + "/qr-search.cfg");
@@ -171,9 +187,9 @@ public class SearchChainConfigurerTestCase {
// Searchers with unchanged config (or that takes no config) are the same as before.
Searcher s = searchers.getComponent(DeclaredTestSearcher.class.getName());
- assertThat((DeclaredTestSearcher)s, sameInstance(noConfigSearcher));
+ assertThat(s, sameInstance(noConfigSearcher));
s = searchers.getComponent(StringSearcher.class.getName());
- assertThat((StringSearcher)s, sameInstance(stringSearcher));
+ assertThat(s, sameInstance(stringSearcher));
configurer.shutdown();
cleanup(cfgDir);
@@ -219,7 +235,7 @@ public class SearchChainConfigurerTestCase {
assertThat(getSearchChainRegistryFrom(configurer).getSearcherRegistry(), not(searchers));
searchers = getSearchChainRegistryFrom(configurer).getSearcherRegistry();
assertThat(searchers.getComponentCount(), is(3));
- assertThat((IntSearcher)searchers.getComponent(IntSearcher.class.getName()), sameInstance(intSearcher));
+ assertThat(searchers.getComponent(IntSearcher.class.getName()), sameInstance(intSearcher));
assertThat(searchers.getComponent(ConfigurableSearcher.class.getName()), instanceOf(ConfigurableSearcher.class));
assertThat(searchers.getComponent(DeclaredTestSearcher.class.getName()), instanceOf(DeclaredTestSearcher.class));
assertThat(searchers.getComponent(StringSearcher.class.getName()), nullValue());
@@ -326,7 +342,7 @@ public class SearchChainConfigurerTestCase {
if (append) {
Pattern p = Pattern.compile("^[a-z]+" + "\\[\\d+\\]\\.id (.+)");
BufferedReader reader = new BufferedReader(new InputStreamReader(
- new FileInputStream(new File(componentsFile)), "UTF-8"));
+ new FileInputStream(new File(componentsFile)), StandardCharsets.UTF_8));
while ((line = reader.readLine()) != null) {
Matcher m = p.matcher(line);
if (m.matches() && !m.group(1).equals(HandlersConfigurerDi.RegistriesHack.class.getName())) {
@@ -337,7 +353,7 @@ public class SearchChainConfigurerTestCase {
reader.close();
}
BufferedReader reader = new BufferedReader(new InputStreamReader(
- new FileInputStream(new File(configFile)), "UTF-8"));
+ new FileInputStream(new File(configFile)), StandardCharsets.UTF_8));
Pattern component = Pattern.compile("^" + componentType + "\\[\\d+\\]\\.id (.+)");
while ((line = reader.readLine()) != null) {
Matcher m = component.matcher(line);
@@ -353,7 +369,7 @@ public class SearchChainConfigurerTestCase {
buf.append("components[").append(i++).append("].id ").append(ExecutionFactory.class.getName()).append("\n");
buf.insert(0, "components["+i+"]\n");
- Writer writer = new OutputStreamWriter(new FileOutputStream(new File(componentsFile)), "UTF-8");
+ Writer writer = new OutputStreamWriter(new FileOutputStream(new File(componentsFile)), StandardCharsets.UTF_8);
writer.write(buf.toString());
writer.flush();
writer.close();
diff --git a/processing/src/main/java/com/yahoo/processing/request/CompoundName.java b/processing/src/main/java/com/yahoo/processing/request/CompoundName.java
index 976fb3e2796..09c0879fdbf 100644
--- a/processing/src/main/java/com/yahoo/processing/request/CompoundName.java
+++ b/processing/src/main/java/com/yahoo/processing/request/CompoundName.java
@@ -5,7 +5,6 @@ import com.google.common.collect.ImmutableList;
import java.util.ArrayList;
import java.util.Arrays;
-import java.util.Collections;
import java.util.List;
import static com.yahoo.text.Lowercase.toLowerCase;
@@ -141,9 +140,8 @@ public final class CompoundName {
if (nameParts.length == 0) return this;
if (isEmpty()) return fromComponents(nameParts);
- List<String> newCompounds = new ArrayList<>();
- for (String namePart : nameParts)
- newCompounds.add(namePart);
+ List<String> newCompounds = new ArrayList<>(nameParts.length+compounds.size());
+ newCompounds.addAll(Arrays.asList(nameParts));
newCompounds.addAll(this.compounds);
return new CompoundName(newCompounds);
}