Skip to content

Commit

Permalink
xds: reimplement EDS LB policy with downstream LB config generations …
Browse files Browse the repository at this point in the history
…that migrate to hierarchical LB tree codepath (#7391)

Implemented the new EDS LB policy, which generates a LB config for instantiating a hierarchical load balancing subtree. The subtree includes downstream LB policies: 

- priority LB policy, which load balances individual priorities separately
- weighted-target LB policy, which load balances individual localities within the same priority separately
- lrs LB policy, which applies load recording that aggregates load stats for each locality
- leaf LB policy (round_robin)

The EDS LB policy is the place that receives endpoint information from traffic director and organizes the data into a model for hierarchical load balancing for the cluster.
  • Loading branch information
voidzcy committed Sep 18, 2020
1 parent b571f23 commit e6b61ea
Show file tree
Hide file tree
Showing 8 changed files with 1,376 additions and 86 deletions.
434 changes: 434 additions & 0 deletions xds/src/main/java/io/grpc/xds/EdsLoadBalancer2.java

Large diffs are not rendered by default.

66 changes: 23 additions & 43 deletions xds/src/main/java/io/grpc/xds/EdsLoadBalancerProvider.java
Expand Up @@ -17,23 +17,17 @@
package io.grpc.xds;

import static com.google.common.base.Preconditions.checkNotNull;
import static io.grpc.xds.XdsLbPolicies.WEIGHTED_TARGET_POLICY_NAME;

import com.google.common.base.MoreObjects;
import com.google.common.base.Objects;
import com.google.common.collect.ImmutableMap;
import io.grpc.Internal;
import io.grpc.LoadBalancer;
import io.grpc.LoadBalancer.Helper;
import io.grpc.LoadBalancerProvider;
import io.grpc.LoadBalancerRegistry;
import io.grpc.NameResolver.ConfigOrError;
import io.grpc.Status;
import io.grpc.internal.JsonUtil;
import io.grpc.internal.ServiceConfigUtil;
import io.grpc.internal.ServiceConfigUtil.LbConfig;
import io.grpc.internal.ServiceConfigUtil.PolicySelection;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import javax.annotation.Nullable;

Expand Down Expand Up @@ -68,60 +62,43 @@ public LoadBalancer newLoadBalancer(Helper helper) {
@Override
public ConfigOrError parseLoadBalancingPolicyConfig(
Map<String, ?> rawLoadBalancingPolicyConfig) {
LoadBalancerRegistry registry = LoadBalancerRegistry.getDefaultRegistry();
try {
String cluster = JsonUtil.getString(rawLoadBalancingPolicyConfig, "cluster");
if (cluster == null) {
return ConfigOrError.fromError(Status.INTERNAL.withDescription("Cluster name required"));
}
String edsServiceName = JsonUtil.getString(rawLoadBalancingPolicyConfig, "edsServiceName");
String lrsServerName =
JsonUtil.getString(rawLoadBalancingPolicyConfig, "lrsLoadReportingServerName");

// TODO(chengyuanzhang): figure out locality_picking_policy parsing and its default value.

LbConfig roundRobinConfig = new LbConfig("round_robin", ImmutableMap.<String, Object>of());
List<LbConfig> endpointPickingPolicy =
ServiceConfigUtil
.unwrapLoadBalancingConfigList(
JsonUtil.getListOfObjects(
rawLoadBalancingPolicyConfig, "endpointPickingPolicy"));
if (endpointPickingPolicy == null || endpointPickingPolicy.isEmpty()) {
endpointPickingPolicy = Collections.singletonList(roundRobinConfig);
}
ConfigOrError endpointPickingConfigOrError =
ServiceConfigUtil.selectLbPolicyFromList(endpointPickingPolicy, registry);
if (endpointPickingConfigOrError.getError() != null) {
return endpointPickingConfigOrError;
}
PolicySelection endpointPickingSelection =
(PolicySelection) endpointPickingConfigOrError.getConfig();
return ConfigOrError.fromConfig(
new EdsConfig(cluster, edsServiceName, lrsServerName, endpointPickingSelection));
} catch (RuntimeException e) {
return ConfigOrError.fromError(
Status.fromThrowable(e).withDescription(
"Failed to parse EDS LB config: " + rawLoadBalancingPolicyConfig));
}
throw new UnsupportedOperationException("not supported as top-level LB policy");
}

static final class EdsConfig {

final String clusterName;
@Nullable
final String edsServiceName;
@Nullable
final String lrsServerName;
final PolicySelection localityPickingPolicy;
final PolicySelection endpointPickingPolicy;

// TODO(chengyuanzhang): delete me.
EdsConfig(
String clusterName,
@Nullable String edsServiceName,
@Nullable String lrsServerName,
PolicySelection endpointPickingPolicy) {
this.clusterName = checkNotNull(clusterName, "clusterName");
this.edsServiceName = edsServiceName;
this.lrsServerName = lrsServerName;
this.endpointPickingPolicy = checkNotNull(endpointPickingPolicy, "endpointPickingPolicy");
LoadBalancerProvider provider =
LoadBalancerRegistry.getDefaultRegistry().getProvider(WEIGHTED_TARGET_POLICY_NAME);
localityPickingPolicy = new PolicySelection(provider, null, null);
}

EdsConfig(
String clusterName,
@Nullable String edsServiceName,
@Nullable String lrsServerName,
PolicySelection localityPickingPolicy,
PolicySelection endpointPickingPolicy) {
this.clusterName = checkNotNull(clusterName, "clusterName");
this.edsServiceName = edsServiceName;
this.lrsServerName = lrsServerName;
this.localityPickingPolicy = checkNotNull(localityPickingPolicy, "localityPickingPolicy");
this.endpointPickingPolicy = checkNotNull(endpointPickingPolicy, "endpointPickingPolicy");
}

Expand All @@ -131,6 +108,7 @@ public String toString() {
.add("clusterName", clusterName)
.add("edsServiceName", edsServiceName)
.add("lrsServerName", lrsServerName)
.add("localityPickingPolicy", localityPickingPolicy)
.add("endpointPickingPolicy", endpointPickingPolicy)
.toString();
}
Expand All @@ -144,6 +122,7 @@ public boolean equals(Object obj) {
return Objects.equal(this.clusterName, that.clusterName)
&& Objects.equal(this.edsServiceName, that.edsServiceName)
&& Objects.equal(this.lrsServerName, that.lrsServerName)
&& Objects.equal(this.localityPickingPolicy, that.localityPickingPolicy)
&& Objects.equal(this.endpointPickingPolicy, that.endpointPickingPolicy);
}

Expand All @@ -154,6 +133,7 @@ public int hashCode() {
clusterName,
edsServiceName,
lrsServerName,
localityPickingPolicy,
endpointPickingPolicy);
}
}
Expand Down
Expand Up @@ -20,6 +20,7 @@
import static com.google.common.base.Preconditions.checkNotNull;

import com.google.common.base.MoreObjects;
import io.grpc.Internal;
import io.grpc.LoadBalancer;
import io.grpc.LoadBalancer.Helper;
import io.grpc.LoadBalancerProvider;
Expand All @@ -31,7 +32,8 @@
import java.util.Map;

/** Provider for priority load balancing policy. */
final class PriorityLoadBalancerProvider extends LoadBalancerProvider {
@Internal
public final class PriorityLoadBalancerProvider extends LoadBalancerProvider {

@Override
public boolean isAvailable() {
Expand Down
Expand Up @@ -127,7 +127,6 @@ static final class WeightedPolicySelection {
final int weight;
final PolicySelection policySelection;

@VisibleForTesting
WeightedPolicySelection(int weight, PolicySelection policySelection) {
this.weight = weight;
this.policySelection = policySelection;
Expand Down
3 changes: 3 additions & 0 deletions xds/src/main/java/io/grpc/xds/XdsLbPolicies.java
Expand Up @@ -20,7 +20,10 @@ final class XdsLbPolicies {
static final String CLUSTER_MANAGER_POLICY_NAME = "cluster_manager_experimental";
static final String CDS_POLICY_NAME = "cds_experimental";
static final String EDS_POLICY_NAME = "eds_experimental";
static final String PRIORITY_POLICY_NAME = "priority_experimental";
static final String WEIGHTED_TARGET_POLICY_NAME = "weighted_target_experimental";
static final String LRS_POLICY_NAME = "lrs_experimental";
// TODO(chengyuanzhang): delete routing policy.
static final String XDS_ROUTING_POLICY_NAME = "xds_routing_experimental";

private XdsLbPolicies() {}
Expand Down
@@ -1,5 +1,7 @@
io.grpc.xds.CdsLoadBalancerProvider
io.grpc.xds.EdsLoadBalancerProvider
io.grpc.xds.PriorityLoadBalancerProvider
io.grpc.xds.WeightedTargetLoadBalancerProvider
io.grpc.xds.LrsLoadBalancerProvider
io.grpc.xds.XdsRoutingLoadBalancerProvider
io.grpc.xds.ClusterManagerLoadBalancerProvider

0 comments on commit e6b61ea

Please sign in to comment.