-
Notifications
You must be signed in to change notification settings - Fork 3.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
xds: add weighted round robin LB policy support #9873
Conversation
1. to merge orca api remove listener 2. to merge metric report api rqs 3. to settle the package
RoundRobinLB picker issue, e.g. size = 5, index = 4 pick1: i = index = 5 pick2: i = index = 6 pick1 : oldi = 5, i = 0, index = 0 pick2: oldi = 6, i = 1, index not updated = 0. pick1 return subchanel[0], pick2 return subchannel[1] next time, it still return subchannel[1], it gets picked more often;
xds/src/main/java/io/grpc/xds/WeightedRoundRobinLoadBalancer.java
Outdated
Show resolved
Hide resolved
xds/src/main/java/io/grpc/xds/WeightedRoundRobinLoadBalancer.java
Outdated
Show resolved
Hide resolved
double newWeight = subchannel.getWeight(); | ||
scheduler.add(i, newWeight > 0 ? newWeight : avgWeight); | ||
} | ||
schedulerRef.set(scheduler); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Because you are completely replacing the scheduler each time you update weights, if something has a large weight and something else has a minimum weight the second one might never get used.
One way of dealing with this would be for ObjectState to have a flag indicating whether this was added from a pick, then for all of the ones that weren't added from a pick you could use the old deadline (or the smaller of the old deadline and the newly calculated one). You could have the flag passed to scheduler.add() and all of the work done in the add method.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Absolutely true.
Note stubby has similar "completion ratio" mechanism, that gives credits to subchannels in the previous state when updating to the next state with the new weight. This way, the minimum weight channel can possibly be picked.
The current implementation is very simplified. I'll make it as a future improvement and I will capture it in the design doc.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Because you are completely replacing the scheduler each time you update weights, if something has a large weight and something else has a minimum weight the second one might never get used.
Randomizing the scheduler each creation should prevent that. Worst-case, if a schedule is used for only a single pick after being created, then that is the same as a WRR implementation that has weighted ranges for each choice and uses a random number to choose (same approach as weighted_target).
The code right now does not seem to randomize the initial scheduler state, but it will need to before de-experimentalizing.
xds/src/test/java/io/grpc/xds/WeightedRoundRobinLoadBalancerTest.java
Outdated
Show resolved
Hide resolved
xds/src/test/java/io/grpc/xds/WeightedRoundRobinLoadBalancerTest.java
Outdated
Show resolved
Hide resolved
Can you rebase this on master because #9875 is merged? I would have looked at just the commits after that other PR, but there were so many; in the future you could squash commits that were just used during development before creating the PR. |
xds/src/main/java/io/grpc/xds/WeightedRoundRobinLoadBalancer.java
Outdated
Show resolved
Hide resolved
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Still haven't found enough time to get through it all :-/. Sending what I have.
xds/src/main/java/io/grpc/xds/WeightedRoundRobinLoadBalancerProvider.java
Show resolved
Hide resolved
xds/src/main/java/io/grpc/xds/WeightedRoundRobinLoadBalancer.java
Outdated
Show resolved
Hide resolved
xds/src/main/java/io/grpc/xds/WeightedRoundRobinLoadBalancer.java
Outdated
Show resolved
Hide resolved
xds/src/main/java/io/grpc/xds/WeightedRoundRobinLoadBalancer.java
Outdated
Show resolved
Hide resolved
xds/src/main/java/io/grpc/xds/WeightedRoundRobinLoadBalancerProvider.java
Outdated
Show resolved
Hide resolved
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Happened to go a bit further, but this is still incomplete. All of these comments are minor.
} | ||
|
||
WeightedRoundRobinLoadBalancerConfig build() { | ||
return new WeightedRoundRobinLoadBalancerConfig(blackoutPeriodNanos, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
FYI: passing this
to the Config constructor is convenient, and Config will have access to the fields even if they are private. (no need to change though)
xds/src/main/java/io/grpc/xds/WeightedRoundRobinLoadBalancer.java
Outdated
Show resolved
Hide resolved
xds/src/main/java/io/grpc/xds/WeightedRoundRobinLoadBalancer.java
Outdated
Show resolved
Hide resolved
xds/src/main/java/io/grpc/xds/WeightedRoundRobinLoadBalancer.java
Outdated
Show resolved
Hide resolved
xds/src/main/java/io/grpc/xds/WeightedRoundRobinLoadBalancer.java
Outdated
Show resolved
Hide resolved
xds/src/main/java/io/grpc/xds/WeightedRoundRobinLoadBalancer.java
Outdated
Show resolved
Hide resolved
xds/src/main/java/io/grpc/xds/WeightedRoundRobinLoadBalancer.java
Outdated
Show resolved
Hide resolved
xds/src/main/java/io/grpc/xds/WeightedRoundRobinLoadBalancer.java
Outdated
Show resolved
Hide resolved
xds/src/main/java/io/grpc/xds/WeightedRoundRobinLoadBalancer.java
Outdated
Show resolved
Hide resolved
xds/src/main/java/io/grpc/xds/WeightedRoundRobinLoadBalancer.java
Outdated
Show resolved
Hide resolved
private volatile long lastUpdated; | ||
private volatile long nonEmptySince; | ||
private volatile double weight; | ||
private volatile WeightedRoundRobinLoadBalancerConfig config; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why is this volatile
? It appears to only be accessed in the synchronization context.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
oh it appears so.
It can be used by pick() from SubchannelStateListener
from transport thread, or here in the LB thread in weightUpdateTask or acceptResolvedAddresses, all in sync context.
xds/src/main/java/io/grpc/xds/WeightedRoundRobinLoadBalancer.java
Outdated
Show resolved
Hide resolved
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There's two non-FYI remaining comments from the previous part of the review that I'd like to see done. They are related; passing config.enableOobLoadReport
to the picker's constructor would allow making config non-volatile.
After those two previous comments and the comments requiring change in this review, things look good. I didn't look at tests, but Larry did previously.
implementation design doc: go/grpc-java-wrr