mirror of
https://github.com/hickory-dns/hickory-dns.git
synced 2026-04-25 03:05:51 +03:00
[GH-ISSUE #1947] Question: Why does trustdns open and close a socket each time it is sending a request? #827
Labels
No labels
blocked
breaking-change
bug
bug:critical
bug:tests
cleanup
compliance
compliance
compliance
crate:all
crate:client
crate:native-tls
crate:proto
crate:recursor
crate:resolver
crate:resolver
crate:rustls
crate:server
crate:util
dependencies
docs
duplicate
easy
easy
enhance
enhance
enhance
feature:dns-over-https
feature:dns-over-quic
feature:dns-over-tls
feature:dnsssec
feature:global_lb
feature:mdns
feature:tsig
features:edns
has workaround
ops
perf
platform:WASM
platform:android
platform:fuchsia
platform:linux
platform:macos
platform:windows
pull-request
question
test
tools
tools
trust
unclear
wontfix
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
starred/hickory-dns#827
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Originally created by @CalderWhite on GitHub (May 28, 2023).
Original GitHub issue: https://github.com/hickory-dns/hickory-dns/issues/1947
PLATFORM: x86_64
OS: Ubuntu 22
Misc: Running in linode cloud on a 4vCPU machine with 8GB of ram.
I am running some performance tests on this library. I already ran into issues with the resolver copying memory too much (5GB+). I tracked that down to it calling
.clone()on the lru cache too much. So instead I have been using the client directly and I noticed after profiling that much of the runtime of the program (~50%) is being spent on opening and closing UDP sockets.My code creates one client for each DNS resolver server then distributes calls amongst them. I can achieve 40k QPS with 4096 resolver servers but after that the overhead of the UDP socket creation and destruction is too great for the server. This can be seen in the flamegraph of my code as well as the kernel usage in htop (mostly red bars, meaning the kernel is doing a ton of work instead of the user threads).
Here's my code for reference:
@CalderWhite commented on GitHub (May 28, 2023):
I'll also mention that I tried TCP but it would throw a proto error "busy" after a few requests and I'm not sure how I should handle this.
@djc commented on GitHub (May 28, 2023):
Thanks for investigating performance with the trust-dns libraries! Sounds like you've run into some interesting results.
I believe the behavior for creating new UDP sockets is because of potential security issues where it's possible to forge DNS responses if a socket is reused over time. Maybe search the issue tracker for previous discussions?
In general the resolver library has seen more work and would probably be a better place to invest in improvements assuming it can meet your performance budget. Would be interesting to dig into the cache cloning issue more to see how it can be mitigated. Maybe you want a set of (one per core) independently caching resolvers rather than resolvers sharing a single cache?
As for the busy issue, I assume this means that the server dislikes the rate at which you're sending requests and asking you to slow down (rate limiting), but I'm a little unclear on what you're using as the server here.
@CalderWhite commented on GitHub (May 28, 2023):
Thanks for the quick response!
@bluejekyll commented on GitHub (May 30, 2023):
Yeah, for UDP the default behavior is to select a new UDP socket and port on all requests in order to reduce the chance of spoofed/forged responses. It's something that we could theoretically add an option to disable, but the aim of the library has generally been one of resilience.
On TCP, I'm going to agree with @djc and say you're probably being rate limited.