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

Add rotate option for recursors #8882

Closed
wants to merge 2 commits into from
Closed

Add rotate option for recursors #8882

wants to merge 2 commits into from

Conversation

munali
Copy link
Contributor

@munali munali commented Oct 8, 2020

Closes #8807

@jsosulska jsosulska added the theme/dns Using Consul as a DNS provider, DNS related issues label Oct 8, 2020
Copy link
Contributor

@dnephin dnephin left a comment

Choose a reason for hiding this comment

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

Thank you for the PR! I think this is a good idea, and I have a suggestion for the implementation.

agent/dns.go Outdated
Comment on lines 1822 to 1826
var start = int(cfg.Recursors.RoundRobinIndex)
if cfg.RecursorRotate {
cfg.Recursors.RoundRobinIndex += 1
}
for _, recursor := range append(cfg.Recursors.Addrs[start:], cfg.Recursors.Addrs[:start]...) {
Copy link
Contributor

Choose a reason for hiding this comment

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

I think there may be a problems here. cfg.Recursors.RoundRobinIndex does not appear to be reset to 0 when it reaches the end of the list. I think this will panic after a few requests.

I believe cfg.Recursors.RoundRobinIndex += 1 is not safe for concurrent use either, so this could return incorrect results when there are multiple handlers running at the same time in different goroutines.

Instead of round robin, would random selection be ok? Something like this would remove the need to track the Index, and I think should also be safe for concurrent use because we only read concurrently, and the recursors list does not change.

for _, idx := range rand.Perm(len(cfg.Recursors)) {
    recursor := cfg.Recursors[idx]
}

Copy link
Contributor Author

@munali munali Oct 10, 2020

Choose a reason for hiding this comment

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

@dnephin Doh! I forgot to modulo.

I am sure this is not safe for concurrent use either, but I believe something like this could work as well? What do you think.

cfg.Recursors.RoundRobinIndex = (atomic.AddInt32(cfg.Recursors.RoundRobinIndex, 1)%len(cfg.Recursors))

Either way, I like your suggestion because it does a good job of distributing the load. Whereas my attempt adds complexity to increment the index and store it as an extra variable.

Would something like this be good/safe golang style?

for idx, random_idx := range rand.Perm(len(cfg.Recursors)) {
    recursor := cfg.Recursors[idx]
    if cfg. RecursorRotate {
       recursor = cfg.Recursors[random_idx]
   }
}

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@dnephin any thoughts on the changes?

@munali
Copy link
Contributor Author

munali commented Oct 14, 2020

Hi @dnephin I am not sure if you so my comment above or my recent push. Does that seem reasonable? Thank you for your help! Much appreciated.

@kyhavlov
Copy link
Contributor

Hi @munali, sorry for the lack of attention on this PR after so long - how would you feel about changing the config field to something like dns_recursor_strategy or similar and having the valid options be default/randomize, instead of a boolean? I think the approach taken with rand.Perm() makes sense, just a thought about the wording of the config field.

@jsosulska jsosulska added type/enhancement Proposed improvement or new feature waiting-reply Waiting on response from Original Poster or another individual in the thread labels Mar 11, 2021
@blake
Copy link
Contributor

blake commented Jul 19, 2021

Hi @munali, we never heard back from you, but we were interested in adding this feature to Consul so I added this in #10611, and gave you credit as one of the authors. I hope you don't mind.

Thank you for your contribution.

@blake blake closed this Jul 19, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
theme/dns Using Consul as a DNS provider, DNS related issues type/enhancement Proposed improvement or new feature waiting-reply Waiting on response from Original Poster or another individual in the thread
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Add option to round robin the queries to upstream DNS servers
5 participants