all: add internal API to disable retry stats (#8510)

Resolves b/197648853 for internal performance regression. Reporting retry stats caused significant amount of performance overhead internally.
This commit is contained in:
ZHANG Dapeng 2021-09-13 09:12:04 -07:00 committed by GitHub
parent 9ff54059d8
commit 7c6f53ab79
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 46 additions and 19 deletions

View File

@ -88,19 +88,21 @@ final class CensusStatsModule {
private final boolean recordStartedRpcs;
private final boolean recordFinishedRpcs;
private final boolean recordRealTimeMetrics;
private final boolean recordRetryMetrics;
/**
* Creates a {@link CensusStatsModule} with the default OpenCensus implementation.
*/
CensusStatsModule(Supplier<Stopwatch> stopwatchSupplier,
boolean propagateTags, boolean recordStartedRpcs, boolean recordFinishedRpcs,
boolean recordRealTimeMetrics) {
boolean recordRealTimeMetrics, boolean recordRetryMetrics) {
this(
Tags.getTagger(),
Tags.getTagPropagationComponent().getBinarySerializer(),
Stats.getStatsRecorder(),
stopwatchSupplier,
propagateTags, recordStartedRpcs, recordFinishedRpcs, recordRealTimeMetrics);
propagateTags, recordStartedRpcs, recordFinishedRpcs, recordRealTimeMetrics,
recordRetryMetrics);
}
/**
@ -111,7 +113,7 @@ final class CensusStatsModule {
final TagContextBinarySerializer tagCtxSerializer,
StatsRecorder statsRecorder, Supplier<Stopwatch> stopwatchSupplier,
boolean propagateTags, boolean recordStartedRpcs, boolean recordFinishedRpcs,
boolean recordRealTimeMetrics) {
boolean recordRealTimeMetrics, boolean recordRetryMetrics) {
this.tagger = checkNotNull(tagger, "tagger");
this.statsRecorder = checkNotNull(statsRecorder, "statsRecorder");
checkNotNull(tagCtxSerializer, "tagCtxSerializer");
@ -120,6 +122,7 @@ final class CensusStatsModule {
this.recordStartedRpcs = recordStartedRpcs;
this.recordFinishedRpcs = recordFinishedRpcs;
this.recordRealTimeMetrics = recordRealTimeMetrics;
this.recordRetryMetrics = recordRetryMetrics;
this.statsHeader =
Metadata.Key.of("grpc-tags-bin", new Metadata.BinaryMarshaller<TagContext>() {
@Override
@ -521,7 +524,9 @@ final class CensusStatsModule {
} else if (inboundMetricTracer != null) {
inboundMetricTracer.recordFinishedAttempt();
}
if (!module.recordRetryMetrics) {
return;
}
long retriesPerCall = 0;
long attempts = attemptsPerCall.get();
if (attempts > 0) {

View File

@ -49,14 +49,16 @@ public final class InternalCensusStatsAccessor {
public static ClientInterceptor getClientInterceptor(
boolean recordStartedRpcs,
boolean recordFinishedRpcs,
boolean recordRealTimeMetrics) {
boolean recordRealTimeMetrics,
boolean recordRetryMetrics) {
CensusStatsModule censusStats =
new CensusStatsModule(
STOPWATCH_SUPPLIER,
true, /* propagateTags */
recordStartedRpcs,
recordFinishedRpcs,
recordRealTimeMetrics);
recordRealTimeMetrics,
recordRetryMetrics);
return censusStats.getClientInterceptor();
}
@ -71,11 +73,13 @@ public final class InternalCensusStatsAccessor {
boolean propagateTags,
boolean recordStartedRpcs,
boolean recordFinishedRpcs,
boolean recordRealTimeMetrics) {
boolean recordRealTimeMetrics,
boolean recordRetryMetrics) {
CensusStatsModule censusStats =
new CensusStatsModule(
tagger, tagCtxSerializer, statsRecorder, stopwatchSupplier,
propagateTags, recordStartedRpcs, recordFinishedRpcs, recordRealTimeMetrics);
propagateTags, recordStartedRpcs, recordFinishedRpcs, recordRealTimeMetrics,
recordRetryMetrics);
return censusStats.getClientInterceptor();
}
@ -92,7 +96,8 @@ public final class InternalCensusStatsAccessor {
true, /* propagateTags */
recordStartedRpcs,
recordFinishedRpcs,
recordRealTimeMetrics);
recordRealTimeMetrics,
false);
return censusStats.getServerTracerFactory();
}
@ -111,7 +116,7 @@ public final class InternalCensusStatsAccessor {
CensusStatsModule censusStats =
new CensusStatsModule(
tagger, tagCtxSerializer, statsRecorder, stopwatchSupplier,
propagateTags, recordStartedRpcs, recordFinishedRpcs, recordRealTimeMetrics);
propagateTags, recordStartedRpcs, recordFinishedRpcs, recordRealTimeMetrics, false);
return censusStats.getServerTracerFactory();
}
}

View File

@ -225,7 +225,7 @@ public class CensusModulesTest {
censusStats =
new CensusStatsModule(
tagger, tagCtxSerializer, statsRecorder, fakeClock.getStopwatchSupplier(),
true, true, true, false /* real-time */);
true, true, true, false /* real-time */, true);
censusTracing = new CensusTracingModule(tracer, mockTracingPropagationHandler);
}
@ -400,7 +400,7 @@ public class CensusModulesTest {
CensusStatsModule localCensusStats =
new CensusStatsModule(
tagger, tagCtxSerializer, statsRecorder, fakeClock.getStopwatchSupplier(),
true, recordStarts, recordFinishes, recordRealTime);
true, recordStarts, recordFinishes, recordRealTime, true);
CensusStatsModule.CallAttemptsTracerFactory callAttemptsTracerFactory =
new CensusStatsModule.CallAttemptsTracerFactory(
localCensusStats, tagger.empty(), method.getFullMethodName());
@ -514,7 +514,7 @@ public class CensusModulesTest {
CensusStatsModule localCensusStats =
new CensusStatsModule(
tagger, tagCtxSerializer, statsRecorder, fakeClock.getStopwatchSupplier(),
true, true, true, true);
true, true, true, true, true);
CensusStatsModule.CallAttemptsTracerFactory callAttemptsTracerFactory =
new CensusStatsModule.CallAttemptsTracerFactory(
localCensusStats, tagger.empty(), method.getFullMethodName());
@ -908,7 +908,7 @@ public class CensusModulesTest {
tagCtxSerializer,
statsRecorder,
fakeClock.getStopwatchSupplier(),
propagate, recordStats, recordStats, recordStats);
propagate, recordStats, recordStats, recordStats, recordStats);
Metadata headers = new Metadata();
CensusStatsModule.CallAttemptsTracerFactory callAttemptsTracerFactory =
new CensusStatsModule.CallAttemptsTracerFactory(
@ -1168,7 +1168,7 @@ public class CensusModulesTest {
CensusStatsModule localCensusStats =
new CensusStatsModule(
tagger, tagCtxSerializer, statsRecorder, fakeClock.getStopwatchSupplier(),
true, recordStarts, recordFinishes, recordRealTime);
true, recordStarts, recordFinishes, recordRealTime, true);
ServerStreamTracer.Factory tracerFactory = localCensusStats.getServerTracerFactory();
ServerStreamTracer tracer =
tracerFactory.newServerStreamTracer(method.getFullMethodName(), new Metadata());
@ -1429,7 +1429,7 @@ public class CensusModulesTest {
CensusStatsModule localCensusStats = new CensusStatsModule(
tagger, tagCtxSerializer, localStats.getStatsRecorder(), fakeClock.getStopwatchSupplier(),
false, false, true, false /* real-time */);
false, false, true, false /* real-time */, true);
CensusStatsModule.CallAttemptsTracerFactory callAttemptsTracerFactory =
new CensusStatsModule.CallAttemptsTracerFactory(

View File

@ -97,6 +97,7 @@ public final class InProcessChannelBuilder extends
// https://github.com/grpc/grpc-java/issues/2284
managedChannelImplBuilder.setStatsRecordStartedRpcs(false);
managedChannelImplBuilder.setStatsRecordFinishedRpcs(false);
managedChannelImplBuilder.setStatsRecordRetryMetrics(false);
}
@Internal

View File

@ -162,6 +162,7 @@ public final class ManagedChannelImplBuilder
private boolean recordStartedRpcs = true;
private boolean recordFinishedRpcs = true;
private boolean recordRealTimeMetrics = false;
private boolean recordRetryMetrics = true;
private boolean tracingEnabled = true;
/**
@ -583,6 +584,10 @@ public final class ManagedChannelImplBuilder
public void setStatsRecordRealTimeMetrics(boolean value) {
recordRealTimeMetrics = value;
}
public void setStatsRecordRetryMetrics(boolean value) {
recordRetryMetrics = value;
}
/**
* Disable or enable tracing features. Enabled by default.
@ -643,6 +648,7 @@ public final class ManagedChannelImplBuilder
"getClientInterceptor",
boolean.class,
boolean.class,
boolean.class,
boolean.class);
statsInterceptor =
(ClientInterceptor) getClientInterceptorMethod
@ -650,7 +656,8 @@ public final class ManagedChannelImplBuilder
null,
recordStartedRpcs,
recordFinishedRpcs,
recordRealTimeMetrics);
recordRealTimeMetrics,
recordRetryMetrics);
} catch (ClassNotFoundException e) {
// Replace these separate catch statements with multicatch when Android min-API >= 19
log.log(Level.FINE, "Unable to apply census stats", e);

View File

@ -389,7 +389,8 @@ public abstract class AbstractInteropTest {
tagger, tagContextBinarySerializer, clientStatsRecorder,
GrpcUtil.STOPWATCH_SUPPLIER,
true, true, true,
/* recordRealTimeMetrics= */ false);
/* recordRealTimeMetrics= */ false,
/* recordRetryMetrics= */ true);
}
protected final ServerStreamTracer.Factory createCustomCensusTracerFactory() {

View File

@ -139,7 +139,7 @@ public class RetryTest {
InternalCensusStatsAccessor.getClientInterceptor(
tagger, tagContextBinarySerializer, clientStatsRecorder,
fakeClock.getStopwatchSupplier(), true, true, true,
/* recordRealTimeMetrics= */ true);
/* recordRealTimeMetrics= */ true, /* recordRetryMetrics= */ true);
private final MethodDescriptor<String, Integer> clientStreamingMethod =
MethodDescriptor.<String, Integer>newBuilder()
.setType(MethodType.CLIENT_STREAMING)

View File

@ -88,6 +88,10 @@ public final class InternalNettyChannelBuilder {
builder.setStatsRecordRealTimeMetrics(value);
}
public static void setStatsRecordRetryMetrics(NettyChannelBuilder builder, boolean value) {
builder.setStatsRecordRetryMetrics(value);
}
/**
* Sets {@link io.grpc.Channel} and {@link io.netty.channel.EventLoopGroup} to Nio. A major
* benefit over using setters is gRPC will manage the life cycle of {@link

View File

@ -605,6 +605,10 @@ public final class NettyChannelBuilder extends
this.managedChannelImplBuilder.setStatsRecordRealTimeMetrics(value);
}
void setStatsRecordRetryMetrics(boolean value) {
this.managedChannelImplBuilder.setStatsRecordRetryMetrics(value);
}
@VisibleForTesting
NettyChannelBuilder setTransportTracerFactory(TransportTracer.Factory transportTracerFactory) {
this.transportTracerFactory = transportTracerFactory;