use of com.linkedin.d2.hashMethodEnum in project rest.li by linkedin.
the class SimpleLoadBalancer method getPartitionInformation.
/**
* If given a collection of keys, the method will maps keys to partitions and
* return the servers that belongs to that partition up to limitHostPerPartition.
*
* If no keys are specified, the method will return hosts in all partitions
*
* @param serviceUri for example d2://articles
* @param keys all the keys we want to find the partition for
* @param limitHostPerPartition the number of hosts that we should return for this partition. Must be larger than 0.
* @param hash this will be used to create Iterator for the hosts in the hash ring
* @return Number of hosts in requested partitions. See {@link com.linkedin.d2.balancer.util.HostToKeyMapper} for more details.
* @throws ServiceUnavailableException
*/
@Override
public <K> HostToKeyMapper<K> getPartitionInformation(URI serviceUri, Collection<K> keys, int limitHostPerPartition, int hash) throws ServiceUnavailableException {
if (limitHostPerPartition <= 0) {
throw new IllegalArgumentException("limitHostPartition cannot be 0 or less");
}
ServiceProperties service = listenToServiceAndCluster(serviceUri);
String serviceName = service.getServiceName();
String clusterName = service.getClusterName();
ClusterProperties cluster = getClusterProperties(serviceName, clusterName);
LoadBalancerStateItem<UriProperties> uriItem = getUriItem(serviceName, clusterName, cluster);
UriProperties uris = uriItem.getProperty();
List<LoadBalancerState.SchemeStrategyPair> orderedStrategies = _state.getStrategiesForService(serviceName, service.getPrioritizedSchemes());
Map<Integer, Integer> partitionWithoutEnoughHost = new HashMap<Integer, Integer>();
if (!orderedStrategies.isEmpty()) {
// get the partitionId -> keys mapping
final PartitionAccessor accessor = getPartitionAccessor(serviceName, clusterName);
int maxPartitionId = accessor.getMaxPartitionId();
List<K> unmappedKeys = new ArrayList<K>();
Map<Integer, Set<K>> partitionSet = getPartitionSet(keys, accessor, unmappedKeys);
final LoadBalancerState.SchemeStrategyPair pair = orderedStrategies.get(0);
//get the partitionId -> host URIs list
Map<Integer, KeysAndHosts<K>> partitionDataMap = new HashMap<Integer, KeysAndHosts<K>>();
for (Integer partitionId : partitionSet.keySet()) {
Set<URI> possibleUris = uris.getUriBySchemeAndPartition(pair.getScheme(), partitionId);
List<TrackerClient> trackerClients = getPotentialClients(serviceName, service, possibleUris);
int size = trackerClients.size() <= limitHostPerPartition ? trackerClients.size() : limitHostPerPartition;
List<URI> rankedUri = new ArrayList<URI>(size);
Ring<URI> ring = pair.getStrategy().getRing(uriItem.getVersion(), partitionId, trackerClients);
Iterator<URI> iterator = ring.getIterator(hash);
while (iterator.hasNext() && rankedUri.size() < size) {
URI uri = iterator.next();
if (!rankedUri.contains(uri)) {
rankedUri.add(uri);
}
}
if (rankedUri.size() < limitHostPerPartition) {
partitionWithoutEnoughHost.put(partitionId, limitHostPerPartition - rankedUri.size());
}
KeysAndHosts<K> keysAndHosts = new KeysAndHosts<K>(partitionSet.get(partitionId), rankedUri);
partitionDataMap.put(partitionId, keysAndHosts);
}
return new HostToKeyMapper<K>(unmappedKeys, partitionDataMap, limitHostPerPartition, maxPartitionId + 1, partitionWithoutEnoughHost);
} else {
throw new ServiceUnavailableException(serviceName, "Unable to find a load balancer strategy");
}
}
use of com.linkedin.d2.hashMethodEnum in project rest.li by linkedin.
the class LoadBalancerStrategyPropertiesConverterTest method testLoadBalancerStrategyPropertiesConverter.
@Test
public void testLoadBalancerStrategyPropertiesConverter() {
final Double globalStepDown = 0.4;
final Double globalStepUp = 0.3;
final Double recoveryLevel = 1.0;
final Double ringRampFactor = 0.01;
final Double highWaterMark = 1000d;
final Double lowWaterMark = 500d;
final Integer pointsPerWeight = 100;
final Long updateIntervalMs = 50000l;
final Integer minCallCountHighWaterMark = 3000;
final Integer minCallCountLowWaterMark = 1500;
final hashMethodEnum hashMethod = hashMethodEnum.URI_REGEX;
final hashConfigType hashConfig = new hashConfigType();
final StringArray regexes = new StringArray();
final Double hashringPointCleanupRate = 0.2;
final ConsistentHashAlgorithmEnum consistentHashAlgorithm = ConsistentHashAlgorithmEnum.MULTI_PROBE;
final Integer numProbes = 1024;
final Double quarantineMaxPercent = 0.2;
final String quarantineMethod = "OPTIONS:/test/path";
final Long quarantineLatency = 200l;
final quarantineInfo quarantineInfo = new quarantineInfo().setQuarantineMaxPercent(quarantineMaxPercent).setQuarantineMethod(quarantineMethod).setQuarantineLatency(quarantineLatency);
final String errorStatusRegex = "(5..)";
regexes.add("+231{w+)");
hashConfig.setUriRegexes(regexes);
hashConfig.setWarnOnNoMatch(false);
hashConfig.setFailOnNoMatch(true);
Map<String, Object> loadBalancerStrategyProperties = new HashMap<>();
loadBalancerStrategyProperties.put(PropertyKeys.HTTP_LB_GLOBAL_STEP_DOWN, globalStepDown.toString());
loadBalancerStrategyProperties.put(PropertyKeys.HTTP_LB_GLOBAL_STEP_UP, globalStepUp.toString());
loadBalancerStrategyProperties.put(PropertyKeys.HTTP_LB_INITIAL_RECOVERY_LEVEL, recoveryLevel.toString());
loadBalancerStrategyProperties.put(PropertyKeys.HTTP_LB_RING_RAMP_FACTOR, ringRampFactor.toString());
loadBalancerStrategyProperties.put(PropertyKeys.HTTP_LB_HIGH_WATER_MARK, highWaterMark.toString());
loadBalancerStrategyProperties.put(PropertyKeys.HTTP_LB_LOW_WATER_MARK, lowWaterMark.toString());
loadBalancerStrategyProperties.put(PropertyKeys.HTTP_LB_STRATEGY_PROPERTIES_POINTS_PER_WEIGHT, pointsPerWeight.toString());
loadBalancerStrategyProperties.put(PropertyKeys.HTTP_LB_STRATEGY_PROPERTIES_UPDATE_INTERVAL_MS, updateIntervalMs.toString());
loadBalancerStrategyProperties.put(PropertyKeys.HTTP_LB_CLUSTER_MIN_CALL_COUNT_HIGH_WATER_MARK, minCallCountHighWaterMark.toString());
loadBalancerStrategyProperties.put(PropertyKeys.HTTP_LB_CLUSTER_MIN_CALL_COUNT_LOW_WATER_MARK, minCallCountLowWaterMark.toString());
loadBalancerStrategyProperties.put(PropertyKeys.HTTP_LB_HASH_METHOD, DegraderLoadBalancerStrategyV3.HASH_METHOD_URI_REGEX);
loadBalancerStrategyProperties.put(PropertyKeys.HTTP_LB_HASHRING_POINT_CLEANUP_RATE, hashringPointCleanupRate.toString());
loadBalancerStrategyProperties.put(PropertyKeys.HTTP_LB_CONSISTENT_HASH_ALGORITHM, DegraderRingFactory.MULTI_PROBE_CONSISTENT_HASH);
loadBalancerStrategyProperties.put(PropertyKeys.HTTP_LB_CONSISTENT_HASH_NUM_PROBES, numProbes.toString());
Map<String, Object> hashConfigMap = new HashMap<>();
hashConfigMap.put(URIRegexHash.KEY_REGEXES, regexes.stream().collect(Collectors.toList()));
hashConfigMap.put(URIRegexHash.KEY_WARN_ON_NO_MATCH, "false");
hashConfigMap.put(URIRegexHash.KEY_FAIL_ON_NO_MATCH, "true");
loadBalancerStrategyProperties.put(PropertyKeys.HTTP_LB_HASH_CONFIG, hashConfigMap);
loadBalancerStrategyProperties.put(PropertyKeys.HTTP_LB_QUARANTINE_MAX_PERCENT, quarantineMaxPercent.toString());
loadBalancerStrategyProperties.put(PropertyKeys.HTTP_LB_QUARANTINE_METHOD, quarantineMethod);
loadBalancerStrategyProperties.put(PropertyKeys.HTTP_LB_QUARANTINE_LATENCY, quarantineLatency.toString());
loadBalancerStrategyProperties.put(PropertyKeys.HTTP_LB_ERROR_STATUS_REGEX, errorStatusRegex);
D2LoadBalancerStrategyProperties d2LoadBalancerStrategyProperties = new D2LoadBalancerStrategyProperties().setGlobalStepDown(globalStepDown).setGlobalStepUp(globalStepUp).setInitialRecoveryLevel(recoveryLevel).setRingRampFactor(ringRampFactor).setHighWaterMark(highWaterMark).setLowWaterMark(lowWaterMark).setPointsPerWeight(pointsPerWeight).setUpdateIntervalMs(updateIntervalMs).setMinCallCountHighWaterMark(minCallCountHighWaterMark).setMinCallCountLowWaterMark(minCallCountLowWaterMark).setHashMethod(hashMethod).setHashConfig(hashConfig).setHashRingPointCleanupRate(hashringPointCleanupRate).setConsistentHashAlgorithm(consistentHashAlgorithm).setNumberOfProbes(numProbes).setQuarantineCfg(quarantineInfo).setErrorStatusRegex(errorStatusRegex);
Assert.assertEquals(LoadBalancerStrategyPropertiesConverter.toConfig(loadBalancerStrategyProperties), d2LoadBalancerStrategyProperties);
Assert.assertEquals(LoadBalancerStrategyPropertiesConverter.toProperties(d2LoadBalancerStrategyProperties), loadBalancerStrategyProperties);
}
use of com.linkedin.d2.hashMethodEnum in project rest.li by linkedin.
the class PartitionPropertiesConverterTest method testHashModuloPartitionProperties.
@Test
public void testHashModuloPartitionProperties() {
final String partitionKeyRegex = "/foo/bar/(\\d+)";
final int partitionCount = 16;
final HashBasedPartitionProperties.HashAlgorithm hashAlgorithm = HashBasedPartitionProperties.HashAlgorithm.MODULO;
PartitionProperties partitionProperties = new HashBasedPartitionProperties(partitionKeyRegex, partitionCount, hashAlgorithm);
D2ClusterPartitionConfiguration.PartitionTypeSpecificData data = new D2ClusterPartitionConfiguration.PartitionTypeSpecificData();
data.setHashAlgorithm(com.linkedin.d2.hashAlgorithm.MODULO);
D2ClusterPartitionConfiguration partitionConfig = new D2ClusterPartitionConfiguration().setType(PartitionTypeEnum.HASH).setPartitionKeyRegex(partitionKeyRegex).setPartitionCount(partitionCount).setPartitionTypeSpecificData(data);
Assert.assertEquals(PartitionPropertiesConverter.toConfig(partitionProperties), partitionConfig);
Assert.assertEquals(PartitionPropertiesConverter.toProperties(partitionConfig), partitionProperties);
}
use of com.linkedin.d2.hashMethodEnum in project rest.li by linkedin.
the class PartitionPropertiesConverterTest method testHashMD5PartitionProperties.
@Test
public void testHashMD5PartitionProperties() {
final String partitionKeyRegex = "/foo/bar/(\\d+)";
final int partitionCount = 8;
final HashBasedPartitionProperties.HashAlgorithm hashAlgorithm = HashBasedPartitionProperties.HashAlgorithm.MD5;
PartitionProperties partitionProperties = new HashBasedPartitionProperties(partitionKeyRegex, partitionCount, hashAlgorithm);
D2ClusterPartitionConfiguration.PartitionTypeSpecificData data = new D2ClusterPartitionConfiguration.PartitionTypeSpecificData();
data.setHashAlgorithm(com.linkedin.d2.hashAlgorithm.MD5);
D2ClusterPartitionConfiguration partitionConfig = new D2ClusterPartitionConfiguration().setType(PartitionTypeEnum.HASH).setPartitionKeyRegex(partitionKeyRegex).setPartitionCount(partitionCount).setPartitionTypeSpecificData(data);
Assert.assertEquals(PartitionPropertiesConverter.toProperties(partitionConfig), partitionProperties);
Assert.assertEquals(PartitionPropertiesConverter.toConfig(partitionProperties), partitionConfig);
}
Aggregations