Search in sources :

Example 16 with PartitionState

use of com.linkedin.d2.balancer.strategies.relative.PartitionState in project rest.li by linkedin.

the class StateUpdaterTest method testHealthScoreDrop.

@Test(dataProvider = "trackerClients")
public void testHealthScoreDrop(List<TrackerClient> trackerClients, double highLatencyFactor, double highErrorRate, boolean expectToDropHealthScore) {
    PartitionState state = new PartitionStateTestDataBuilder().setClusterGenerationId(DEFAULT_CLUSTER_GENERATION_ID).setTrackerClientStateMap(trackerClients, Arrays.asList(StateUpdater.MAX_HEALTH_SCORE, StateUpdater.MAX_HEALTH_SCORE, StateUpdater.MAX_HEALTH_SCORE), 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().setRelativeLatencyHighThresholdFactor(highLatencyFactor).setHighErrorRate(highErrorRate), partitionLoadBalancerStateMap);
    _stateUpdater.updateState();
    Map<URI, Integer> pointsMap = _stateUpdater.getPointsMap(DEFAULT_PARTITION_ID);
    if (!expectToDropHealthScore) {
        assertEquals(pointsMap.get(trackerClients.get(0).getUri()).intValue(), HEALTHY_POINTS);
        assertEquals(pointsMap.get(trackerClients.get(1).getUri()).intValue(), HEALTHY_POINTS);
        assertEquals(pointsMap.get(trackerClients.get(2).getUri()).intValue(), HEALTHY_POINTS);
    } else {
        assertEquals(pointsMap.get(trackerClients.get(0).getUri()).intValue(), (int) (HEALTHY_POINTS - RelativeLoadBalancerStrategyFactory.DEFAULT_DOWN_STEP * RelativeLoadBalancerStrategyFactory.DEFAULT_POINTS_PER_WEIGHT));
        assertEquals(pointsMap.get(trackerClients.get(1).getUri()).intValue(), HEALTHY_POINTS);
        assertEquals(pointsMap.get(trackerClients.get(2).getUri()).intValue(), HEALTHY_POINTS);
    }
}
Also used : ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) URI(java.net.URI) D2RelativeStrategyProperties(com.linkedin.d2.D2RelativeStrategyProperties) Test(org.testng.annotations.Test)

Example 17 with PartitionState

use of com.linkedin.d2.balancer.strategies.relative.PartitionState in project rest.li by linkedin.

the class StateUpdaterTest method testClusterUrisChange.

@Test
public void testClusterUrisChange() {
    List<TrackerClient> trackerClients = TrackerClientMockHelper.mockTrackerClients(3, Arrays.asList(20, 20, 20), Arrays.asList(10, 10, 10), Arrays.asList(200L, 220L, 1000L), Arrays.asList(100L, 110L, 500L), Arrays.asList(0, 0, 0));
    PartitionState state = new PartitionStateTestDataBuilder().setClusterGenerationId(DEFAULT_CLUSTER_GENERATION_ID).setTrackerClientStateMap(trackerClients, Arrays.asList(StateUpdater.MAX_HEALTH_SCORE, StateUpdater.MAX_HEALTH_SCORE, StateUpdater.MAX_HEALTH_SCORE), 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);
    // New tracker clients set only contains 2 out of 3 tracker clients from the old state
    Set<TrackerClient> newTrackerClientSet = new HashSet<>();
    newTrackerClientSet.add(trackerClients.get(0));
    newTrackerClientSet.add(trackerClients.get(1));
    _stateUpdater.updateStateForPartition(newTrackerClientSet, DEFAULT_PARTITION_ID, state, 1L, false);
    Map<URI, Integer> pointsMap = _stateUpdater.getPointsMap(DEFAULT_PARTITION_ID);
    assertEquals(pointsMap.size(), 2, "There should only be 2 uris after cluster id change");
    assertEquals(pointsMap.get(trackerClients.get(0).getUri()).intValue(), HEALTHY_POINTS);
    assertEquals(pointsMap.get(trackerClients.get(1).getUri()).intValue(), HEALTHY_POINTS);
}
Also used : TrackerClient(com.linkedin.d2.balancer.clients.TrackerClient) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) URI(java.net.URI) D2RelativeStrategyProperties(com.linkedin.d2.D2RelativeStrategyProperties) HashSet(java.util.HashSet) Test(org.testng.annotations.Test)

Example 18 with PartitionState

use of com.linkedin.d2.balancer.strategies.relative.PartitionState 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 19 with PartitionState

use of com.linkedin.d2.balancer.strategies.relative.PartitionState in project rest.li by linkedin.

the class QuarantineManager method enrollNewQuarantineAndRecovery.

/**
 * Enroll new tracker client to quarantine or recovery state
 *
 * @param newPartitionState The new state of the partition
 * @param oldPartitionState The old state of the partition
 * @param quarantineLatency The latency threshold for D2 quarantine
 */
private void enrollNewQuarantineAndRecovery(PartitionState newPartitionState, PartitionState oldPartitionState, long quarantineLatency, long currentTime) {
    int partitionId = newPartitionState.getPartitionId();
    Map<TrackerClient, LoadBalancerQuarantine> quarantineMap = newPartitionState.getQuarantineMap();
    Map<TrackerClient, LoadBalancerQuarantine> quarantineHistory = newPartitionState.getQuarantineHistory();
    Set<TrackerClient> recoverySet = newPartitionState.getRecoveryTrackerClients();
    for (TrackerClient trackerClient : newPartitionState.getTrackerClients()) {
        TrackerClientState trackerClientState = newPartitionState.getTrackerClientStateMap().get(trackerClient);
        double serverWeight = trackerClient.getPartitionWeight(partitionId);
        // Check and enroll quarantine map
        boolean isQuarantined = enrollClientInQuarantineMap(trackerClient, trackerClientState, serverWeight, quarantineMap, quarantineHistory, newPartitionState.getTrackerClientStateMap().size(), quarantineLatency, currentTime);
        if (!isQuarantined) {
            if (!_fastRecoveryEnabled) {
                performNormalRecovery(trackerClientState);
            } else {
                // Only enroll the client into recovery state if fast recovery is enabled
                enrollSingleClientInRecoverySet(trackerClient, trackerClientState, serverWeight, recoverySet, oldPartitionState);
            }
        }
    }
}
Also used : LoadBalancerQuarantine(com.linkedin.d2.balancer.strategies.LoadBalancerQuarantine) TrackerClient(com.linkedin.d2.balancer.clients.TrackerClient)

Example 20 with PartitionState

use of com.linkedin.d2.balancer.strategies.relative.PartitionState in project rest.li by linkedin.

the class StateUpdater method updateBaseHealthScoreAndState.

/**
 * Update the health score of all tracker clients for the service
 */
private void updateBaseHealthScoreAndState(Set<TrackerClient> trackerClients, PartitionState partitionState, long clusterAvgLatency, boolean clusterUpdated, Map<TrackerClient, CallTracker.CallStats> lastCallStatsMap) {
    // Calculate the base health score before we override them when handling the quarantine and recovery
    calculateBaseHealthScore(trackerClients, partitionState, clusterAvgLatency, lastCallStatsMap);
    // Remove the trackerClients from original map if there is any change in uri list
    Map<TrackerClient, TrackerClientState> trackerClientStateMap = partitionState.getTrackerClientStateMap();
    if (clusterUpdated) {
        List<TrackerClient> trackerClientsToRemove = trackerClientStateMap.keySet().stream().filter(oldTrackerClient -> !trackerClients.contains(oldTrackerClient)).collect(Collectors.toList());
        for (TrackerClient trackerClient : trackerClientsToRemove) {
            partitionState.removeTrackerClient(trackerClient);
        }
    }
}
Also used : Logger(org.slf4j.Logger) ReentrantLock(java.util.concurrent.locks.ReentrantLock) D2RelativeStrategyProperties(com.linkedin.d2.D2RelativeStrategyProperties) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) LoggerFactory(org.slf4j.LoggerFactory) Set(java.util.Set) HashMap(java.util.HashMap) Collectors(java.util.stream.Collectors) PartitionStateUpdateListener(com.linkedin.d2.balancer.strategies.PartitionStateUpdateListener) ConcurrentMap(java.util.concurrent.ConcurrentMap) TimeUnit(java.util.concurrent.TimeUnit) ErrorType(com.linkedin.util.degrader.ErrorType) List(java.util.List) Lock(java.util.concurrent.locks.Lock) CallTracker(com.linkedin.util.degrader.CallTracker) Map(java.util.Map) ScheduledExecutorService(java.util.concurrent.ScheduledExecutorService) DelegatingRingFactory(com.linkedin.d2.balancer.strategies.DelegatingRingFactory) Ring(com.linkedin.d2.balancer.util.hashing.Ring) URI(java.net.URI) TrackerClient(com.linkedin.d2.balancer.clients.TrackerClient) TrackerClient(com.linkedin.d2.balancer.clients.TrackerClient)

Aggregations

TrackerClient (com.linkedin.d2.balancer.clients.TrackerClient)17 Test (org.testng.annotations.Test)12 D2RelativeStrategyProperties (com.linkedin.d2.D2RelativeStrategyProperties)10 ConcurrentHashMap (java.util.concurrent.ConcurrentHashMap)9 URI (java.net.URI)6 LoadBalancerQuarantine (com.linkedin.d2.balancer.strategies.LoadBalancerQuarantine)5 HashMap (java.util.HashMap)5 ScheduledExecutorService (java.util.concurrent.ScheduledExecutorService)5 CountDownLatch (java.util.concurrent.CountDownLatch)4 CallTracker (com.linkedin.util.degrader.CallTracker)2 ArrayList (java.util.ArrayList)2 HashSet (java.util.HashSet)2 None (com.linkedin.common.util.None)1 DegraderTrackerClient (com.linkedin.d2.balancer.clients.DegraderTrackerClient)1 DelegatingRingFactory (com.linkedin.d2.balancer.strategies.DelegatingRingFactory)1 PartitionStateUpdateListener (com.linkedin.d2.balancer.strategies.PartitionStateUpdateListener)1 PartitionState (com.linkedin.d2.balancer.strategies.relative.PartitionState)1 RelativeLoadBalancerStrategy (com.linkedin.d2.balancer.strategies.relative.RelativeLoadBalancerStrategy)1 TrackerClientState (com.linkedin.d2.balancer.strategies.relative.TrackerClientState)1 Ring (com.linkedin.d2.balancer.util.hashing.Ring)1