Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Implement zone aware load balancing for
XdsEndpointGroup
(#5808)
Motivation: This changeset attempts to implement envoy's [zone aware routing](https://www.envoyproxy.io/docs/envoy/latest/intro/arch_overview/upstream/load_balancing/zone_aware). A small sample on how this can be configured can be seen [here](https://www.envoyproxy.io/docs/envoy/latest/faq/configuration/zone_aware_routing) as well. The basic algorithm in layman's terms is the following: 1) A client supplies a locality and a local cluster. The corresponding cluster should also be added. 2) The percentage of hosts for each locality is computed for both upstream and local clusters. 3) The percentage is compared and a new "weight" is computed to determine which locality to route to when selecting an endpoint. The code has been mostly adapted from envoy's implementation: - Computing the locality routing state - https://github.com/envoyproxy/envoy/blob/ae1811aaf8736e2a4ca9fc0d045f6696f58e45e2/source/extensions/load_balancing_policies/common/load_balancer_impl.cc#L450-L542 - Routing the locality for each request - https://github.com/envoyproxy/envoy/blob/ae1811aaf8736e2a4ca9fc0d045f6696f58e45e2/source/extensions/load_balancing_policies/common/load_balancer_impl.cc#L772-L816 Modifications: - (Breaking) Previously we had been accepting a `ListenerRoot` when creating an `XdsEndpointGroup`. However, we need more information like local locality from the bootstrap. To make this intention clear, `XdsEndpointGroup` now accepts an `XdsBootstrap`. Additionally, `XdsBootstrap#bootstrap` has been added to access the local cluster name and locality. - `ClusterManager` now maintains a `LocalCluster` data structure which watches changes in the local cluster if exists. When a `ClusterEntry` is created, the existing `LocalCluster` is passed. - The upstream `ClusterEntry` needs to listen to the local `ClusterEntry` for updates in order to pre-compute the state. `ClusterEntry` is now an `AbstractListenable` and notifies the current `LoadBalancer`. - Following this change, the `PrioritySet` is required to compute the locality state. Added a `LoadBalancer#prioritySet` method to retrieve the current `PrioritySet`. - `XdsLoadBalancer` has been added as an extra abstraction layer to avoid conflicts with #5779 - `ClusterEntry` now has two update points: 1) when the endpoints are updated 2) when the local cluster is updated. Now, the two entry points call a single `tryRefresh` to refresh the load balancer. - Added `LocalityRoutingStateFactory` and modified `DefaultLoadBalancer` to support zone aware routing. The implementation should look very similar to envoy's source. - Testing was difficult due to multiple locations where random was used. To make the tests deterministic, I've added a `XdsRandom` interface for easier testing. Additionally, to guarantee that the local cluster was fully loaded before proceeding with tests, `ClusterEntry#initialLocalEntryStateFuture` has been added. - In order to access `XdsEndpointGroup#clusterEntries`, the factory methods for `XdsEndpointGroup` now return the concrete type. Result: - `XdsEndpointGroup` now supports zone-aware load balancing.
- Loading branch information