Skip to content
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

Make heavy loaded optimization configurable #2 #211

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

dkropachev
Copy link
Collaborator

@dkropachev dkropachev commented Jul 6, 2024

It is updated #114
Due to the #114 being stuck with no progress

Comment on lines -424 to +426
return c.streams.NumStreams/2 > c.AvailableStreams()
return c.StreamsInUse() > c.session.cfg.HeavyLoadedConnectionThreshold

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This part was already configurable trough MaxRequestsPerConn parameter in ClusterConfig.
I think we should either stick with the old parameter or remove it. Having 2 will be confusing.
Also, currently this PR changes the default (previously it was 32768 / 2, now it is 512). Why this number and why should the default be changed?

Copy link
Collaborator Author

@dkropachev dkropachev Aug 1, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Having it in an old way do not allow user to switch early and to have lot's of requests in flight at the same time.
MaxRequestsPerConn used to control not only max number of requests in flight, but also a waterline after which connection is considered under high load.
This kind of coupling is never good.
Beside that, before this PR driver considered connection to be highly loaded only after reaching 16k requests in flight, which is a HUGE number, it is safe to say that this feature never worked before.

Having a separate configuration for a heavy loaded water line allows user to allow driver to have big number of in flight requests and at the same time to switch to underutilized connections early.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Having it in an old way do not allow user to switch early and to have lot's of requests in flight at the same time. MaxRequestsPerConn used to control not only max number of requests in flight, but also a waterline after which connection is considered under high load. This kind of coupling is never good.
Beside that, before this PR driver considered connection to be highly loaded only after reaching 16k requests in flight, which is a HUGE number, it is safe to say that this feature never worked before.

This number was configurable by the user, so its not really safe to say this.

Having a separate configuration for a heavy loaded water line allows user to allow driver to have big number of in flight requests and at the same time to switch to underutilized connections early.

If switching out early is the goal (which also means disabling shard awareness early!!) then I agree that HeavyLoadedConnectionThreshold makes sense.

scylla.go Outdated
if alternative == nil || alternative.AvailableStreams()*120 > c.AvailableStreams()*100 {
return c
} else {
if alternative != nil && alternative.StreamsInUse()*100 >= c.StreamsInUse()*(100-c.session.cfg.HeavyLoadedSwitchConnectionPercentage) {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shouldn't it be <?
Right now you are returning the alternative if it's more loaded than the original connection, not less

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It would be good to have some test to verify that the inequality is correct.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

both done, added tests and fixed the code

@sylwiaszunejko
Copy link
Collaborator

@dkropachev Do you plan to continue work on this PR?

@dkropachev
Copy link
Collaborator Author

@dkropachev Do you plan to continue work on this PR?

Sure, I am going to work on it this week.

@dkropachev
Copy link
Collaborator Author

@sylwiaszunejko , @Lorak-mmk , it is done, please take a look

sylwiaszunejko
sylwiaszunejko previously approved these changes Aug 26, 2024
Copy link
Collaborator

@sylwiaszunejko sylwiaszunejko left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For me it looks good, but maybe @Lorak-mmk has any comments?

@Lorak-mmk
Copy link

I'll try to respond here soon, after reviewing scylladb/scylla-rust-driver#1061 and scylladb/scylla-rust-driver#1065

cluster.go Outdated
Comment on lines 370 to 380
if len(cfg.Hosts) == 0 {
return ErrNoHosts
}

if cfg.Authenticator != nil && cfg.AuthProvider != nil {
return errors.New("Can't use both Authenticator and AuthProvider in cluster config.")
}

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't see how this change is related to this commit / PR.
Please put it in separate commit at least.

cluster.go Outdated
Comment on lines 378 to 407
if cfg.HeavyLoadedSwitchConnectionPercentage > 100 || cfg.HeavyLoadedSwitchConnectionPercentage < 0 {
return fmt.Errorf("HeavyLoadedSwitchConnectionPercentage must be between 0 and 100, got %d", cfg.HeavyLoadedSwitchConnectionPercentage)
}

if cfg.HeavyLoadedConnectionThreshold < 0 {
return fmt.Errorf("HeavyLoadedConnectionThreshold must be greater than or equal to 0, got %d", cfg.HeavyLoadedConnectionThreshold)
}

return nil
}

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You should also validate that MaxRequestsPerConn >= HeavyLoadedConnectionThreshold to prevent weird configurations

Comment on lines -424 to +426
return c.streams.NumStreams/2 > c.AvailableStreams()
return c.StreamsInUse() > c.session.cfg.HeavyLoadedConnectionThreshold

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Having it in an old way do not allow user to switch early and to have lot's of requests in flight at the same time. MaxRequestsPerConn used to control not only max number of requests in flight, but also a waterline after which connection is considered under high load. This kind of coupling is never good.
Beside that, before this PR driver considered connection to be highly loaded only after reaching 16k requests in flight, which is a HUGE number, it is safe to say that this feature never worked before.

This number was configurable by the user, so its not really safe to say this.

Having a separate configuration for a heavy loaded water line allows user to allow driver to have big number of in flight requests and at the same time to switch to underutilized connections early.

If switching out early is the goal (which also means disabling shard awareness early!!) then I agree that HeavyLoadedConnectionThreshold makes sense.

Scylla Go Driver has a capability to avoid sending requests to an
overloaded shard, instead sending the request on a different connection
(at the same node).

This change makes it possible to customize the parameters used to
determine when this behavior would kick in.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants