Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 31 additions & 0 deletions solr/benchmark/src/java/org/apache/solr/bench/SolrBenchState.java
Original file line number Diff line number Diff line change
Expand Up @@ -32,9 +32,11 @@
import java.util.ArrayList;
import java.util.List;
import java.util.SplittableRandom;
import java.util.concurrent.Executor;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicLong;
import org.apache.solr.client.solrj.SolrServerException;
Expand Down Expand Up @@ -259,6 +261,14 @@ public void metricsEnabled(boolean metricsEnabled) {
* @param nodeCount the node count
*/
public void startSolr(int nodeCount) {
startSolr(nodeCount, 0);
}

/** Starts the benchmark nodes with an explicit search worker count. */
public void startSolr(int nodeCount, int searchThreads) {
if (searchThreads < 0) {
throw new IllegalArgumentException("searchThreads must be non-negative");
}
log("starting mini cluster at base directory: " + miniClusterBaseDir.toAbsolutePath());

if (!allowClusterReuse && Files.exists(miniClusterBaseDir)) {
Expand All @@ -277,6 +287,12 @@ public void startSolr(int nodeCount) {
try {
cluster =
new MiniSolrCloudCluster.Builder(nodeCount, miniClusterBaseDir)
.withSolrXml(
MiniSolrCloudCluster.DEFAULT_CLOUD_SOLR_XML.replace(
"<solr>",
"<solr><int name=\"indexSearcherExecutorThreads\">"
+ searchThreads
+ "</int>"))
.formatZkServer(false)
.addConfig("conf", getFile("src/resources/configs/cloud-minimal/conf"))
.configure();
Expand Down Expand Up @@ -341,6 +357,21 @@ public void createCollection(String collection, int numShards, int numReplicas)
}
}

/** Returns completed search-pool tasks; direct execution without a pool contributes zero. */
public long completedSearchTasks() {
long completed = 0;
for (JettySolrRunner jetty : cluster.getJettySolrRunners()) {
Executor executor = jetty.getCoreContainer().getIndexSearcherExecutor();
if (executor != null) {
if (!(executor instanceof ThreadPoolExecutor pool)) {
throw new IllegalStateException("Unsupported search executor: " + executor.getClass());
}
completed += pool.getCompletedTaskCount();
}
}
return completed;
}

/** Setting useHttp1 to true will make the {@link #client} use http1 */
public void setUseHttp1(boolean useHttp1) {
if (client != null) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,46 +63,61 @@ public static class BenchState {

Docs queryFields;

int NUM_DOCS = 500_000;
int WORDS = NUM_DOCS / 100;
@Param({"500000"})
int numDocs;

@Param({"0"})
int searchThreads;

@Param({"false"})
boolean multiThreaded;

@Param({"1000"})
int timeAllowed;

int words;
long tasksBeforeIteration;

@Setup(Level.Trial)
public void setupTrial(SolrBenchState solrBenchState) throws Exception {
if (numDocs < 1) {
throw new IllegalArgumentException("numDocs must be positive");
}
words = Math.max(1, numDocs / 100);
solrBenchState.setUseHttp1(true);
System.setProperty("documentCache.enabled", "false");
System.setProperty("queryResultCache.enabled", "false");
System.setProperty("filterCache.enabled", "false");
System.setProperty("miniClusterBaseDir", "build/work/mini-cluster");
// create a lot of small segments
System.setProperty("segmentsPerTier", "200");
System.setProperty("maxBufferedDocs", "100");

solrBenchState.startSolr(1);
solrBenchState.startSolr(1, searchThreads);
log("######### Creating index ...");
solrBenchState.createCollection(COLLECTION, 1, 1);
// create a lot of large-ish fields to scan positions
Docs docs =
Docs.docs(1234567890L)
.field("id", integers().incrementing())
.field("f1_ts", strings().alpha().maxCardinality(WORDS).ofLengthBetween(3, 10))
.field("f1_ts", strings().alpha().maxCardinality(words).ofLengthBetween(3, 10))
.field(
"f2_ts", strings().alpha().maxCardinality(WORDS).multi(50).ofLengthBetween(3, 10))
"f2_ts", strings().alpha().maxCardinality(words).multi(50).ofLengthBetween(3, 10))
.field(
"f3_ts", strings().alpha().maxCardinality(WORDS).multi(50).ofLengthBetween(3, 10))
"f3_ts", strings().alpha().maxCardinality(words).multi(50).ofLengthBetween(3, 10))
.field(
"f4_ts", strings().alpha().maxCardinality(WORDS).multi(50).ofLengthBetween(3, 10))
"f4_ts", strings().alpha().maxCardinality(words).multi(50).ofLengthBetween(3, 10))
.field(
"f5_ts", strings().alpha().maxCardinality(WORDS).multi(50).ofLengthBetween(3, 10))
"f5_ts", strings().alpha().maxCardinality(words).multi(50).ofLengthBetween(3, 10))
.field(
"f6_ts", strings().alpha().maxCardinality(WORDS).multi(50).ofLengthBetween(3, 10))
"f6_ts", strings().alpha().maxCardinality(words).multi(50).ofLengthBetween(3, 10))
.field(
"f7_ts", strings().alpha().maxCardinality(WORDS).multi(50).ofLengthBetween(3, 10))
"f7_ts", strings().alpha().maxCardinality(words).multi(50).ofLengthBetween(3, 10))
.field(
"f8_ts", strings().alpha().maxCardinality(WORDS).multi(50).ofLengthBetween(3, 10))
"f8_ts", strings().alpha().maxCardinality(words).multi(50).ofLengthBetween(3, 10))
.field(
"f9_ts",
strings().alpha().maxCardinality(WORDS).multi(50).ofLengthBetween(3, 10));
solrBenchState.index(COLLECTION, docs, NUM_DOCS, true);
strings().alpha().maxCardinality(words).multi(50).ofLengthBetween(3, 10));
solrBenchState.index(COLLECTION, docs, numDocs, false);
solrBenchState.forceMerge(COLLECTION, 200);
solrBenchState.dumpCoreInfo();
}
Expand All @@ -123,16 +138,21 @@ public void setupQueries(SolrBenchState solrBenchState) throws Exception {
CollectionAdminRequest.Reload reload = CollectionAdminRequest.reloadCollection(COLLECTION);
solrBenchState.client.request(reload);

tasksBeforeIteration = solrBenchState.completedSearchTasks();

queryFields =
Docs.docs(1234567890L)
.field("id", integers().incrementing())
.field("f1_ts", strings().alpha().maxCardinality(WORDS).ofLengthBetween(3, 10))
.field("f1_ts", strings().alpha().maxCardinality(words).ofLengthBetween(3, 10))
.field(
"f2_ts", strings().alpha().maxCardinality(WORDS).multi(5).ofLengthBetween(3, 10));
"f2_ts", strings().alpha().maxCardinality(words).multi(5).ofLengthBetween(3, 10));
}

@TearDown(Level.Iteration)
public void tearDownTrial() throws Exception {
public void tearDownTrial(SolrBenchState solrBenchState) throws Exception {
log(
"Completed search-pool tasks in iteration: "
+ (solrBenchState.completedSearchTasks() - tasksBeforeIteration));
if (verifyEDRInUse) {
CallerSpecificQueryLimit queryLimit = (CallerSpecificQueryLimit) TestInjection.queryTimeout;
if (queryLimit == null) {
Expand All @@ -151,17 +171,20 @@ public void tearDownTrial() throws Exception {
}
}

private static ModifiableSolrParams createInitialParams() {
ModifiableSolrParams params =
SolrBenchState.params("rows", "100", "timeAllowed", "1000", "fl", "*");
private static ModifiableSolrParams createInitialParams(BenchState state) {
ModifiableSolrParams params = SolrBenchState.params("rows", "100", "fl", "*");
params.set("multiThreaded", state.multiThreaded);
if (state.timeAllowed > 0) {
params.set("timeAllowed", state.timeAllowed);
}
return params;
}

@Benchmark
public void testShortQuery(SolrBenchState solrBenchState, Blackhole bh, BenchState state)
throws Exception {
SolrInputDocument queryDoc = state.queryFields.inputDocument();
ModifiableSolrParams params = createInitialParams();
ModifiableSolrParams params = createInitialParams(state);
params.set("q", "f1_ts:" + queryDoc.getFieldValue("f1_ts").toString());
QueryRequest queryRequest = new QueryRequest(params);
QueryResponse rsp = queryRequest.process(solrBenchState.client, COLLECTION);
Expand All @@ -172,7 +195,7 @@ public void testShortQuery(SolrBenchState solrBenchState, Blackhole bh, BenchSta
public void testLongQuery(SolrBenchState solrBenchState, Blackhole bh, BenchState state)
throws Exception {
SolrInputDocument queryDoc = state.queryFields.inputDocument();
ModifiableSolrParams params = createInitialParams();
ModifiableSolrParams params = createInitialParams(state);
StringBuilder query = new StringBuilder();
for (int i = 2; i < 10; i++) {
if (query.length() > 0) {
Expand Down
Loading