KAFKA-10012; Reduce overhead of strings in SelectorMetrics (#8684)

`SelectorMetrics` has a per-connection metrics, which means the number of `MetricName` objects and the strings associated with it (such as group name and description) grows with the number of connections in the client. This overhead of duplicate string objects is amplified when there are multiple instances of kafka clients within the same JVM.  This patch addresses some of the memory overhead by making `metricGrpName` a constant field and introducing a new field `perConnectionMetricGrpName`. 

Reviewers: Ismael Juma <ismael@juma.me.uk>, Jason Gustafson <jason@confluent.io>
This commit is contained in:
Navina Ramesh 2020-06-07 18:44:44 -07:00 committed by GitHub
parent 9a0b694a66
commit 7777dc8f8f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1 changed files with 12 additions and 12 deletions

View File

@ -1114,9 +1114,10 @@ public class Selector implements Selectable, AutoCloseable {
class SelectorMetrics implements AutoCloseable {
private final Metrics metrics;
private final String metricGrpPrefix;
private final Map<String, String> metricTags;
private final boolean metricsPerConnection;
private final String metricGrpName;
private final String perConnectionMetricGrpName;
public final Sensor connectionClosed;
public final Sensor connectionCreated;
@ -1142,10 +1143,10 @@ public class Selector implements Selectable, AutoCloseable {
public SelectorMetrics(Metrics metrics, String metricGrpPrefix, Map<String, String> metricTags, boolean metricsPerConnection) {
this.metrics = metrics;
this.metricGrpPrefix = metricGrpPrefix;
this.metricTags = metricTags;
this.metricsPerConnection = metricsPerConnection;
String metricGrpName = metricGrpPrefix + "-metrics";
this.metricGrpName = metricGrpPrefix + "-metrics";
this.perConnectionMetricGrpName = metricGrpPrefix + "-node-metrics";
StringBuilder tagsSuffix = new StringBuilder();
for (Map.Entry<String, String> tag: metricTags.entrySet()) {
@ -1293,34 +1294,33 @@ public class Selector implements Selectable, AutoCloseable {
String nodeRequestName = "node-" + connectionId + ".requests-sent";
Sensor nodeRequest = this.metrics.getSensor(nodeRequestName);
if (nodeRequest == null) {
String metricGrpName = metricGrpPrefix + "-node-metrics";
Map<String, String> tags = new LinkedHashMap<>(metricTags);
tags.put("node-id", "node-" + connectionId);
nodeRequest = sensor(nodeRequestName);
nodeRequest.add(createMeter(metrics, metricGrpName, tags, new WindowedCount(), "request", "requests sent"));
MetricName metricName = metrics.metricName("request-size-avg", metricGrpName, "The average size of requests sent.", tags);
nodeRequest.add(createMeter(metrics, perConnectionMetricGrpName, tags, new WindowedCount(), "request", "requests sent"));
MetricName metricName = metrics.metricName("request-size-avg", perConnectionMetricGrpName, "The average size of requests sent.", tags);
nodeRequest.add(metricName, new Avg());
metricName = metrics.metricName("request-size-max", metricGrpName, "The maximum size of any request sent.", tags);
metricName = metrics.metricName("request-size-max", perConnectionMetricGrpName, "The maximum size of any request sent.", tags);
nodeRequest.add(metricName, new Max());
String bytesSentName = "node-" + connectionId + ".bytes-sent";
Sensor bytesSent = sensor(bytesSentName);
bytesSent.add(createMeter(metrics, metricGrpName, tags, "outgoing-byte", "outgoing bytes"));
bytesSent.add(createMeter(metrics, perConnectionMetricGrpName, tags, "outgoing-byte", "outgoing bytes"));
String nodeResponseName = "node-" + connectionId + ".responses-received";
Sensor nodeResponse = sensor(nodeResponseName);
nodeResponse.add(createMeter(metrics, metricGrpName, tags, new WindowedCount(), "response", "responses received"));
nodeResponse.add(createMeter(metrics, perConnectionMetricGrpName, tags, new WindowedCount(), "response", "responses received"));
String bytesReceivedName = "node-" + connectionId + ".bytes-received";
Sensor bytesReceive = sensor(bytesReceivedName);
bytesReceive.add(createMeter(metrics, metricGrpName, tags, "incoming-byte", "incoming bytes"));
bytesReceive.add(createMeter(metrics, perConnectionMetricGrpName, tags, "incoming-byte", "incoming bytes"));
String nodeTimeName = "node-" + connectionId + ".latency";
Sensor nodeRequestTime = sensor(nodeTimeName);
metricName = metrics.metricName("request-latency-avg", metricGrpName, tags);
metricName = metrics.metricName("request-latency-avg", perConnectionMetricGrpName, tags);
nodeRequestTime.add(metricName, new Avg());
metricName = metrics.metricName("request-latency-max", metricGrpName, tags);
metricName = metrics.metricName("request-latency-max", perConnectionMetricGrpName, tags);
nodeRequestTime.add(metricName, new Max());
}
}