Search in sources :

Example 46 with DegraderLoadBalancerStrategyV3

use of com.linkedin.d2.balancer.strategies.degrader.DegraderLoadBalancerStrategyV3 in project rest.li by linkedin.

the class RetryClientTest method prepareLoadBalancer.

public SimpleLoadBalancer prepareLoadBalancer(List<String> uris, double maxClientRequestRetryRatio) throws URISyntaxException {
    String serviceName = "retryService";
    String clusterName = "cluster";
    String path = "";
    String strategyName = "degrader";
    // setup partition
    Map<URI, Map<Integer, PartitionData>> partitionDescriptions = new HashMap<>();
    for (String uri : uris) {
        final URI foo = URI.create(uri);
        Map<Integer, PartitionData> foo1Data = new HashMap<>();
        // ensure that we first route to the retry uris before the good uris
        double weight = uri.contains("good") ? 0.1 : 1.0;
        foo1Data.put(0, new PartitionData(weight));
        partitionDescriptions.put(foo, foo1Data);
    }
    DegraderLoadBalancerStrategyV3 strategy = new DegraderLoadBalancerStrategyV3(new DegraderLoadBalancerStrategyConfig(5000), serviceName, null, Collections.emptyList());
    List<LoadBalancerState.SchemeStrategyPair> orderedStrategies = new ArrayList<>();
    orderedStrategies.add(new LoadBalancerState.SchemeStrategyPair("http", strategy));
    PartitionAccessor accessor = new TestRetryPartitionAccessor();
    SimpleLoadBalancer balancer = new SimpleLoadBalancer(new PartitionedLoadBalancerTestState(clusterName, serviceName, path, strategyName, partitionDescriptions, orderedStrategies, accessor, maxClientRequestRetryRatio), _executor);
    return balancer;
}
Also used : SimpleLoadBalancer(com.linkedin.d2.balancer.simple.SimpleLoadBalancer) HashMap(java.util.HashMap) DegraderLoadBalancerStrategyConfig(com.linkedin.d2.balancer.strategies.degrader.DegraderLoadBalancerStrategyConfig) ArrayList(java.util.ArrayList) PartitionedLoadBalancerTestState(com.linkedin.d2.balancer.PartitionedLoadBalancerTestState) ByteString(com.linkedin.data.ByteString) URI(java.net.URI) LoadBalancerState(com.linkedin.d2.balancer.LoadBalancerState) DegraderLoadBalancerStrategyV3(com.linkedin.d2.balancer.strategies.degrader.DegraderLoadBalancerStrategyV3) PartitionAccessor(com.linkedin.d2.balancer.util.partitions.PartitionAccessor) PartitionData(com.linkedin.d2.balancer.properties.PartitionData) HashMap(java.util.HashMap) Map(java.util.Map)

Example 47 with DegraderLoadBalancerStrategyV3

use of com.linkedin.d2.balancer.strategies.degrader.DegraderLoadBalancerStrategyV3 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 48 with DegraderLoadBalancerStrategyV3

use of com.linkedin.d2.balancer.strategies.degrader.DegraderLoadBalancerStrategyV3 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 49 with DegraderLoadBalancerStrategyV3

use of com.linkedin.d2.balancer.strategies.degrader.DegraderLoadBalancerStrategyV3 in project rest.li by linkedin.

the class DegraderLoadBalancerTest method testBadTrackerClients.

@Test(groups = { "small", "back-end" })
public void testBadTrackerClients() throws URISyntaxException {
    DegraderLoadBalancerStrategyV3 strategy = getStrategy();
    // test null twice (first time will have no state)
    for (int i = 0; i < 2; ++i) {
        assertNull(getTrackerClient(strategy, null, new RequestContext(), 0, null));
    }
    strategy = getStrategy();
    // test empty twice (first time will have no state)
    for (int i = 0; i < 2; ++i) {
        assertNull(getTrackerClient(strategy, null, new RequestContext(), 0, new ArrayList<>()));
    }
    // test same cluster generation id but different client lists
    strategy = getStrategy();
    List<DegraderTrackerClient> clients1 = new ArrayList<>();
    SettableClock clock1 = new SettableClock();
    SettableClock clock2 = new SettableClock();
    List<DegraderTrackerClient> clients2 = new ArrayList<>();
    SettableClock clock3 = new SettableClock();
    SettableClock clock4 = new SettableClock();
    clients1.add(getClient(URI.create("http://test.linkedin.com:3242/fdsaf"), clock1));
    clients1.add(getClient(URI.create("http://test.linkedin.com:3243/fdsaf"), clock2));
    clients2.add(getClient(URI.create("http://asdbasdf.com:3242/fdsaf"), clock3));
    clients2.add(getClient(URI.create("ftp://example.com:21/what"), clock4));
    // same cluster generation id but different tracker clients
    assertNotNull(getTrackerClient(strategy, null, new RequestContext(), 0, clients2));
    assertNull(getTrackerClient(strategy, null, new RequestContext(), 0, clients1));
    // now trigger an update by cluster generation id
    assertNotNull(getTrackerClient(strategy, null, new RequestContext(), 1, clients1));
    assertNull(getTrackerClient(strategy, null, new RequestContext(), 1, clients2));
}
Also used : DegraderTrackerClient(com.linkedin.d2.balancer.clients.DegraderTrackerClient) ArrayList(java.util.ArrayList) SettableClock(com.linkedin.util.clock.SettableClock) RequestContext(com.linkedin.r2.message.RequestContext) Test(org.testng.annotations.Test) DegraderTrackerClientTest(com.linkedin.d2.balancer.clients.DegraderTrackerClientTest)

Example 50 with DegraderLoadBalancerStrategyV3

use of com.linkedin.d2.balancer.strategies.degrader.DegraderLoadBalancerStrategyV3 in project rest.li by linkedin.

the class DegraderLoadBalancerTest method testLowTrafficHighLatency100Clients.

@Test(groups = { "small", "back-end" })
public void testLowTrafficHighLatency100Clients() {
    Map<String, Object> myMap = lbDefaultConfig();
    Long timeInterval = 5000L;
    TestClock clock = new TestClock();
    myMap.put(PropertyKeys.CLOCK, clock);
    myMap.put(PropertyKeys.HTTP_LB_STRATEGY_PROPERTIES_UPDATE_INTERVAL_MS, timeInterval);
    // we need to override the min call count to 0 because we're testing a service with low traffic.
    // if we don't do this, the computedDropRate will not change and we will never be able to recover
    // after we degraded the cluster.
    Map<String, String> degraderImplProperties = degraderDefaultConfig();
    degraderImplProperties.put(PropertyKeys.DEGRADER_MIN_CALL_COUNT, "1");
    degraderImplProperties.put(PropertyKeys.DEGRADER_HIGH_ERROR_RATE, "0.5");
    degraderImplProperties.put(PropertyKeys.DEGRADER_LOW_ERROR_RATE, "0.2");
    DegraderImpl.Config degraderConfig = DegraderConfigFactory.toDegraderConfig(degraderImplProperties);
    double qps = 0.3;
    // test Strategy V3
    List<DegraderTrackerClient> clients = createTrackerClient(100, clock, degraderConfig);
    DegraderLoadBalancerStrategyConfig config = DegraderLoadBalancerStrategyConfig.createHttpConfigFromMap(myMap);
    DegraderLoadBalancerStrategyV3 strategyV3 = new DegraderLoadBalancerStrategyV3(config, "DegraderLoadBalancerTest", null, DEGRADER_STATE_LISTENER_FACTORIES);
    DegraderLoadBalancerStrategyAdapter strategy = new DegraderLoadBalancerStrategyAdapter(strategyV3);
    testDegraderLoadBalancerSimulator(strategy, clock, timeInterval, clients, qps, degraderConfig);
}
Also used : DegraderTrackerClient(com.linkedin.d2.balancer.clients.DegraderTrackerClient) DegraderImpl(com.linkedin.util.degrader.DegraderImpl) AtomicLong(java.util.concurrent.atomic.AtomicLong) Test(org.testng.annotations.Test) DegraderTrackerClientTest(com.linkedin.d2.balancer.clients.DegraderTrackerClientTest)

Aggregations

Test (org.testng.annotations.Test)49 DegraderTrackerClientTest (com.linkedin.d2.balancer.clients.DegraderTrackerClientTest)44 DegraderTrackerClient (com.linkedin.d2.balancer.clients.DegraderTrackerClient)40 ArrayList (java.util.ArrayList)35 URI (java.net.URI)27 RequestContext (com.linkedin.r2.message.RequestContext)23 HashMap (java.util.HashMap)20 AtomicLong (java.util.concurrent.atomic.AtomicLong)19 TrackerClient (com.linkedin.d2.balancer.clients.TrackerClient)16 DegraderImpl (com.linkedin.util.degrader.DegraderImpl)14 DegraderTrackerClientImpl (com.linkedin.d2.balancer.clients.DegraderTrackerClientImpl)10 CallCompletion (com.linkedin.util.degrader.CallCompletion)9 DegraderControl (com.linkedin.util.degrader.DegraderControl)9 DegraderLoadBalancerStrategyV3 (com.linkedin.d2.balancer.strategies.degrader.DegraderLoadBalancerStrategyV3)6 PartitionData (com.linkedin.d2.balancer.properties.PartitionData)5 URIRequest (com.linkedin.d2.balancer.util.URIRequest)5 NullStateListenerCallback (com.linkedin.d2.balancer.LoadBalancerState.NullStateListenerCallback)4 ClusterProperties (com.linkedin.d2.balancer.properties.ClusterProperties)4 ServiceProperties (com.linkedin.d2.balancer.properties.ServiceProperties)4 LoadBalancerStrategy (com.linkedin.d2.balancer.strategies.LoadBalancerStrategy)4