xds: equally weight endpoints within locality if endpoint-level weight unspecified (#8245)

Use a multiplier of 1 for endpoints with endpoint-level load balancing weight unspecified when computing weights for mixing-locality load balancing. Therefore, if a locality has endpoints without endpoint-level load balancing weight, they are weighted equally within the locality.
This commit is contained in:
Chengyuan Zhang 2021-06-09 12:04:17 -07:00 committed by GitHub
parent b7f3fddc76
commit d41094944c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 29 additions and 14 deletions

View File

@ -387,13 +387,17 @@ final class ClusterResolverLoadBalancer extends LoadBalancer {
for (LbEndpoint endpoint : localityLbInfo.endpoints()) {
if (endpoint.isHealthy()) {
discard = false;
long weight =
(long) localityLbInfo.localityWeight() * endpoint.loadBalancingWeight();
Attributes attr = endpoint.eag().getAttributes().toBuilder()
.set(InternalXdsAttributes.ATTR_LOCALITY, locality)
.set(InternalXdsAttributes.ATTR_SERVER_WEIGHT, weight).build();
EquivalentAddressGroup eag =
new EquivalentAddressGroup(endpoint.eag().getAddresses(), attr);
long weight = localityLbInfo.localityWeight();
if (endpoint.loadBalancingWeight() != 0) {
weight *= endpoint.loadBalancingWeight();
}
Attributes attr =
endpoint.eag().getAttributes().toBuilder()
.set(InternalXdsAttributes.ATTR_LOCALITY, locality)
.set(InternalXdsAttributes.ATTR_SERVER_WEIGHT, weight)
.build();
EquivalentAddressGroup eag = new EquivalentAddressGroup(
endpoint.eag().getAddresses(), attr);
eag = AddressFilter.setPathFilter(
eag, Arrays.asList(priorityName, localityName(locality)));
addresses.add(eag);

View File

@ -16,6 +16,8 @@
package io.grpc.xds;
import static com.google.common.base.Preconditions.checkArgument;
import com.google.auto.value.AutoValue;
import com.google.common.annotations.VisibleForTesting;
import com.google.common.collect.ImmutableList;
@ -33,7 +35,7 @@ final class Endpoints {
// Endpoints to be load balanced.
abstract ImmutableList<LbEndpoint> endpoints();
// Locality's weight for inter-locality load balancing.
// Locality's weight for inter-locality load balancing. Guaranteed to be greater than 0.
abstract int localityWeight();
// Locality's priority level.
@ -41,6 +43,7 @@ final class Endpoints {
static LocalityLbEndpoints create(List<LbEndpoint> endpoints, int localityWeight,
int priority) {
checkArgument(localityWeight > 0, "localityWeight must be greater than 0");
return new AutoValue_Endpoints_LocalityLbEndpoints(
ImmutableList.copyOf(endpoints), localityWeight, priority);
}
@ -52,7 +55,7 @@ final class Endpoints {
// The endpoint address to be connected to.
abstract EquivalentAddressGroup eag();
// Endpoint's wight for load balancing.
// Endpoint's weight for load balancing. If unspecified, value of 0 is returned.
abstract int loadBalancingWeight();
// Whether the endpoint is healthy.

View File

@ -217,29 +217,37 @@ public class ClusterResolverLoadBalancerTest {
// One priority with two localities of different weights.
EquivalentAddressGroup endpoint1 = makeAddress("endpoint-addr-1");
EquivalentAddressGroup endpoint2 = makeAddress("endpoint-addr-2");
EquivalentAddressGroup endpoint3 = makeAddress("endpoint-addr-3");
LocalityLbEndpoints localityLbEndpoints1 =
LocalityLbEndpoints.create(
Collections.singletonList(
LbEndpoint.create(endpoint1, 100 /* loadBalancingWeight */, true)),
Arrays.asList(
LbEndpoint.create(endpoint1, 0 /* loadBalancingWeight */, true),
LbEndpoint.create(endpoint2, 0 /* loadBalancingWeight */, true)),
10 /* localityWeight */, 1 /* priority */);
LocalityLbEndpoints localityLbEndpoints2 =
LocalityLbEndpoints.create(
Collections.singletonList(
LbEndpoint.create(endpoint2, 60 /* loadBalancingWeight */, true)),
LbEndpoint.create(endpoint3, 60 /* loadBalancingWeight */, true)),
50 /* localityWeight */, 1 /* priority */);
xdsClient.deliverClusterLoadAssignment(
EDS_SERVICE_NAME1,
ImmutableMap.of(locality1, localityLbEndpoints1, locality2, localityLbEndpoints2));
assertThat(childBalancers).hasSize(1);
FakeLoadBalancer childBalancer = Iterables.getOnlyElement(childBalancers);
assertThat(childBalancer.addresses).hasSize(2);
assertThat(childBalancer.addresses).hasSize(3);
EquivalentAddressGroup addr1 = childBalancer.addresses.get(0);
EquivalentAddressGroup addr2 = childBalancer.addresses.get(1);
EquivalentAddressGroup addr3 = childBalancer.addresses.get(2);
// Endpoints in locality1 have no endpoint-level weight specified, so all endpoints within
// locality1 are equally weighted.
assertThat(addr1.getAddresses()).isEqualTo(endpoint1.getAddresses());
assertThat(addr1.getAttributes().get(InternalXdsAttributes.ATTR_SERVER_WEIGHT))
.isEqualTo(10 * 100);
.isEqualTo(10);
assertThat(addr2.getAddresses()).isEqualTo(endpoint2.getAddresses());
assertThat(addr2.getAttributes().get(InternalXdsAttributes.ATTR_SERVER_WEIGHT))
.isEqualTo(10);
assertThat(addr3.getAddresses()).isEqualTo(endpoint3.getAddresses());
assertThat(addr3.getAttributes().get(InternalXdsAttributes.ATTR_SERVER_WEIGHT))
.isEqualTo(50 * 60);
assertThat(childBalancer.name).isEqualTo(PRIORITY_POLICY_NAME);
PriorityLbConfig priorityLbConfig = (PriorityLbConfig) childBalancer.config;