8000 dnsdist: add route policy of first ordered then weighted by pacnal · Pull Request #15670 · PowerDNS/pdns · GitHub
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content

dnsdist: add route policy of first ordered then weighted #15670

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

Merged
merged 4 commits into from
Jun 17, 2025

Conversation

pacnal
Copy link
Contributor
@pacnal pacnal commented Jun 13, 2025

Short description

User may require two levels of routing policy to select downstream servers. First choose the least ordered, then distribute queries according to weights among the same ordered servers. It also added special filtering on selecting servers for query restart. If user sets the required tag in the restarted query then the policy will not select server(s) that had been tried before.

Checklist

I have:

  • read the CONTRIBUTING.md document
  • compiled this code
  • tested this code
  • included documentation (including possible behaviour changes)
  • documented the code
  • added or modified regression test(s)
  • added or modified unit test(s)

User may require two levels of routing policy to select downstream
servers. First choose the least ordered, then distribute queries
according to weights among the same ordered servers. It also added
special filtering on selecting servers for query restart. If user
sets the required tag in the restarted query then the policy will
not select server(s) that had been tried before.
@rgacogne rgacogne self-requested a review June 13, 2025 11:31
@rgacogne rgacogne added this to the dnsdist-2.0.0 milestone Jun 13, 2025
@coveralls
Copy link
coveralls commented Jun 13, 2025

Pull Request Test Coverage Report for Build 15697060781

Warning: This coverage report may be inaccurate.

This pull request's base commit is no longer the HEAD commit of its target branch. This means it includes changes from outside the original pull request, including, potentially, unrelated coverage changes.

Details

  • 19 of 23 (82.61%) changed or added relevant lines in 1 file are covered.
  • 385 unchanged lines in 15 files lost coverage.
  • Overall coverage increased (+0.03%) to 65.547%

Changes Missing Coverage Covered Lines Changed/Added Lines %
pdns/dnsdistdist/dnsdist-lbpolicies.cc 19 23 82.61%
Files with Coverage Reduction New Missed Lines %
modules/gpgsqlbackend/gpgsqlbackend.cc 1 88.8%
modules/pipebackend/pipebackend.cc 2 61.16%
pdns/recursordist/sortlist.cc 2 72.94%
pdns/sstuff.hh 2 57.14%
pdns/dnsdistdist/dnsdist-carbon.cc 3 62.6%
pdns/iputils.hh 3 78.58%
pdns/opensslsigners.cc 3 61.2%
pdns/packethandler.cc 3 73.52%
pdns/rcpgenerator.cc 3 91.24%
pdns/stubresolver.cc 3 77.02%
Totals Coverage Status
Change from base Build 15632943391: 0.03%
Covered Lines: 125723
Relevant Lines: 163397

💛 - Coveralls

if (svr.second->isUp() && svr.second->d_config.order <= curOrder && (!dnsq->ids.qTag || dnsq->ids.qTag->count(svr.second->getNameWithAddr()) == 0)) {
if (svr.second->d_config.order < curOrder) {
curOrder = svr.second->d_config.order;
startIndex = candidates.end() - candidates.begin();
Copy link
Contributor

Choose a reason for hiding this comment

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

Wouldn't that be

Suggested change
startIndex = candidates.end() - candidates.begin();
startIndex = candidates.size();

@@ -2079,7 +2079,7 @@ load_balancing_policies:
lua-name: "setWeightedBalancingFactor"
internal-field-name: "d_weightedBalancingFactor"
runtime-configurable: false
description: "Set the maximum imbalance between the number of outstanding queries intended for a given server, based on its weight, and the actual number, when using the ``whashed`` or ``wrandom`` load-balancing policy. Default is 0, which disables the bounded-load algorithm"
description: "Set the maximum imbalance between the number of outstanding queries intended for a given server, based on its weight, and the actual number, when using the ``whashed`` or ``wrandom`` or ``orderedWrandUntag`` load-balancing policy. Default is 0, which disables the bounded-load algorithm"
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
description: "Set the maximum imbalance between the number of outstanding queries intended for a given server, based on its weight, and the actual number, when using the ``whashed`` or ``wrandom`` or ``orderedWrandUntag`` load-balancing policy. Default is 0, which disables the bounded-load algorithm"
description: "Set the maximum imbalance between the number of outstanding queries intended for a given server, based on its weight, and the actual number, when using the ``whashed``, ``wrandom`` or ``orderedWrandUntag`` load-balancing policy. Default is 0, which disables the bounded-load algorithm"

``orderedWrandUntag`` is another weighted policy with additional server filtering:

- select the group of server(s) with the lowest ``order`` passed to :func:`newServer`.
- filter out server(s) that were tagged with key string of :func:`Server:getNameWithAddr` in the query that was set by :func:`DNSQuestion:setTag`. This can be useful to restart a query with a different server, the user is responsible to set the required tag in lua action before calling :func:`DNSResponse:restart`. Initial queries are not impacted by this filtering if no other intentional lua action to set the tag.
Copy link
Contributor

Choose a reason for hiding this comment

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

I suppose you mean

Suggested change
- filter out server(s) that were tagged with key string of :func:`Server:getNameWithAddr` in the query that was set by :func:`DNSQuestion:setTag`. This can be useful to restart a query with a different server, the user is responsible to set the required tag in lua action before calling :func:`DNSResponse:restart`. Initial queries are not impacted by this filtering if no other intentional lua action to set the tag.
- filter out server(s) that were tagged with key string of :func:`Server:getNameWithAddr` in the query that was set by :func:`DNSQuestion:setTag`. This can be useful to restart a query with a different server, the user is responsible to set the required tag in lua action before calling :func:`DNSResponse:restart`. Initial queries are not impacted by this filtering if there is no other intentional lua action to set the tag.

@@ -300,7 +309,7 @@ Functions
.. versionadded: 1.5.0

Set the maximum imbalance between the number of outstanding queries intended for a given server, based on its weight,
and the actual number, when using the ``whashed`` or ``wrandom`` load-balancing policy.
and the actual number, when using the ``whashed`` or ``wrandom`` or ``orderedWrandUntag`` load-balancing policy.
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
and the actual number, when using the ``whashed`` or ``wrandom`` or ``orderedWrandUntag`` load-balancing policy.
and the actual number, when using the ``whashed``, ``wrandom`` or ``orderedWrandUntag`` load-balancing policy.

@@ -631,7 +631,7 @@ Setting for load-balancing policies
- **default_policy**: String ``(leastOutstanding)`` - Set the default server selection policy
- **servfail_on_no_server**: Boolean ``(false)`` - If set, return a ServFail when no servers are available, instead of the default behaviour of dropping the query
- **round_robin_servfail_on_no_server**: Boolean ``(false)`` - By default the roundrobin load-balancing policy will still try to select a backend even if all backends are currently down. Setting this to true will make the policy fail and return that no server is available instead
- **weighted_balancing_factor**: Double ``(0.0)`` - Set the maximum imbalance between the number of outstanding queries intended for a given server, based on its weight, and the actual number, when using the ``whashed`` or ``wrandom`` load-balancing policy. Default is 0, which disables the bounded-load algorithm
- **weighted_balancing_factor**: Double ``(0.0)`` - Set the maximum imbalance between the number of outstanding queries intended for a given server, based on its weight, and the actual number, when using the ``whashed`` or ``wrandom`` or ``orderedWrandUntag`` load-balancing policy. Default is 0, which disables the bounded-load algorithm
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
- **weighted_balancing_factor**: Double ``(0.0)`` - Set the maximum imbalance between the number of outstanding queries intended for a given server, based on its weight, and the actual number, when using the ``whashed`` or ``wrandom`` or ``orderedWrandUntag`` load-balancing policy. Default is 0, which disables the bounded-load algorithm
- **weighted_balancing_factor**: Double ``(0.0)`` - Set the maximum imbalance between the number of outstanding queries intended for a given server, based on its weight, and the actual number, when using the ``whashed``, ``wrandom`` or ``orderedWrandUntag`` load-balancing policy. Default is 0, which disables the bounded-load algorithm

@pacnal
Copy link
Contributor Author
pacnal commented Jun 14, 2025

Thanks for the comments, addressed in the followed commit.

Copy link
Member
@rgacogne rgacogne left a comment

Choose a reason for hiding this comment

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

Thanks for contributing this PR! I have made a few comments, but the general idea looks OK.

return {};
}

ServerPolicy::NumberedServerVector selected(candidates.begin() + startIndex, candidates.end());
Copy link
Member

Choose a reason for hiding this comment

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

Is there a reason you decided to copy to a new vector rather than erasing1 from candidates? In theory I think it would be slightly more efficient to erase but I have not measured it. Actually, I don't think this is needed because of my comment above.


for (const auto& svr : servers) {
if (svr.second->isUp() && svr.second->d_config.order <= curOrder && (!dnsq->ids.qTag || dnsq->ids.qTag->count(svr.second->getNameWithAddr()) == 0)) {
if (svr.second->d_config.order < curOrder) {
Copy link
Member

Choose a reason for hiding this comment

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

This should never happen because servers are ordered on their order inside a pool. And if it did happen you would have an issue because the index that is stored in svr.second would be completely wrong, which could cause an exception to be thrown in getValRandom. So I think it would make sense to remove this test, perhaps adding a comment explaining why it is not needed.

end
end
"""

Copy link
Member

Choose a reason for hiding this comment

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

Unless I'm mistaken this doesn't test the case where a server is not used because a tag? It would be nice to test this case as well.

@pacnal
Copy link
Contributor Author
pacnal commented Jun 17, 2025

that will be good if the pool servers are already sorted by its order. I'll checkout and make changes accordingly. Yes, tag is not tested as I thought it is the same condition as server down. But yes, rigorously, separate testing for that condition is better. I'll work it out.

@rgacogne rgacogne merged commit 8c6f451 into PowerDNS:master Jun 17, 2025
89 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants
0