bench: add --vs-nextdns, --vs-unbound-cold modes with mode validation
- --vs-nextdns: Numa local cache vs NextDNS cloud (45.90.28.0) - --vs-unbound-cold: unique random subdomains, no record cache hits - check_numa_mode validates forward/recursive mode before running - numa-bench-recursive.toml config for cold benchmarks
This commit is contained in:
30
benches/numa-bench-recursive.toml
Normal file
30
benches/numa-bench-recursive.toml
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
[server]
|
||||||
|
bind_addr = "127.0.0.1:5454"
|
||||||
|
api_port = 5381
|
||||||
|
api_bind_addr = "127.0.0.1"
|
||||||
|
data_dir = "/tmp/numa-bench"
|
||||||
|
|
||||||
|
[upstream]
|
||||||
|
mode = "recursive"
|
||||||
|
timeout_ms = 10000
|
||||||
|
|
||||||
|
[cache]
|
||||||
|
min_ttl = 60
|
||||||
|
max_ttl = 3600
|
||||||
|
|
||||||
|
[blocking]
|
||||||
|
enabled = false
|
||||||
|
|
||||||
|
[proxy]
|
||||||
|
port = 8080
|
||||||
|
tls_port = 8443
|
||||||
|
|
||||||
|
[dot]
|
||||||
|
enabled = true
|
||||||
|
port = 8530
|
||||||
|
|
||||||
|
[mobile]
|
||||||
|
enabled = false
|
||||||
|
|
||||||
|
[lan]
|
||||||
|
enabled = false
|
||||||
@@ -7,6 +7,8 @@
|
|||||||
//! --direct Library-to-library: Numa forward_query_raw vs Hickory resolver.lookup
|
//! --direct Library-to-library: Numa forward_query_raw vs Hickory resolver.lookup
|
||||||
//! --hedge-5x Hedging: single vs hedge-same vs hedge-dual vs Hickory (5 iterations)
|
//! --hedge-5x Hedging: single vs hedge-same vs hedge-dual vs Hickory (5 iterations)
|
||||||
//! --vs-unbound Server-to-server: Numa vs Unbound (plain UDP, caching)
|
//! --vs-unbound Server-to-server: Numa vs Unbound (plain UDP, caching)
|
||||||
|
//! --vs-unbound-cold Cold: Numa vs Unbound (unique subdomains, no cache hits)
|
||||||
|
//! --vs-nextdns Server-to-cloud: Numa (local cache) vs NextDNS (remote, 45.90.28.0)
|
||||||
//! --vs-dot DoT server: Numa vs Unbound
|
//! --vs-dot DoT server: Numa vs Unbound
|
||||||
//! --vs-doh-servers DoH server: Numa vs Unbound (DoT upstream)
|
//! --vs-doh-servers DoH server: Numa vs Unbound (DoT upstream)
|
||||||
//!
|
//!
|
||||||
@@ -145,10 +147,20 @@ fn main() {
|
|||||||
return run_hedge_multi(&rt, 5);
|
return run_hedge_multi(&rt, 5);
|
||||||
}
|
}
|
||||||
if arg("--vs-unbound") {
|
if arg("--vs-unbound") {
|
||||||
return run_server_comparison(&rt, "Unbound", "127.0.0.1:5456", 5);
|
check_numa_mode(&rt, "forward");
|
||||||
|
return run_server_comparison(&rt, "Unbound", "127.0.0.1:5456", 5, false);
|
||||||
|
}
|
||||||
|
if arg("--vs-unbound-cold") {
|
||||||
|
check_numa_mode(&rt, "recursive");
|
||||||
|
return run_server_comparison(&rt, "Unbound", "127.0.0.1:5456", 5, true);
|
||||||
}
|
}
|
||||||
if arg("--vs-dnscrypt") {
|
if arg("--vs-dnscrypt") {
|
||||||
return run_server_comparison(&rt, "dnscrypt-proxy", "127.0.0.1:5455", 5);
|
check_numa_mode(&rt, "forward");
|
||||||
|
return run_server_comparison(&rt, "dnscrypt-proxy", "127.0.0.1:5455", 5, false);
|
||||||
|
}
|
||||||
|
if arg("--vs-nextdns") {
|
||||||
|
check_numa_mode(&rt, "forward");
|
||||||
|
return run_server_comparison(&rt, "NextDNS", "45.90.28.0:53", 5, false);
|
||||||
}
|
}
|
||||||
if arg("--vs-dot") {
|
if arg("--vs-dot") {
|
||||||
return run_dot_comparison(&rt, 5);
|
return run_dot_comparison(&rt, 5);
|
||||||
@@ -380,12 +392,18 @@ fn run_direct(rt: &tokio::runtime::Runtime) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Server-to-server: Numa vs another server, both on plain UDP.
|
/// Server-to-server: Numa vs another server, both on plain UDP.
|
||||||
|
/// When `cold` is true, each query uses a unique random subdomain so neither
|
||||||
|
/// server can answer from its record cache (NS delegation caching still applies).
|
||||||
fn run_server_comparison(
|
fn run_server_comparison(
|
||||||
rt: &tokio::runtime::Runtime,
|
rt: &tokio::runtime::Runtime,
|
||||||
other_name: &str,
|
other_name: &str,
|
||||||
other_addr: &str,
|
other_addr: &str,
|
||||||
iterations: usize,
|
iterations: usize,
|
||||||
|
cold: bool,
|
||||||
) {
|
) {
|
||||||
|
use std::sync::atomic::{AtomicU64, Ordering};
|
||||||
|
static COUNTER: AtomicU64 = AtomicU64::new(0);
|
||||||
|
|
||||||
let numa_addr: SocketAddr = NUMA_BENCH.parse().unwrap();
|
let numa_addr: SocketAddr = NUMA_BENCH.parse().unwrap();
|
||||||
let other: SocketAddr = other_addr.parse().unwrap();
|
let other: SocketAddr = other_addr.parse().unwrap();
|
||||||
|
|
||||||
@@ -402,19 +420,35 @@ fn run_server_comparison(
|
|||||||
let _ = rt.block_on(query_udp(other, "example.com"));
|
let _ = rt.block_on(query_udp(other, "example.com"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let tag = if cold {
|
||||||
|
"cold, unique subdomains"
|
||||||
|
} else {
|
||||||
|
"caching"
|
||||||
|
};
|
||||||
|
|
||||||
compare_two(
|
compare_two(
|
||||||
rt,
|
rt,
|
||||||
&format!("Server-to-Server: Numa vs {other_name} (UDP, caching)"),
|
&format!("Server-to-Server: Numa vs {other_name} (UDP, {tag})"),
|
||||||
"Numa",
|
"Numa",
|
||||||
other_name,
|
other_name,
|
||||||
&|domain| {
|
&|domain| {
|
||||||
|
let d = if cold {
|
||||||
|
format!("c{}.{}", COUNTER.fetch_add(1, Ordering::Relaxed), domain)
|
||||||
|
} else {
|
||||||
|
domain.to_string()
|
||||||
|
};
|
||||||
let t = Instant::now();
|
let t = Instant::now();
|
||||||
let _ = rt.block_on(query_udp(numa_addr, domain));
|
let _ = rt.block_on(query_udp(numa_addr, &d));
|
||||||
t.elapsed().as_secs_f64() * 1000.0
|
t.elapsed().as_secs_f64() * 1000.0
|
||||||
},
|
},
|
||||||
&|domain| {
|
&|domain| {
|
||||||
|
let d = if cold {
|
||||||
|
format!("c{}.{}", COUNTER.fetch_add(1, Ordering::Relaxed), domain)
|
||||||
|
} else {
|
||||||
|
domain.to_string()
|
||||||
|
};
|
||||||
let t = Instant::now();
|
let t = Instant::now();
|
||||||
let _ = rt.block_on(query_udp(other, domain));
|
let _ = rt.block_on(query_udp(other, &d));
|
||||||
t.elapsed().as_secs_f64() * 1000.0
|
t.elapsed().as_secs_f64() * 1000.0
|
||||||
},
|
},
|
||||||
iterations,
|
iterations,
|
||||||
@@ -991,6 +1025,28 @@ fn build_query(buf: &mut [u8], domain: &str) -> usize {
|
|||||||
pos
|
pos
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn check_numa_mode(rt: &tokio::runtime::Runtime, expected: &str) {
|
||||||
|
let url = format!("http://127.0.0.1:{NUMA_API}/stats");
|
||||||
|
let resp = match rt.block_on(async { reqwest::get(&url).await?.text().await }) {
|
||||||
|
Ok(body) => body,
|
||||||
|
Err(_) => {
|
||||||
|
eprintln!("Bench Numa not responding on {NUMA_BENCH}");
|
||||||
|
eprintln!("Start with: cargo run -- benches/numa-bench.toml");
|
||||||
|
std::process::exit(1);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
let config = if expected == "recursive" {
|
||||||
|
"benches/numa-bench-recursive.toml"
|
||||||
|
} else {
|
||||||
|
"benches/numa-bench.toml"
|
||||||
|
};
|
||||||
|
if !resp.contains(&format!("\"mode\":\"{expected}\"")) {
|
||||||
|
eprintln!("This benchmark requires Numa in {expected} mode.");
|
||||||
|
eprintln!("Restart with: cargo run -- {config}");
|
||||||
|
std::process::exit(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn flush_cache() {
|
fn flush_cache() {
|
||||||
let _ = std::process::Command::new("curl")
|
let _ = std::process::Command::new("curl")
|
||||||
.args([
|
.args([
|
||||||
|
|||||||
Reference in New Issue
Block a user