Skip to content

Commit

Permalink
[Profiling] Use downsampled K/V indices
Browse files Browse the repository at this point in the history
  • Loading branch information
danielmitterdorfer committed Jul 10, 2023
1 parent d60e698 commit 7c2ba38
Show file tree
Hide file tree
Showing 6 changed files with 151 additions and 35 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ protected boolean useOnlyAllEvents() {
}

public void testGetProfilingDataUnfiltered() throws Exception {
GetProfilingRequest request = new GetProfilingRequest(1, null);
GetProfilingRequest request = new GetProfilingRequest(1, null, null);
GetProfilingResponse response = client().execute(GetProfilingAction.INSTANCE, request).get();
assertEquals(1, response.getTotalFrames());
assertNotNull(response.getStackTraces());
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0; you may not use this file except in compliance with the Elastic License
* 2.0.
*/

package org.elasticsearch.xpack.profiler;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Locale;

public class DownsampledIndex {
private static final int SAMPLING_FACTOR = 5;

private static final int MIN_EXPONENT = 1;

private static final int MAX_EXPONENT = 11;

public static String indexName(String namePrefix, int exp) {
return (exp > 0) ? String.format(Locale.ROOT, "%s-%dpow%02d", namePrefix, SAMPLING_FACTOR, exp) : namePrefix;
}

public static Collection<String> indexNames(String namePrefix) {
return DownsampledIndex.indexNames(namePrefix, namePrefix);
}

public static Collection<String> indexNames(String fullIndexName, String namePrefix) {
List<String> names = new ArrayList<>();
names.add(fullIndexName);
for (int exp = MIN_EXPONENT; exp <= MAX_EXPONENT; exp++) {
names.add(indexName(namePrefix, exp));
}
return Collections.unmodifiableList(names);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -36,29 +36,35 @@
public class GetProfilingRequest extends ActionRequest implements IndicesRequest {
public static final ParseField QUERY_FIELD = new ParseField("query");
public static final ParseField SAMPLE_SIZE_FIELD = new ParseField("sample_size");
public static final ParseField DOWNSAMPLED_INDICES_SIZE_FIELD = new ParseField("downsampled_indices");

private QueryBuilder query;

private Integer sampleSize;

private Boolean useDownsampledIndices;

public GetProfilingRequest() {
this(null, null);
this(null, null, null);
}

public GetProfilingRequest(Integer sampleSize, QueryBuilder query) {
public GetProfilingRequest(Integer sampleSize, Boolean useDownsampledIndices, QueryBuilder query) {
this.sampleSize = sampleSize;
this.useDownsampledIndices = useDownsampledIndices;
this.query = query;
}

public GetProfilingRequest(StreamInput in) throws IOException {
this.query = in.readOptionalNamedWriteable(QueryBuilder.class);
this.sampleSize = in.readOptionalInt();
this.useDownsampledIndices = in.readOptionalBoolean();
}

@Override
public void writeTo(StreamOutput out) throws IOException {
out.writeOptionalNamedWriteable(query);
out.writeOptionalInt(sampleSize);
out.writeOptionalBoolean(useDownsampledIndices);
}

public Integer getSampleSize() {
Expand All @@ -69,6 +75,10 @@ public QueryBuilder getQuery() {
return query;
}

public boolean isUseDownsampledIndices() {
return useDownsampledIndices != null && useDownsampledIndices;
}

public void parseXContent(XContentParser parser) throws IOException {
XContentParser.Token token = parser.currentToken();
String currentFieldName = null;
Expand All @@ -86,6 +96,8 @@ public void parseXContent(XContentParser parser) throws IOException {
} else if (token.isValue()) {
if (SAMPLE_SIZE_FIELD.match(currentFieldName, parser.getDeprecationHandler())) {
this.sampleSize = parser.intValue();
} else if (DOWNSAMPLED_INDICES_SIZE_FIELD.match(currentFieldName, parser.getDeprecationHandler())) {
this.useDownsampledIndices = parser.booleanValue();
} else {
throw new ParsingException(
parser.getTokenLocation(),
Expand Down Expand Up @@ -134,6 +146,7 @@ public String getDescription() {
// generating description lazily since the query could be large
StringBuilder sb = new StringBuilder();
sb.append("sample_size[").append(sampleSize).append("]");
sb.append("downsampled_indices[").append(useDownsampledIndices).append("]");
if (query == null) {
sb.append(", query[]");
} else {
Expand Down Expand Up @@ -164,6 +177,7 @@ public int hashCode() {
@Override
public String[] indices() {
Set<String> indices = new HashSet<>();
// TODO: Do we need to add all indices here?
indices.add("profiling-stacktraces");
indices.add("profiling-stackframes");
indices.add("profiling-executables");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@
import org.elasticsearch.threadpool.ThreadPool;
import org.elasticsearch.xpack.core.ClientHelper;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.Locale;
Expand All @@ -40,32 +42,61 @@
*/
public class ProfilingIndexManager extends AbstractProfilingPersistenceManager<ProfilingIndexManager.ProfilingIndex> {
// For testing
public static final List<ProfilingIndex> PROFILING_INDICES = List.of(
ProfilingIndex.regular(
"profiling-returnpads-private",
ProfilingIndexTemplateRegistry.PROFILING_RETURNPADS_PRIVATE_VERSION,
OnVersionBump.KEEP_OLD
),
ProfilingIndex.regular(
"profiling-sq-executables",
ProfilingIndexTemplateRegistry.PROFILING_SQ_EXECUTABLES_VERSION,
OnVersionBump.DELETE_OLD
),
ProfilingIndex.regular(
"profiling-sq-leafframes",
ProfilingIndexTemplateRegistry.PROFILING_SQ_LEAFFRAMES_VERSION,
OnVersionBump.DELETE_OLD
),
ProfilingIndex.regular(
"profiling-symbols-private",
ProfilingIndexTemplateRegistry.PROFILING_SYMBOLS_VERSION,
OnVersionBump.KEEP_OLD
),
ProfilingIndex.kv("profiling-executables", ProfilingIndexTemplateRegistry.PROFILING_EXECUTABLES_VERSION),
ProfilingIndex.kv("profiling-stackframes", ProfilingIndexTemplateRegistry.PROFILING_STACKFRAMES_VERSION),
ProfilingIndex.kv("profiling-stacktraces", ProfilingIndexTemplateRegistry.PROFILING_STACKTRACES_VERSION),
ProfilingIndex.kv("profiling-symbols-global", ProfilingIndexTemplateRegistry.PROFILING_SYMBOLS_VERSION)
);
public static final List<ProfilingIndex> PROFILING_INDICES;

static {
List<ProfilingIndex> indices = new ArrayList<>();
indices.add(
ProfilingIndex.regular(
"profiling-returnpads-private",
ProfilingIndexTemplateRegistry.PROFILING_RETURNPADS_PRIVATE_VERSION,
OnVersionBump.KEEP_OLD
)
);
indices.add(
ProfilingIndex.regular(
"profiling-sq-executables",
ProfilingIndexTemplateRegistry.PROFILING_SQ_EXECUTABLES_VERSION,
OnVersionBump.DELETE_OLD
)
);
indices.add(
ProfilingIndex.regular(
"profiling-sq-leafframes",
ProfilingIndexTemplateRegistry.PROFILING_SQ_LEAFFRAMES_VERSION,
OnVersionBump.DELETE_OLD
)
);
indices.add(
ProfilingIndex.regular(
"profiling-symbols-private",
ProfilingIndexTemplateRegistry.PROFILING_SYMBOLS_VERSION,
OnVersionBump.KEEP_OLD
)
);
indices.addAll(
DownsampledIndex.indexNames("profiling-executables")
.stream()
.map(n -> ProfilingIndex.kv(n, ProfilingIndexTemplateRegistry.PROFILING_EXECUTABLES_VERSION))
.toList()
);
indices.addAll(
DownsampledIndex.indexNames("profiling-stackframes")
.stream()
.map(n -> ProfilingIndex.kv(n, ProfilingIndexTemplateRegistry.PROFILING_STACKFRAMES_VERSION))
.toList()
);
indices.addAll(
DownsampledIndex.indexNames("profiling-stacktraces")
.stream()
.map(n -> ProfilingIndex.kv(n, ProfilingIndexTemplateRegistry.PROFILING_STACKTRACES_VERSION))
.toList()
);

indices.add(ProfilingIndex.kv("profiling-symbols-global", ProfilingIndexTemplateRegistry.PROFILING_SYMBOLS_VERSION));

PROFILING_INDICES = Collections.unmodifiableList(indices);
}

private final ThreadPool threadPool;
private final Client client;
Expand Down Expand Up @@ -354,7 +385,7 @@ public ProfilingIndex withGeneration(String generation) {
}

public boolean isMatchWithoutVersion(String indexName) {
return indexName.startsWith("." + namePrefix);
return indexName.startsWith("." + namePrefix + "-v");
}

public boolean isMatchWithoutGeneration(String indexName) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -155,7 +155,9 @@ private void searchEventGroupByStackTrace(
) {
long start = System.nanoTime();
GetProfilingResponseBuilder responseBuilder = new GetProfilingResponseBuilder();
int exp = eventsIndex.getExponent();
responseBuilder.setExponent(eventsIndex.getExponent());
responseBuilder.setUseDownsampledIndices(request.isUseDownsampledIndices());
log.debug("Using exponent [{}].", eventsIndex.getExponent());
responseBuilder.setSampleRate(eventsIndex.getSampleRate());
client.prepareSearch(eventsIndex.getName())
.setTrackTotalHits(false)
Expand Down Expand Up @@ -222,7 +224,12 @@ private void retrieveStackTraces(
List<String> eventIds = new ArrayList<>(responseBuilder.getStackTraceEvents().keySet());
List<List<String>> slicedEventIds = sliced(eventIds, desiredSlices);
ClusterState clusterState = clusterService.state();
List<Index> indices = resolver.resolve(clusterState, "profiling-stacktraces", responseBuilder.getStart(), responseBuilder.getEnd());
List<Index> indices = resolver.resolve(
clusterState,
indexPattern(responseBuilder, "profiling-stacktraces"),
responseBuilder.getStart(),
responseBuilder.getEnd()
);
StackTraceHandler handler = new StackTraceHandler(
clusterState,
client,
Expand Down Expand Up @@ -331,13 +338,13 @@ private void retrieveStackTraceDetails(
List<List<String>> slicedExecutableIds = sliced(executableIds, desiredDetailSlices);
List<Index> stackFrameIndices = resolver.resolve(
clusterState,
"profiling-stackframes",
indexPattern(responseBuilder, "profiling-stackframes"),
responseBuilder.getStart(),
responseBuilder.getEnd()
);
List<Index> executableIndices = resolver.resolve(
clusterState,
"profiling-executables",
indexPattern(responseBuilder, "profiling-executables"),
responseBuilder.getStart(),
responseBuilder.getEnd()
);
Expand Down Expand Up @@ -489,6 +496,10 @@ public void mayFinish() {
}
}

private String indexPattern(GetProfilingResponseBuilder responseBuilder, String indexName) {
return responseBuilder.isUseDownsampledIndices() ? DownsampledIndex.indexName(indexName, responseBuilder.getExponent()) : indexName;
}

private void mget(Client client, List<Index> indices, List<String> slice, ActionListener<MultiGetResponse> listener) {
for (Index index : indices) {
client.prepareMultiGet()
Expand All @@ -506,8 +517,12 @@ private static class GetProfilingResponseBuilder {
private Map<String, StackFrame> stackFrames;
private Map<String, String> executables;
private Map<String, Integer> stackTraceEvents;

private int exponent;
private double samplingRate;

private boolean useDownsampledIndices;

public void setStackTraces(Map<String, StackTrace> stackTraces) {
this.stackTraces = stackTraces;
}
Expand Down Expand Up @@ -552,6 +567,22 @@ public void setSampleRate(double rate) {
this.samplingRate = rate;
}

public int getExponent() {
return exponent;
}

public void setExponent(int exponent) {
this.exponent = exponent;
}

public boolean isUseDownsampledIndices() {
return useDownsampledIndices;
}

public void setUseDownsampledIndices(boolean useDownsampledIndices) {
this.useDownsampledIndices = useDownsampledIndices;
}

public GetProfilingResponse build() {
return new GetProfilingResponse(stackTraces, stackFrames, executables, stackTraceEvents, totalFrames, samplingRate);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,10 @@
public class GetProfilingRequestTests extends ESTestCase {
public void testSerialization() throws IOException {
Integer sampleSize = randomBoolean() ? randomIntBetween(0, Integer.MAX_VALUE) : null;
Boolean useDownsampledIndices = randomBoolean() ? randomBoolean() : null;
QueryBuilder query = randomBoolean() ? new BoolQueryBuilder() : null;

GetProfilingRequest request = new GetProfilingRequest(sampleSize, query);
GetProfilingRequest request = new GetProfilingRequest(sampleSize, useDownsampledIndices, query);
try (BytesStreamOutput out = new BytesStreamOutput()) {
request.writeTo(out);
try (NamedWriteableAwareStreamInput in = new NamedWriteableAwareStreamInput(out.bytes().streamInput(), writableRegistry())) {
Expand Down

0 comments on commit 7c2ba38

Please sign in to comment.