diff options
author | Jon Bratseth <bratseth@gmail.com> | 2022-08-22 10:17:59 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-08-22 10:17:59 +0200 |
commit | e4768f639711f5157f109f1f75b440d085f34b8a (patch) | |
tree | ef0917457fd827802ba5570f73d0fbdc140ecac0 | |
parent | b4fb9448ff8afc48bc08dac950e4de4c3e60ec8e (diff) | |
parent | 7b746b08e37f9c1b891457f5c42c241718841595 (diff) |
Merge pull request #23728 from vespa-engine/balder/use-steady-clock
Use System.nanotTime instead of System.curretTimeMillis to get a stea…
4 files changed, 42 insertions, 38 deletions
diff --git a/container-search/src/main/java/com/yahoo/search/dispatch/CloseableInvoker.java b/container-search/src/main/java/com/yahoo/search/dispatch/CloseableInvoker.java index e66c48ddb74..9da89c6bfd8 100644 --- a/container-search/src/main/java/com/yahoo/search/dispatch/CloseableInvoker.java +++ b/container-search/src/main/java/com/yahoo/search/dispatch/CloseableInvoker.java @@ -2,6 +2,7 @@ package com.yahoo.search.dispatch; import java.io.Closeable; +import java.time.Duration; import java.util.function.BiConsumer; /** @@ -15,13 +16,13 @@ public abstract class CloseableInvoker implements Closeable { protected abstract void release(); - private BiConsumer<Boolean, Long> teardown = null; + private BiConsumer<Boolean, Duration> teardown = null; private boolean success = false; private long startTime = 0; - public void teardown(BiConsumer<Boolean, Long> teardown) { + public void teardown(BiConsumer<Boolean, Duration> teardown) { this.teardown = teardown; - this.startTime = System.currentTimeMillis(); + this.startTime = System.nanoTime(); } protected void setFinalStatus(boolean success) { @@ -31,7 +32,7 @@ public abstract class CloseableInvoker implements Closeable { @Override public final void close() { if (teardown != null) { - teardown.accept(success, System.currentTimeMillis() - startTime); + teardown.accept(success, Duration.ofNanos(System.nanoTime() - startTime)); teardown = null; } release(); diff --git a/container-search/src/main/java/com/yahoo/search/dispatch/Dispatcher.java b/container-search/src/main/java/com/yahoo/search/dispatch/Dispatcher.java index a9a000e36e3..9ae97dabccd 100644 --- a/container-search/src/main/java/com/yahoo/search/dispatch/Dispatcher.java +++ b/container-search/src/main/java/com/yahoo/search/dispatch/Dispatcher.java @@ -25,11 +25,11 @@ import com.yahoo.search.query.profile.types.QueryProfileType; import com.yahoo.search.result.ErrorMessage; import com.yahoo.vespa.config.search.DispatchConfig; +import java.time.Duration; import java.util.HashSet; import java.util.List; import java.util.Optional; import java.util.Set; -import java.util.stream.Collectors; /** * A dispatcher communicates with search nodes to perform queries and fill hits. @@ -227,7 +227,7 @@ public class Dispatcher extends AbstractComponent { invoker.get().teardown((success, time) -> loadBalancer.releaseGroup(group, success, time)); return invoker.get(); } else { - loadBalancer.releaseGroup(group, false, 0); + loadBalancer.releaseGroup(group, false, Duration.ZERO); if (rejected == null) { rejected = new HashSet<>(); } @@ -247,7 +247,7 @@ public class Dispatcher extends AbstractComponent { */ private Set<Integer> rejectGroupBlockingFeed(List<Group> groups) { if (groups.size() == 1) return null; - List<Group> groupsRejectingFeed = groups.stream().filter(Group::isBlockingWrites).collect(Collectors.toList()); + List<Group> groupsRejectingFeed = groups.stream().filter(Group::isBlockingWrites).toList(); if (groupsRejectingFeed.size() != 1) return null; Set<Integer> rejected = new HashSet<>(); rejected.add(groupsRejectingFeed.get(0).id()); diff --git a/container-search/src/main/java/com/yahoo/search/dispatch/LoadBalancer.java b/container-search/src/main/java/com/yahoo/search/dispatch/LoadBalancer.java index c1df730ac18..6d8bb1dce3d 100644 --- a/container-search/src/main/java/com/yahoo/search/dispatch/LoadBalancer.java +++ b/container-search/src/main/java/com/yahoo/search/dispatch/LoadBalancer.java @@ -4,6 +4,7 @@ package com.yahoo.search.dispatch; import com.yahoo.search.dispatch.searchcluster.Group; import com.yahoo.search.dispatch.searchcluster.SearchCluster; +import java.time.Duration; import java.util.ArrayList; import java.util.List; import java.util.Optional; @@ -77,13 +78,13 @@ public class LoadBalancer { * * @param group previously allocated group * @param success was the query successful - * @param searchTimeMs query execution time in milliseconds, used for adaptive load balancing + * @param searchTime query execution time, used for adaptive load balancing */ - public void releaseGroup(Group group, boolean success, double searchTimeMs) { + public void releaseGroup(Group group, boolean success, Duration searchTime) { synchronized (this) { for (GroupStatus sched : scoreboard) { if (sched.group.id() == group.id()) { - sched.release(success, searchTimeMs / 1000.0); + sched.release(success, searchTime); break; } } @@ -105,22 +106,23 @@ public class LoadBalancer { allocations++; } - void release(boolean success, double searchTime) { + void release(boolean success, Duration searchTime) { + double searchSeconds = searchTime.toMillis()/1000.0; allocations--; if (allocations < 0) { log.warning("Double free of query target group detected"); allocations = 0; } if (success) { - searchTime = Math.max(searchTime, MIN_QUERY_TIME); + searchSeconds = Math.max(searchSeconds, MIN_QUERY_TIME); double decayRate = Math.min(queries + MIN_LATENCY_DECAY_RATE, DEFAULT_LATENCY_DECAY_RATE); - averageSearchTime = (searchTime + (decayRate - 1) * averageSearchTime) / decayRate; + averageSearchTime = (searchSeconds + (decayRate - 1) * averageSearchTime) / decayRate; queries++; } } - double averageSearchTime() { - return averageSearchTime; + Duration averageSearchTime() { + return Duration.ofNanos((long)(averageSearchTime*1000000000)); } double averageSearchTimeInverse() { @@ -131,9 +133,9 @@ public class LoadBalancer { return group.id(); } - void setQueryStatistics(long queries, double averageSearchTime) { + void setQueryStatistics(long queries, Duration averageSearchTime) { this.queries = queries; - this.averageSearchTime = averageSearchTime; + this.averageSearchTime = averageSearchTime.toMillis()/1000.0; } } diff --git a/container-search/src/test/java/com/yahoo/search/dispatch/LoadBalancerTest.java b/container-search/src/test/java/com/yahoo/search/dispatch/LoadBalancerTest.java index 0ad572c0bdf..c9981b3598b 100644 --- a/container-search/src/test/java/com/yahoo/search/dispatch/LoadBalancerTest.java +++ b/container-search/src/test/java/com/yahoo/search/dispatch/LoadBalancerTest.java @@ -10,6 +10,7 @@ import com.yahoo.search.dispatch.searchcluster.SearchCluster; import org.junit.jupiter.api.Test; import org.opentest4j.AssertionFailedError; +import java.time.Duration; import java.util.ArrayList; import java.util.Collections; import java.util.List; @@ -78,7 +79,7 @@ public class LoadBalancerTest { Group group = grp.get(); int id1 = group.id(); // release allocation - lb.releaseGroup(group, true, 1.0); + lb.releaseGroup(group, true, Duration.ofMillis(1)); // get second group grp = lb.takeGroup(null); @@ -91,28 +92,28 @@ public class LoadBalancerTest { final double delta = 0.00001; GroupStatus gs = newGroupStatus(1); - gs.setQueryStatistics(0, 1.0); - updateSearchTime(gs, 1.0); - assertEquals(1.0, gs.averageSearchTime(), delta); - updateSearchTime(gs, 2.0); - assertEquals(1.02326, gs.averageSearchTime(), delta); - updateSearchTime(gs, 2.0); - assertEquals(1.04545, gs.averageSearchTime(), delta); - updateSearchTime(gs, 0.1); - updateSearchTime(gs, 0.1); - updateSearchTime(gs, 0.1); - updateSearchTime(gs, 0.1); - assertEquals(0.966667, gs.averageSearchTime(), delta); + gs.setQueryStatistics(0, Duration.ofSeconds(1)); + updateSearchTime(gs, Duration.ofSeconds(1)); + assertEquals(Duration.ofSeconds(1), gs.averageSearchTime()); + updateSearchTime(gs, Duration.ofSeconds(2)); + assertEquals(Duration.ofNanos(1023255813), gs.averageSearchTime()); + updateSearchTime(gs, Duration.ofSeconds(2)); + assertEquals(Duration.ofNanos(1045454545), gs.averageSearchTime()); + updateSearchTime(gs, Duration.ofMillis(100)); + updateSearchTime(gs, Duration.ofMillis(100)); + updateSearchTime(gs, Duration.ofMillis(100)); + updateSearchTime(gs, Duration.ofMillis(100)); + assertEquals(Duration.ofNanos(966666666), gs.averageSearchTime()); for (int i = 0; i < 10000; i++) { - updateSearchTime(gs, 1.0); + updateSearchTime(gs, Duration.ofSeconds(1)); } - assertEquals(1.0, gs.averageSearchTime(), delta); - updateSearchTime(gs, 0.1); - assertEquals(0.9991, gs.averageSearchTime(), delta); + assertEquals(Duration.ofNanos(999999812), gs.averageSearchTime()); + updateSearchTime(gs, Duration.ofMillis(100)); + assertEquals(Duration.ofNanos(999099812), gs.averageSearchTime()); for (int i = 0; i < 10000; i++) { - updateSearchTime(gs, 0.0); + updateSearchTime(gs, Duration.ZERO); } - assertEquals(0.001045, gs.averageSearchTime(), delta); + assertEquals(Duration.ofNanos(1045087), gs.averageSearchTime()); } @Test @@ -139,7 +140,7 @@ public class LoadBalancerTest { List<GroupStatus> scoreboard = new ArrayList<>(); for (int i = 0; i < 5; i++) { GroupStatus gs = newGroupStatus(i); - gs.setQueryStatistics(1, 0.1 * (i + 1)); + gs.setQueryStatistics(1, Duration.ofMillis((long)(0.1 * (i + 1)*1000.0))); scoreboard.add(gs); } Random seq = sequence(0.0, 0.4379, 0.4380, 0.6569, 0.6570, 0.8029, 0.8030, 0.9124, 0.9125); @@ -189,7 +190,7 @@ public class LoadBalancerTest { assertEquals(0, allocate(sched.takeNextGroup(null).get()).groupId()); } - private static void updateSearchTime(GroupStatus gs, double time) { + private static void updateSearchTime(GroupStatus gs, Duration time) { gs.allocate(); gs.release(true, time); } |