Unbound DNS Sunucusu Performans Testi ve Benchmark Rehberi
DNS sunucunuzun ne kadar hızlı çalıştığını biliyor musunuz? Çoğu sysadmin Unbound’u kurar, birkaç temel ayarı yapar ve “çalışıyor, tamam” der geçer. Oysa production ortamında yüz binlerce sorgu işleyen bir DNS sunucusunda performans farkı, kullanıcı deneyimini doğrudan etkiler. Bu yazıda Unbound DNS sunucusunun performansını nasıl test edeceğinizi, darboğazları nasıl bulacağınızı ve benchmark sonuçlarını nasıl yorumlayacağınızı ele alacağım.
Neden Benchmark Yapmalıyız?
Sistemi kurarken “yeterince hızlı” gibi muğlak bir hedefle çalışmak yerine somut rakamlar üzerinden konuşmak çok daha sağlıklı. Benchmark yapmanın birkaç kritik amacı var:
- Baseline oluşturmak: Sistemin normal performansını bilmeden, bir sorun çıktığında neyin değiştiğini anlayamazsınız.
- Kapasite planlaması: “Bu sunucu kaç sorgu/saniye kaldırır?” sorusuna gerçek veri ile cevap verebilmek.
- Konfigürasyon değişikliklerinin etkisini ölçmek: Cache boyutunu artırdınız, thread sayısını değiştirdiniz. Bunların etkisi ne oldu?
- Donanım yükseltmesi kararları: Daha fazla RAM veya CPU almak gerekiyor mu?
Deneyimlerimden şunu söyleyebilirim: Bir e-ticaret altyapısında yapılan DNS optimizasyonu, sayfa yükleme sürelerini ortalama 40-80ms düşürebiliyor. Bu rakamlar conversion rate açısından ciddi fark yaratıyor.
Test Ortamının Hazırlanması
Benchmark yapmadan önce test ortamını doğru kurmak şart. Production sunucusunda doğrudan test yapmak hem riskli hem de yanıltıcı sonuçlar verir; gerçek trafikle test trafiği birbirine karışır.
Gerekli Araçlar
Test için kullanacağımız temel araçlar:
- dnsperf: ISC tarafından geliştirilen, DNS sunucu performans testi için en yaygın kullanılan araç
- resperf: dnsperf’in kardeşi, özellikle ramp-up testleri için
- queryperf: BIND ile gelen ama Unbound testlerinde de kullanılabilen araç
- drill/dig: Temel gecikme ölçümleri için
Kurulum:
# Ubuntu/Debian
apt-get install dnsperf
# RHEL/CentOS/Rocky Linux
dnf install epel-release
dnf install dnsperf
# Kaynak koddan derleme (en güncel sürüm için)
git clone https://github.com/DNS-OARC/dnsperf.git
cd dnsperf
./configure
make && make install
Test Sorgu Dosyasının Oluşturulması
dnsperf, test sorgularını bir dosyadan okur. Gerçekçi bir test için gerçek dünya trafiğine benzer sorgular kullanmak gerekiyor.
# Temel bir sorgu dosyası oluşturma
cat > /tmp/queryfile.txt << 'EOF'
google.com A
facebook.com A
youtube.com A
github.com A
cloudflare.com A
amazon.com A
stackoverflow.com A
linkedin.com A
twitter.com AAAA
microsoft.com MX
apple.com A
netflix.com A
reddit.com A
wikipedia.org A
instagram.com A
EOF
Daha büyük ve gerçekçi bir sorgu seti için Alexa veya benzeri listelerden yararlanabilirsiniz:
# Örnek büyük sorgu dosyası oluşturma scripti
#!/bin/bash
DOMAINS=(
"google.com" "youtube.com" "facebook.com" "twitter.com" "instagram.com"
"linkedin.com" "github.com" "stackoverflow.com" "reddit.com" "wikipedia.org"
"amazon.com" "netflix.com" "apple.com" "microsoft.com" "cloudflare.com"
)
TYPES=("A" "AAAA" "MX" "NS" "TXT")
for i in $(seq 1 1000); do
domain=${DOMAINS[$RANDOM % ${#DOMAINS[@]}]}
type=${TYPES[$RANDOM % ${#TYPES[@]}]}
echo "$domain $type"
done > /tmp/large_queryfile.txt
echo "Sorgu dosyası oluşturuldu: $(wc -l /tmp/large_queryfile.txt) satır"
Temel Benchmark Testleri
İlk Baseline Testi
Herhangi bir optimizasyon yapmadan önce mevcut performansı ölçmek gerekiyor. Bu baseline olmadan iyileştirmelerin etkisini göremezsiniz.
# Temel dnsperf testi
# -s: hedef sunucu
# -d: sorgu dosyası
# -l: test süresi (saniye)
# -c: eşzamanlı bağlantı sayısı
# -Q: maksimum sorgu/saniye
dnsperf -s 127.0.0.1
-d /tmp/queryfile.txt
-l 30
-c 10
-Q 1000
-p 53
# Çıktı örneği:
# DNS Performance Testing Tool
# Queries sent: 30000
# Queries completed: 29987 (99.96%)
# Queries lost: 13 (0.04%)
# Run time (s): 30.000
# Queries per second: 999.57
# Average latency (s): 0.002341
# Latency std dev (s): 0.001205
Cache Hit Oranını Test Etme
Unbound’un en büyük güçlerinden biri cache mekanizması. Cache hit oranı performansın en kritik göstergelerinden biri.
# Önce cache'i temizle
unbound-control flush_zone "."
unbound-control reload
# İlk geçiş - cold cache
echo "=== COLD CACHE TESTİ ==="
dnsperf -s 127.0.0.1
-d /tmp/queryfile.txt
-l 30
-c 20
-p 53 2>&1 | grep -E "(Queries per second|Average latency|completed)"
# Kısa bekleme - cache dolsun
sleep 5
# İkinci geçiş - warm cache
echo "=== WARM CACHE TESTİ ==="
dnsperf -s 127.0.0.1
-d /tmp/queryfile.txt
-l 30
-c 20
-p 53 2>&1 | grep -E "(Queries per second|Average latency|completed)"
Kendi test ortamımda tipik olarak cold cache’de 2-5ms gecikme, warm cache’de 0.1-0.5ms gecikme görüyorum. Bu fark Unbound’un neden önde geldiğini net olarak ortaya koyuyor.
Unbound Konfigürasyon Optimizasyonları ve Etkilerini Ölçme
Thread ve Bellek Ayarları
# /etc/unbound/unbound.conf - performans odaklı ayarlar
server:
# CPU çekirdek sayısına göre ayarlayın
num-threads: 4
# Her thread için ayrı cache (false daha az bellek kullanır ama lock contention yaratır)
so-reuseport: yes
# Cache boyutları - mevcut RAM'in %25'ini geçmeyin
msg-cache-size: 256m
rrset-cache-size: 512m
# Negative cache
neg-cache-size: 4m
# Outgoing bağlantı sayısı
outgoing-range: 4096
num-queries-per-thread: 4096
# Prefetch - TTL dolmadan önce cache yenile
prefetch: yes
prefetch-key: yes
# Minimal yanıtlar (daha az data transfer)
minimal-responses: yes
# EDNS buffer size
edns-buffer-size: 1232
Bu ayarları uyguladıktan sonra benchmark tekrar çalıştırın:
#!/bin/bash
# Konfigürasyon karşılaştırma scripti
run_test() {
local label=$1
local duration=30
echo "=== $label ==="
result=$(dnsperf -s 127.0.0.1
-d /tmp/large_queryfile.txt
-l $duration
-c 50
-p 53 2>&1)
qps=$(echo "$result" | grep "Queries per second" | awk '{print $NF}')
latency=$(echo "$result" | grep "Average latency" | awk '{print $NF}')
loss=$(echo "$result" | grep "Queries lost" | awk '{print $NF}')
echo "QPS: $qps"
echo "Ortalama Gecikme: $latency saniye"
echo "Kayıp: $loss"
echo "---"
}
systemctl restart unbound
sleep 3
run_test "Varsayılan Ayarlar"
# Ayarları uygula...
# systemctl restart unbound
# sleep 3
# run_test "Optimize Edilmiş Ayarlar"
So-reuseport Etkisi
Linux kernel 3.9 ve sonrasında SO_REUSEPORT socket opsiyonu, çok thread’li DNS sunucularında ciddi performans artışı sağlıyor.
# Unbound istatistiklerini kontrol et
unbound-control stats_noreset | grep -E "(total.|num.)" | head -20
# Önemli metrikler:
# total.num.queries: toplam sorgu sayısı
# total.num.cachehits: cache'den karşılanan sorgular
# total.num.cachemiss: upstream'e giden sorgular
# total.num.prefetch: prefetch ile yenilenen kayıtlar
# Cache hit oranını hesapla
hits=$(unbound-control stats_noreset | grep "total.num.cachehits" | awk -F= '{print $2}')
total=$(unbound-control stats_noreset | grep "total.num.queries" | awk -F= '{print $2}')
if [ -n "$hits" ] && [ -n "$total" ] && [ "$total" -gt 0 ]; then
ratio=$(echo "scale=2; $hits * 100 / $total" | bc)
echo "Cache hit oranı: %$ratio"
fi
Stres Testi ve Kapasite Planlaması
Normal koşullar altında iyi çalışan bir sunucu, trafik aniden yükseldiğinde nasıl davranır? Resperf bu soruyu cevaplamak için biçilmiş kaftan.
# resperf ile kademeli yük testi
# -s: hedef
# -d: sorgu dosyası
# -r: test süresi (saniye)
# -m: maksimum QPS (ramp-up hedefi)
resperf -s 127.0.0.1
-d /tmp/large_queryfile.txt
-r 60
-m 50000
-p 53 > /tmp/resperf_output.txt 2>&1
# Sonuçları görüntüle
tail -20 /tmp/resperf_output.txt
Resperf çıktısı size sistemin hangi QPS değerinde doyuma ulaştığını, yani “elbow point”i gösterir. Bu nokta teorik kapasitenizdir ve güvenli operasyon için bu değerin %70-80’inde çalışmanızı öneririm.
Uzun Süreli Dayanıklılık Testi
#!/bin/bash
# 10 dakikalık dayanıklılık testi
echo "Dayanıklılık testi başlıyor: $(date)"
dnsperf -s 127.0.0.1
-d /tmp/large_queryfile.txt
-l 600
-c 100
-Q 5000
-p 53
-v > /tmp/endurance_test.log 2>&1 &
DNSPERF_PID=$!
# Test sırasında sistem kaynaklarını izle
while kill -0 $DNSPERF_PID 2>/dev/null; do
timestamp=$(date '+%H:%M:%S')
cpu=$(top -bn1 | grep "unbound" | awk '{print $9}' | head -1)
mem=$(ps aux | grep unbound | grep -v grep | awk '{print $6}' | head -1)
echo "$timestamp - CPU: ${cpu}%, MEM: ${mem}KB" >> /tmp/resource_usage.log
sleep 10
done
echo "Test tamamlandı: $(date)"
echo "Kaynak kullanımı özeti:"
tail -5 /tmp/resource_usage.log
Gecikme Dağılımı Analizi
Ortalama gecikme bazen yanıltıcı olabilir. 1ms ortalama gecikmeniz olabilir ama P99 (yüzde doksan dokuzuncu yüzdelik) gecikmeniz 500ms ise bu ciddi bir sorun.
# dnsperf ile percentile analizi
dnsperf -s 127.0.0.1
-d /tmp/large_queryfile.txt
-l 60
-c 50
-p 53
-T 200 2>&1 | tee /tmp/latency_test.txt
# Çıktıdan latency percentile'larını okuyun
grep -E "(latency|percentile)" /tmp/latency_test.txt
# Manuel percentile hesaplama için
# dnsperf -T flag'i 200 hesaplama aralığı kullanır
# Sonuçlar şöyle görünür:
# Latency distribution:
# < 0.001000 s: 45.23%
# < 0.002000 s: 78.91%
# < 0.005000 s: 95.43%
# < 0.010000 s: 99.12%
# < 0.020000 s: 99.87%
P95 ve P99 değerlerinizi takip etmek, sporadik yavaşlık sorunlarını tespit etmek için kritik öneme sahip.
Unbound İstatistikleri ile Sürekli Monitoring
Benchmark tek seferlik değil, sürekli yapılması gereken bir aktivite. Unbound’un built-in istatistikleri bu konuda çok işe yarıyor.
#!/bin/bash
# Unbound performans monitoring scripti
# Bunu cron'a ekleyebilir veya bir monitoring sistemine entegre edebilirsiniz
collect_stats() {
stats=$(unbound-control stats_noreset)
total_queries=$(echo "$stats" | grep "^total.num.queries=" | cut -d= -f2)
cache_hits=$(echo "$stats" | grep "^total.num.cachehits=" | cut -d= -f2)
cache_miss=$(echo "$stats" | grep "^total.num.cachemiss=" | cut -d= -f2)
avg_latency=$(echo "$stats" | grep "^total.recursion.time.avg=" | cut -d= -f2)
median_latency=$(echo "$stats" | grep "^total.recursion.time.median=" | cut -d= -f2)
# Cache hit oranı
if [ "$total_queries" -gt 0 ] 2>/dev/null; then
hit_ratio=$(echo "scale=4; $cache_hits / $total_queries * 100" | bc 2>/dev/null)
fi
timestamp=$(date '+%Y-%m-%d %H:%M:%S')
echo "$timestamp | Toplam: $total_queries | Hit: $cache_hits | Miss: $cache_miss | Hit Oranı: %${hit_ratio} | Ort. Gecikme: ${avg_latency}s | Medyan: ${median_latency}s"
}
# Her 60 saniyede bir istatistik topla
while true; do
collect_stats >> /var/log/unbound_perf.log
sleep 60
done
Bu scripti bir systemd service olarak çalıştırabilir, çıktıyı Prometheus + Grafana gibi monitoring sistemlerinize besleyebilirsiniz.
Yaygın Performans Sorunları ve Çözümleri
Benchmark sonuçlarınız beklentilerin altında kalıyorsa kontrol etmeniz gereken noktalar:
Yüksek cache miss oranı (%20’nin üzeri): Sorgu çeşitliliği çok yüksek olabilir ya da cache boyutu yetersiz. msg-cache-size ve rrset-cache-size değerlerini artırın.
Yüksek recursion süresi: Upstream DNS sunucularınız yavaş olabilir. outbound-msg-retry ve target-fetch-policy ayarlarını gözden geçirin.
Thread başına düşen sorgu sayısı dengesiz: so-reuseport: yes aktif değilse thread’ler arasında yük dengesiz dağılabilir.
Yüksek paket kaybı: outgoing-range değeri too low olabilir. Özellikle yüksek QPS testlerinde bu değeri artırın.
# Hızlı tanı komutu
unbound-control stats | grep -E "(num.queries|cachehits|cachemiss|recursion)" |
while IFS='=' read key value; do
printf "%-45s: %sn" "$key" "$value"
done
Karşılaştırmalı Test: Unbound vs Bind vs PowerDNS Recursor
Kendi sunucunuzun rakiplerle karşılaştırmasını yapmak isteyebilirsiniz. Bunun için Docker kullanarak izole test ortamı oluşturabilirsiniz:
# Unbound test container
docker run -d --name unbound-test
-p 5301:53/udp -p 5301:53/tcp
mvance/unbound:latest
# Bind test container
docker run -d --name bind-test
-p 5302:53/udp -p 5302:53/tcp
internetsystemsconsortium/bind9:9.18
# Her iki sunucuya karşı test
echo "=== UNBOUND ==="
dnsperf -s 127.0.0.1 -p 5301 -d /tmp/large_queryfile.txt -l 30 -c 50 2>&1 |
grep -E "(per second|latency|lost)"
echo "=== BIND ==="
dnsperf -s 127.0.0.1 -p 5302 -d /tmp/large_queryfile.txt -l 30 -c 50 2>&1 |
grep -E "(per second|latency|lost)"
# Temizlik
docker stop unbound-test bind-test
docker rm unbound-test bind-test
Sonuç
Unbound performans testi sadece “çalışıyor mu” sorusunun ötesine geçip “ne kadar iyi çalışıyor” sorusuna cevap arıyor. Bu yazıda ele aldığımız yaklaşımları özetlemek gerekirse:
- Baseline oluşturun: Her optimizasyon öncesi ve sonrası ölçüm yapın, sezgiyle değil veriyle karar verin.
- Gerçekçi test verileri kullanın: Gerçek trafiğe benzer sorgu setleri hazırlayın, yüzlerce rastgele alan adı değil, gerçek dağılımı yansıtan setler kullanın.
- Sadece ortalamaya bakmayın: P95 ve P99 gecikme değerleri çoğu zaman ortalamadan daha anlamlı bilgi verir.
- Stres testini ihmal etmeyin: Sisteminizin teorik kapasitesini biliyor olmanız, ani trafik artışlarına hazırlıklı olmanızı sağlar.
- Sürekli izleyin: Tek seferlik benchmark yeterli değil;
unbound-control statsçıktısını düzenli aralıklarla toplayın.
Cache hit oranınız %80’in altındaysa veya P99 gecikmeniz 50ms’yi geçiyorsa konfigürasyonunuzu gözden geçirme zamanı gelmiş demektir. Sayılar yalan söylemez; sadece onlara kulak vermek gerekiyor.
