-
Notifications
You must be signed in to change notification settings - Fork 317
Description
First of all, thanks for the great library!
I'm looking into using the tower::balance::p2c load balancer with weighted services. This is primarily to allow for a use case of canary deployments, where one service that the load balancer serves should receive (a configurable amount of) less traffic than the other services.
This particular use case of a single, less weighted, service mostly works through implementing a weight tower::Load implementation that can scale down a particular service's load. I've put up an initial attempt of doing this in this PR which is heavily inspired by the implementation that used to exist in tower.
However, because of the way p2c balancing works, this implementation can have unexpected results in the general case.
For example, if there are 3 services: [A, B, C] with weights [0.99, 0.005, 0.005] then a user would likely expect that (assuming everything else is equal):
- Service A would serve 99%
- Service B would serve 0.5%
- Service C would serve 0.5%
What will actually occur with a p2c load balancer, because of the "randomly pick any two" heuristic, is that:
- Service A will serve ~66% of requests
- Service B would serve ~16%
- Service C would serve ~16%
This is because the permutations AB, AC, BC are all equally likely - so BC will account for a third of requests.
The only nice way around this that I can think of is to also allow the p2c load balancer's random picking to be weighted, probably by using weighted random sampling.
The way this could work is that each service would implement weight, which would be used in the weighted random sampling and in the load comparisons. Note that it's still not enough to just do weighted random sampling because the load balancer will equally load the pairs of services it picks.
Anyway, I thought it'd be worth checking in with the community to see what would be a desired path forward before I start working on any implementation. Curious to hear other's thoughts, or if there's a more elegant solution that I'm missing.
I also see that there was a little bit of talk about this topic back in 2019: #286 (comment) maybe @olix0r has some thoughts here as well. 😄