Search in sources :

Example 41 with DEFAULT_PARTITION_ID

use of com.linkedin.d2.balancer.util.partitions.DefaultPartitionAccessor.DEFAULT_PARTITION_ID in project rest.li by linkedin.

the class StateUpdaterTest method testUpdateTrackerClientWithDoNotLoadBalance.

@Test
public void testUpdateTrackerClientWithDoNotLoadBalance() {
    final boolean doNotLoadBalance = true;
    List<TrackerClient> trackerClients = TrackerClientMockHelper.mockTrackerClients(3, Arrays.asList(20, 1, 20), Arrays.asList(0, 0, 0), Arrays.asList(1000L, 5000L, 100000L), Arrays.asList(0L, 0L, 0L), Arrays.asList(0, 0, 10), Arrays.asList(false, false, doNotLoadBalance));
    PartitionState state = new PartitionStateTestDataBuilder().setClusterGenerationId(DEFAULT_CLUSTER_GENERATION_ID).setTrackerClientStateMap(trackerClients, Arrays.asList(1.0, 1.0, 1.0), Arrays.asList(TrackerClientState.HealthState.HEALTHY, TrackerClientState.HealthState.HEALTHY, TrackerClientState.HealthState.HEALTHY), Arrays.asList(30, 30, 30)).build();
    ConcurrentMap<Integer, PartitionState> partitionLoadBalancerStateMap = new ConcurrentHashMap<>();
    partitionLoadBalancerStateMap.put(DEFAULT_PARTITION_ID, state);
    setup(new D2RelativeStrategyProperties(), partitionLoadBalancerStateMap);
    _stateUpdater.updateState();
    Map<URI, Integer> pointsMap = _stateUpdater.getPointsMap(DEFAULT_PARTITION_ID);
    assertEquals(pointsMap.get(trackerClients.get(0).getUri()).intValue(), HEALTHY_POINTS, "Healthy client should not have health score reduced.");
    assertEquals(pointsMap.get(trackerClients.get(1).getUri()).intValue(), (int) (HEALTHY_POINTS - RelativeLoadBalancerStrategyFactory.DEFAULT_DOWN_STEP * RelativeLoadBalancerStrategyFactory.DEFAULT_POINTS_PER_WEIGHT), "This should be considered unhealthy because its latency exceeds the threshold " + "(the client with load balancing disabled should not affect the average latency calculation).");
    assertEquals(pointsMap.get(trackerClients.get(2).getUri()).intValue(), HEALTHY_POINTS, "The client with load balancing disabled " + "should not have health score reduced.");
}
Also used : TrackerClient(com.linkedin.d2.balancer.clients.TrackerClient) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) URI(java.net.URI) D2RelativeStrategyProperties(com.linkedin.d2.D2RelativeStrategyProperties) Test(org.testng.annotations.Test)

Example 42 with DEFAULT_PARTITION_ID

use of com.linkedin.d2.balancer.util.partitions.DefaultPartitionAccessor.DEFAULT_PARTITION_ID in project rest.li by linkedin.

the class StateUpdaterTest method testInitializePartitionWithSlowStartInitialHealthScore.

@Test(dataProvider = "trueFalse")
public void testInitializePartitionWithSlowStartInitialHealthScore(boolean doNotSlowStart) {
    double initialHealthScore = 0.01;
    D2RelativeStrategyProperties relativeStrategyProperties = new D2RelativeStrategyProperties().setInitialHealthScore(initialHealthScore);
    setup(relativeStrategyProperties, new ConcurrentHashMap<>());
    List<TrackerClient> trackerClients = TrackerClientMockHelper.mockTrackerClients(2, Arrays.asList(20, 20), Arrays.asList(10, 10), Arrays.asList(200L, 500L), Arrays.asList(100L, 200L), Arrays.asList(0, 0), doNotSlowStart, Arrays.asList(false, false));
    assertTrue(_stateUpdater.getPointsMap(DEFAULT_PARTITION_ID).isEmpty(), "There should be no state before initialization");
    _stateUpdater.updateState(new HashSet<>(trackerClients), DEFAULT_PARTITION_ID, DEFAULT_CLUSTER_GENERATION_ID, false);
    if (!doNotSlowStart) {
        assertEquals(_stateUpdater.getPointsMap(DEFAULT_PARTITION_ID).get(trackerClients.get(0).getUri()).intValue(), (int) (initialHealthScore * RelativeLoadBalancerStrategyFactory.DEFAULT_POINTS_PER_WEIGHT));
        assertEquals(_stateUpdater.getPointsMap(DEFAULT_PARTITION_ID).get(trackerClients.get(1).getUri()).intValue(), (int) (initialHealthScore * RelativeLoadBalancerStrategyFactory.DEFAULT_POINTS_PER_WEIGHT));
    } else {
        assertEquals(_stateUpdater.getPointsMap(DEFAULT_PARTITION_ID).get(trackerClients.get(0).getUri()).intValue(), HEALTHY_POINTS);
        assertEquals(_stateUpdater.getPointsMap(DEFAULT_PARTITION_ID).get(trackerClients.get(1).getUri()).intValue(), HEALTHY_POINTS);
    }
}
Also used : TrackerClient(com.linkedin.d2.balancer.clients.TrackerClient) D2RelativeStrategyProperties(com.linkedin.d2.D2RelativeStrategyProperties) Test(org.testng.annotations.Test)

Example 43 with DEFAULT_PARTITION_ID

use of com.linkedin.d2.balancer.util.partitions.DefaultPartitionAccessor.DEFAULT_PARTITION_ID in project rest.li by linkedin.

the class DegraderLoadBalancerTest method testshouldUpdatePartition.

@Test(groups = { "small", "back-end" })
public void testshouldUpdatePartition() throws URISyntaxException {
    Map<String, Object> myConfig = new HashMap<>();
    TestClock testClock = new TestClock();
    myConfig.put(PropertyKeys.CLOCK, testClock);
    myConfig.put(PropertyKeys.HTTP_LB_STRATEGY_PROPERTIES_UPDATE_INTERVAL_MS, 5000L);
    myConfig.put(PropertyKeys.HTTP_LB_STRATEGY_PROPERTIES_MAX_CLUSTER_LATENCY_WITHOUT_DEGRADING, 100d);
    DegraderLoadBalancerStrategyV3 strategy = getStrategy(myConfig);
    List<DegraderTrackerClient> clients = new ArrayList<>();
    Map<URI, Integer> pointsMap = new HashMap<>();
    long clusterCallCount = 15;
    RingFactory<URI> ringFactory = new DelegatingRingFactory<>(new DegraderLoadBalancerStrategyConfig(1L));
    URI uri1 = URI.create("http://test.linkedin.com:3242/fdsaf");
    URI uri2 = URI.create("http://test.linkedin.com:3243/fdsaf");
    clients.add(getClient(uri1));
    clients.add(getClient(uri2));
    pointsMap.put(uri1, 1);
    pointsMap.put(uri2, 1);
    // state is default initialized, new cluster generation
    assertTrue(DegraderLoadBalancerStrategyV3.shouldUpdatePartition(0, strategy.getState().getPartitionState(DEFAULT_PARTITION_ID), strategy.getConfig(), true, false, clients));
    PartitionDegraderLoadBalancerState current = strategy.getState().getPartitionState(DEFAULT_PARTITION_ID);
    current = new PartitionDegraderLoadBalancerState(0, testClock._currentTimeMillis, true, ringFactory, pointsMap, PartitionDegraderLoadBalancerState.Strategy.LOAD_BALANCE, 0.0, -1, new HashMap<>(), "Test", current.getDegraderProperties(), clusterCallCount, 0, 0, Collections.emptyMap(), Collections.emptyMap(), null, 0);
    strategy.getState().setPartitionState(DEFAULT_PARTITION_ID, current);
    // state is not null, but we're on the same cluster generation id, and 5 seconds
    // haven't gone by
    testClock.addMs(1);
    assertFalse(DegraderLoadBalancerStrategyV3.shouldUpdatePartition(0, strategy.getState().getPartitionState(DEFAULT_PARTITION_ID), strategy.getConfig(), true, false, clients));
    // generation Id for the next state is changed
    current = new PartitionDegraderLoadBalancerState(1, testClock._currentTimeMillis, true, ringFactory, pointsMap, PartitionDegraderLoadBalancerState.Strategy.LOAD_BALANCE, 0.0, -1, new HashMap<>(), "Test", current.getDegraderProperties(), clusterCallCount, 0, 0, Collections.emptyMap(), Collections.emptyMap(), null, 0);
    strategy.getState().setPartitionState(DEFAULT_PARTITION_ID, current);
    // state is not null, and cluster generation has changed so we will update
    testClock.addMs(1);
    assertTrue(DegraderLoadBalancerStrategyV3.shouldUpdatePartition(0, strategy.getState().getPartitionState(DEFAULT_PARTITION_ID), strategy.getConfig(), true, false, clients));
    // state is not null, and force 5s to go by with the same cluster generation id
    current = new PartitionDegraderLoadBalancerState(1, testClock._currentTimeMillis, true, ringFactory, pointsMap, PartitionDegraderLoadBalancerState.Strategy.LOAD_BALANCE, 0.0, -1, new HashMap<>(), "Test", current.getDegraderProperties(), clusterCallCount, 0, 0, Collections.emptyMap(), Collections.emptyMap(), null, 0);
    strategy.getState().setPartitionState(DEFAULT_PARTITION_ID, current);
    testClock.addMs(5000);
    assertTrue(DegraderLoadBalancerStrategyV3.shouldUpdatePartition(1, strategy.getState().getPartitionState(DEFAULT_PARTITION_ID), strategy.getConfig(), true, false, clients));
    current = new PartitionDegraderLoadBalancerState(1, testClock._currentTimeMillis, true, ringFactory, pointsMap, PartitionDegraderLoadBalancerState.Strategy.LOAD_BALANCE, 0.0, -1, new HashMap<>(), "Test", current.getDegraderProperties(), clusterCallCount, 0, 0, Collections.emptyMap(), Collections.emptyMap(), null, 0);
    strategy.getState().setPartitionState(DEFAULT_PARTITION_ID, current);
    // now try a new cluster generation id so state will be updated again
    testClock.addMs(15);
    assertTrue(DegraderLoadBalancerStrategyV3.shouldUpdatePartition(2, strategy.getState().getPartitionState(DEFAULT_PARTITION_ID), strategy.getConfig(), true, false, clients));
}
Also used : HashMap(java.util.HashMap) DegraderTrackerClient(com.linkedin.d2.balancer.clients.DegraderTrackerClient) ArrayList(java.util.ArrayList) URI(java.net.URI) DelegatingRingFactory(com.linkedin.d2.balancer.strategies.DelegatingRingFactory) Test(org.testng.annotations.Test) DegraderTrackerClientTest(com.linkedin.d2.balancer.clients.DegraderTrackerClientTest)

Example 44 with DEFAULT_PARTITION_ID

use of com.linkedin.d2.balancer.util.partitions.DefaultPartitionAccessor.DEFAULT_PARTITION_ID in project rest.li by linkedin.

the class DegraderLoadBalancerTest method testshouldUpdatePartitionOnlyAtInterval.

@Test(groups = { "small", "back-end" })
public void testshouldUpdatePartitionOnlyAtInterval() throws URISyntaxException {
    Map<String, Object> myConfig = new HashMap<>();
    TestClock testClock = new TestClock();
    myConfig.put(PropertyKeys.CLOCK, testClock);
    myConfig.put(PropertyKeys.HTTP_LB_STRATEGY_PROPERTIES_UPDATE_INTERVAL_MS, 5000L);
    myConfig.put(PropertyKeys.HTTP_LB_STRATEGY_PROPERTIES_MAX_CLUSTER_LATENCY_WITHOUT_DEGRADING, 100d);
    myConfig.put(PropertyKeys.HTTP_LB_STRATEGY_PROPERTIES_UPDATE_ONLY_AT_INTERVAL, true);
    DegraderLoadBalancerStrategyV3 strategy = getStrategy(myConfig);
    List<DegraderTrackerClient> clients = new ArrayList<>();
    Map<URI, Integer> pointsMap = new HashMap<>();
    long clusterCallCount = 15;
    RingFactory<URI> ringFactory = new DelegatingRingFactory<>(new DegraderLoadBalancerStrategyConfig(1L));
    URI uri1 = URI.create("http://test.linkedin.com:3242/fdsaf");
    URI uri2 = URI.create("http://test.linkedin.com:3243/fdsaf");
    clients.add(getClient(uri1));
    clients.add(getClient(uri2));
    pointsMap.put(uri1, 1);
    pointsMap.put(uri2, 1);
    PartitionDegraderLoadBalancerState current = strategy.getState().getPartitionState(DEFAULT_PARTITION_ID);
    current = new PartitionDegraderLoadBalancerState(0, testClock._currentTimeMillis, true, ringFactory, pointsMap, PartitionDegraderLoadBalancerState.Strategy.LOAD_BALANCE, 0.0, -1, new HashMap<>(), "Test", current.getDegraderProperties(), clusterCallCount, 0, 0, Collections.emptyMap(), Collections.emptyMap(), null, 0);
    strategy.getState().setPartitionState(DEFAULT_PARTITION_ID, current);
    // state is default initialized, new cluster generation
    assertFalse(DegraderLoadBalancerStrategyV3.shouldUpdatePartition(0, strategy.getState().getPartitionState(DEFAULT_PARTITION_ID), strategy.getConfig(), true, false, clients));
    // state is not null, but we're on the same cluster generation id, and 5 seconds
    // haven't gone by
    testClock.addMs(1);
    assertFalse(DegraderLoadBalancerStrategyV3.shouldUpdatePartition(0, strategy.getState().getPartitionState(DEFAULT_PARTITION_ID), strategy.getConfig(), true, false, clients));
    testClock.addMs(5000);
    assertTrue(DegraderLoadBalancerStrategyV3.shouldUpdatePartition(1, strategy.getState().getPartitionState(DEFAULT_PARTITION_ID), strategy.getConfig(), true, false, clients));
    current = new PartitionDegraderLoadBalancerState(1, testClock._currentTimeMillis, true, new DelegatingRingFactory<>(new DegraderLoadBalancerStrategyConfig(1L)), pointsMap, PartitionDegraderLoadBalancerState.Strategy.LOAD_BALANCE, 0.0, -1, new HashMap<>(), "Test", current.getDegraderProperties(), clusterCallCount, 0, 0, Collections.emptyMap(), Collections.emptyMap(), null, 0);
    strategy.getState().setPartitionState(DEFAULT_PARTITION_ID, current);
}
Also used : HashMap(java.util.HashMap) DegraderTrackerClient(com.linkedin.d2.balancer.clients.DegraderTrackerClient) ArrayList(java.util.ArrayList) URI(java.net.URI) DelegatingRingFactory(com.linkedin.d2.balancer.strategies.DelegatingRingFactory) Test(org.testng.annotations.Test) DegraderTrackerClientTest(com.linkedin.d2.balancer.clients.DegraderTrackerClientTest)

Example 45 with DEFAULT_PARTITION_ID

use of com.linkedin.d2.balancer.util.partitions.DefaultPartitionAccessor.DEFAULT_PARTITION_ID in project rest.li by linkedin.

the class DegraderLoadBalancerTest method testBalancingRing.

@Test(groups = { "small", "back-end" }, dataProvider = "consistentHashAlgorithms")
public void testBalancingRing(String consistentHashAlgorithm) throws URISyntaxException {
    DegraderLoadBalancerStrategyV3 strategy = getStrategy(consistentHashAlgorithm);
    List<DegraderTrackerClient> clients = new ArrayList<>();
    URI uri1 = URI.create("http://someTestService/someTestUrl");
    URI uri2 = URI.create("http://abcxfweuoeueoueoueoukeueoueoueoueoueouo/2354");
    TestClock clock1 = new TestClock();
    TestClock clock2 = new TestClock();
    DegraderTrackerClient client1 = getClient(uri1, clock1);
    DegraderTrackerClient client2 = getClient(uri2, clock2);
    clients.add(client1);
    clients.add(client2);
    // force client2 to be disabled
    DegraderControl dcClient2Default = client2.getDegraderControl(DEFAULT_PARTITION_ID);
    dcClient2Default.setOverrideMinCallCount(1);
    dcClient2Default.setMinCallCount(1);
    dcClient2Default.setMaxDropRate(1d);
    dcClient2Default.setUpStep(0.4d);
    dcClient2Default.setHighErrorRate(0);
    CallCompletion cc = client2.getCallTracker().startCall();
    clock2.addMs(1);
    cc.endCallWithError();
    clock1.addMs(15000);
    clock2.addMs(5000);
    // now do a basic verification to verify getTrackerClient is properly weighting things
    double calls = 10000d;
    int client1Count = 0;
    int client2Count = 0;
    double tolerance = 0.05d;
    for (int i = 0; i < calls; ++i) {
        TrackerClient client = getTrackerClient(strategy, null, new RequestContext(), 1, clients);
        assertNotNull(client);
        if (client.getUri().equals(uri1)) {
            ++client1Count;
        } else {
            ++client2Count;
        }
    }
    assertTrue(Math.abs((client1Count / calls) - (100 / 160d)) < tolerance);
    assertTrue(Math.abs((client2Count / calls) - (60 / 160d)) < tolerance);
}
Also used : CallCompletion(com.linkedin.util.degrader.CallCompletion) DegraderTrackerClient(com.linkedin.d2.balancer.clients.DegraderTrackerClient) TrackerClient(com.linkedin.d2.balancer.clients.TrackerClient) DegraderTrackerClient(com.linkedin.d2.balancer.clients.DegraderTrackerClient) ArrayList(java.util.ArrayList) DegraderControl(com.linkedin.util.degrader.DegraderControl) RequestContext(com.linkedin.r2.message.RequestContext) URI(java.net.URI) Test(org.testng.annotations.Test) DegraderTrackerClientTest(com.linkedin.d2.balancer.clients.DegraderTrackerClientTest)

Aggregations

Test (org.testng.annotations.Test)32 TrackerClient (com.linkedin.d2.balancer.clients.TrackerClient)30 URI (java.net.URI)28 ArrayList (java.util.ArrayList)26 DegraderTrackerClient (com.linkedin.d2.balancer.clients.DegraderTrackerClient)21 RequestContext (com.linkedin.r2.message.RequestContext)19 DegraderTrackerClientTest (com.linkedin.d2.balancer.clients.DegraderTrackerClientTest)17 DegraderControl (com.linkedin.util.degrader.DegraderControl)12 HashMap (java.util.HashMap)12 URIRequest (com.linkedin.d2.balancer.util.URIRequest)11 D2RelativeStrategyProperties (com.linkedin.d2.D2RelativeStrategyProperties)10 CallCompletion (com.linkedin.util.degrader.CallCompletion)10 ScheduledExecutorService (java.util.concurrent.ScheduledExecutorService)9 ConcurrentHashMap (java.util.concurrent.ConcurrentHashMap)7 AtomicLong (java.util.concurrent.atomic.AtomicLong)7 DegraderTrackerClientImpl (com.linkedin.d2.balancer.clients.DegraderTrackerClientImpl)6 HashSet (java.util.HashSet)6 CountDownLatch (java.util.concurrent.CountDownLatch)6 FutureCallback (com.linkedin.common.callback.FutureCallback)5 None (com.linkedin.common.util.None)5