diff options
author | Arne H Juul <arnej@yahoo-inc.com> | 2016-11-03 15:28:10 +0100 |
---|---|---|
committer | Arne H Juul <arnej@yahoo-inc.com> | 2016-11-03 15:28:10 +0100 |
commit | 6be16d1ac0b82b11a6aca46cd0285112c8fec8e5 (patch) | |
tree | cfa69b62b0064b5a0b1cb2584e4d3a11e8eca375 | |
parent | 49b4b33db07d2e8595a8f8c71f42a0a3d0dcaeec (diff) |
convert RateLimitingSearcher to use simplemetrics
3 files changed, 37 insertions, 19 deletions
diff --git a/container-search/src/main/java/com/yahoo/search/searchers/RateLimitingSearcher.java b/container-search/src/main/java/com/yahoo/search/searchers/RateLimitingSearcher.java index 95cec1d0960..00157f0e251 100755 --- a/container-search/src/main/java/com/yahoo/search/searchers/RateLimitingSearcher.java +++ b/container-search/src/main/java/com/yahoo/search/searchers/RateLimitingSearcher.java @@ -3,7 +3,11 @@ package com.yahoo.search.searchers; import com.google.inject.Inject; import com.yahoo.cloud.config.ClusterInfoConfig; -import com.yahoo.jdisc.Metric; + +import com.yahoo.metrics.simple.MetricReceiver; +import com.yahoo.metrics.simple.Counter; +import com.yahoo.metrics.simple.Point; + import com.yahoo.processing.request.CompoundName; import com.yahoo.search.Query; import com.yahoo.search.Result; @@ -69,7 +73,7 @@ public class RateLimitingSearcher extends Searcher { private final ThreadLocal<Map<String, Double>> allocatedCapacity = new ThreadLocal<>(); /** For emitting metrics */ - private final Metric metric; + private final Counter overQuotaCounter; /** * How much capacity to allocate to a thread each time it runs out. @@ -81,19 +85,19 @@ public class RateLimitingSearcher extends Searcher { private final double recheckForCapacityProbability; @Inject - public RateLimitingSearcher(RateLimitingConfig rateLimitingConfig, ClusterInfoConfig clusterInfoConfig, Metric metric) { + public RateLimitingSearcher(RateLimitingConfig rateLimitingConfig, ClusterInfoConfig clusterInfoConfig, MetricReceiver metric) { this(rateLimitingConfig, clusterInfoConfig, metric, Clock.systemUTC()); } /** For testing - allows injection of a timer to avoid depending on the system clock */ - public RateLimitingSearcher(RateLimitingConfig rateLimitingConfig, ClusterInfoConfig clusterInfoConfig, Metric metric, Clock clock) { + public RateLimitingSearcher(RateLimitingConfig rateLimitingConfig, ClusterInfoConfig clusterInfoConfig, MetricReceiver metric, Clock clock) { this.capacityIncrement = rateLimitingConfig.capacityIncrement(); this.recheckForCapacityProbability = rateLimitingConfig.recheckForCapacityProbability(); this.availableCapacity = new AvailableCapacity(rateLimitingConfig.maxAvailableCapacity(), clock); this.nodeCount = clusterInfoConfig.nodeCount(); - this.metric = metric; + this.overQuotaCounter = metric.declareCounter(requestsOverQuotaMetricName); } @Override @@ -119,7 +123,12 @@ public class RateLimitingSearcher extends Searcher { } if (rate==0 || getAllocatedCapacity(id) <= 0) { // we are still over rate: reject - metric.add(requestsOverQuotaMetricName, 1, createContext(query.properties().getString(idDimensionKey, ""), id)); + String idDim = query.properties().getString(idDimensionKey, null); + if (idDim == null) { + overQuotaCounter.add(1); + } else { + overQuotaCounter.add(1, createContext(idDim, id)); + } if ( ! query.properties().getBoolean(dryRunKey, false)) return new Result(query, new ErrorMessage(429, "Too many requests", "Allowed rate: " + rate + "/s")); } @@ -133,10 +142,8 @@ public class RateLimitingSearcher extends Searcher { return result; } - private Metric.Context createContext(String dimensionName, String dimensionValue) { - if (dimensionName.isEmpty()) - return metric.createContext(Collections.emptyMap()); - return metric.createContext(Collections.singletonMap(dimensionName, dimensionValue)); + private Point createContext(String dimensionName, String dimensionValue) { + return overQuotaCounter.builder().set(dimensionName, dimensionValue).build(); } private double getAllocatedCapacity(String id) { diff --git a/container-search/src/test/java/com/yahoo/search/searchers/test/RateLimitingBenchmark.java b/container-search/src/test/java/com/yahoo/search/searchers/test/RateLimitingBenchmark.java index 9381cf2ab7e..b58abce7f5f 100644 --- a/container-search/src/test/java/com/yahoo/search/searchers/test/RateLimitingBenchmark.java +++ b/container-search/src/test/java/com/yahoo/search/searchers/test/RateLimitingBenchmark.java @@ -3,7 +3,10 @@ package com.yahoo.search.searchers.test; import com.yahoo.cloud.config.ClusterInfoConfig; import com.yahoo.component.chain.Chain; -import com.yahoo.jdisc.Metric; +import com.yahoo.metrics.simple.Bucket; +import com.yahoo.metrics.simple.MetricReceiver; +import com.yahoo.metrics.simple.Point; +import com.yahoo.metrics.simple.UntypedMetric; import com.yahoo.search.Query; import com.yahoo.search.Result; import com.yahoo.search.Searcher; @@ -41,7 +44,8 @@ public class RateLimitingBenchmark { private final int timeBetweenPeaksMs = 2000; private final Chain<Searcher> chain; - private final MockMetric metric; + private final MetricReceiver metric; + private Bucket metricSnapshot; private final Map<String, RequestCounts> requestCounters = new HashMap<>(); @@ -61,7 +65,7 @@ public class RateLimitingBenchmark { clusterInfoConfig.clusterId("testCluster"); clusterInfoConfig.nodeCount(1); - this.metric = new MockMetric(); + this.metric = new MetricReceiver.MockReceiver(); chain = new Chain<>("test", new RateLimitingSearcher(new RateLimitingConfig(rateLimitingConfig), new ClusterInfoConfig(clusterInfoConfig), metric)); @@ -75,6 +79,7 @@ public class RateLimitingBenchmark { runWorkers(); long totalTime = Math.max(1, System.currentTimeMillis() - startTime); + metricSnapshot = metric.getSnapshot(); double totalAttemptedRate = 0; for (int i=0; i < clientCount; i++) { double attemptedRate = requestCounters.get(toClientId(i)).attempted.get() * 1000d / totalTime; @@ -108,10 +113,10 @@ public class RateLimitingBenchmark { } private int rejectedRequests(int id) { - Metric.Context context = metric.createContext("id", toClientId(id)); - Number rejectedRequestsMetric = metric.values(context).get("requestsOverQuota"); + Point context = metric.pointBuilder().set("id", toClientId(id)).build(); + UntypedMetric rejectedRequestsMetric = metricSnapshot.getMapForMetric("requestsOverQuota").get(context); if (rejectedRequestsMetric == null) return 0; - return rejectedRequestsMetric.intValue(); + return (int)rejectedRequestsMetric.getCount(); } private class Worker implements Runnable { diff --git a/container-search/src/test/java/com/yahoo/search/searchers/test/RateLimitingSearcherTestCase.java b/container-search/src/test/java/com/yahoo/search/searchers/test/RateLimitingSearcherTestCase.java index 02d6620df2e..e210213c515 100755 --- a/container-search/src/test/java/com/yahoo/search/searchers/test/RateLimitingSearcherTestCase.java +++ b/container-search/src/test/java/com/yahoo/search/searchers/test/RateLimitingSearcherTestCase.java @@ -3,6 +3,10 @@ package com.yahoo.search.searchers.test; import com.yahoo.cloud.config.ClusterInfoConfig; import com.yahoo.component.chain.Chain; +import com.yahoo.metrics.simple.Bucket; +import com.yahoo.metrics.simple.MetricReceiver; +import com.yahoo.metrics.simple.Point; +import com.yahoo.metrics.simple.UntypedMetric; import com.yahoo.search.Query; import com.yahoo.search.Result; import com.yahoo.search.Searcher; @@ -14,6 +18,7 @@ import org.junit.Test; import com.yahoo.test.ManualClock; import java.time.Duration; +import java.util.Map; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; @@ -38,7 +43,7 @@ public class RateLimitingSearcherTestCase { clusterInfoConfig.nodeCount(4); ManualClock clock = new ManualClock(); - MockMetric metric = new MockMetric(); + MetricReceiver.MockReceiver metric = new MetricReceiver.MockReceiver(); Chain<Searcher> chain = new Chain<Searcher>("test", new RateLimitingSearcher(new RateLimitingConfig(rateLimitingConfig), new ClusterInfoConfig(clusterInfoConfig), @@ -68,8 +73,9 @@ public class RateLimitingSearcherTestCase { assertTrue(executeWasAllowed(chain, "id1")); // check metrics - assertEquals((double)requestsToTry-2 + 1 + requestsToTry-2 + 3, metric.values(metric.createContext("id", "id1")).get("requestsOverQuota")); - assertEquals((double)requestsToTry-2 + requestsToTry-4, metric.values(metric.createContext("id", "id2")).get("requestsOverQuota")); + Map<Point,UntypedMetric> map = metric.getSnapshot().getMapForMetric("requestsOverQuota"); + assertEquals(requestsToTry-2 + 1 + requestsToTry-2 + 3, map.get(metric.point("id", "id1")).getCount()); + assertEquals(requestsToTry-2 + requestsToTry-4, map.get(metric.point("id", "id2")).getCount()); } private int requestsToTry = 50; |