C# 加快大批量IP的反向DNS查找
出于分析目的,我想在大批量IP上执行反向DNS查找。“大”的意思是,每小时至少数万。我正在寻找提高处理速度的方法,即降低每批的处理时间 将的异步版本包装到可等待的任务中已经有了很大的帮助(与顺序请求相比),导致了appox的吞吐量。100-200 IP/秒:C# 加快大批量IP的反向DNS查找,c#,.net,dns,async-await,reverse-dns,C#,.net,Dns,Async Await,Reverse Dns,出于分析目的,我想在大批量IP上执行反向DNS查找。“大”的意思是,每小时至少数万。我正在寻找提高处理速度的方法,即降低每批的处理时间 将的异步版本包装到可等待的任务中已经有了很大的帮助(与顺序请求相比),导致了appox的吞吐量。100-200 IP/秒: static async Task DoReverseDnsLookups() { // in reality, thousands of IPs var ips = new[] { "173.194.121.9", "17
static async Task DoReverseDnsLookups()
{
// in reality, thousands of IPs
var ips = new[] { "173.194.121.9", "173.252.110.27", "98.138.253.109" };
var hosts = new Dictionary<string, string>();
var tasks =
ips.Select(
ip =>
Task.Factory.FromAsync(Dns.BeginGetHostEntry,
(Func<IAsyncResult, IPHostEntry>) Dns.EndGetHostEntry,
ip, null)
.ContinueWith(t =>
hosts[ip] = ((t.Exception == null) && (t.Result != null))
? t.Result.HostName : null));
var start = DateTime.UtcNow;
await Task.WhenAll(tasks);
var end = DateTime.UtcNow;
Console.WriteLine("Resolved {0} IPs in {1}, that's {2}/sec.",
ips.Count(), end - start,
ips.Count() / (end - start).TotalSeconds);
}
静态异步任务DoReverseDnsLookups()
{
//事实上,成千上万的IP
var ips=new[]{“173.194.121.9”、“173.252.110.27”、“98.138.253.109”};
var hosts=newdictionary();
变量任务=
选择(
ip=>
Task.Factory.FromAsync(Dns.BeginGetHostEntry,
(Func)Dns.EndGetHostEntry,
ip,空)
.ContinueWith(t=>
主机[ip]=((t.Exception==null)和&(t.Result!=null))
?t.Result.HostName:null);
var start=DateTime.UtcNow;
等待任务。何时(任务);
var end=DateTime.UtcNow;
WriteLine(“在{1}中解析了{0}个IP,即{2}/秒。”,
ips.Count(),结束-开始,
ips.Count()/(结束-开始).TotalSeconds);
}
有没有办法进一步提高处理速度
例如,是否有任何方法将一批IP发送到DNS服务器
顺便说一句,我假设在封面下,是由异步方法使用的-如果我错了,请纠正我。您好这里有一些提示,您可以改进:
- 和往常一样,我建议使用的,而不是一次触发所有请求并等待所有请求完成。使用具有高
的MaxDegreeOfParallelism
可以让ActionBlock
自行决定并发触发多少调用,从而更好地利用资源:TPL
var block=新动作块(
异步ip=>
{
尝试
{
var host=(wait Dns.GetHostEntryAsync(ip)).HostName;
如果(!string.IsNullOrWhitespace(主机))
{
hosts[ip]=主机;
}
}
抓住
{
返回;
}
},
新的ExecutionDataflowBlockOptions{MaxDegreeOfParallelism=5000});
- 我还建议添加一个缓存,并确保不会多次解析同一ip
- 当您使用.net的
类时,它在Dns(例如LLMNR)旁边包含一些回退,这使得它非常慢。如果您所需要的只是DNS查询,那么您可能需要使用一个专用的库,如Dns
附:关于您的代码示例的一些备注:
GetHostEntryAsync
而不是FromAsync
ConcurrentDictionary
为什么要使用
fromsync
而不是现有的?@noserratio,因为我没有看到它。:/可能没有想到Begin/End和-Async版本。缓存确实有帮助,实际上已经在这样做了(应该提到)。多个DNS服务器也是一个好主意。谢谢试用了ARSoft.Tools.Net,它比System.Net.Dns快得多-至少5倍。
var block = new ActionBlock<string>(
async ip =>
{
try
{
var host = (await Dns.GetHostEntryAsync(ip)).HostName;
if (!string.IsNullOrWhitespace(host))
{
hosts[ip] = host;
}
}
catch
{
return;
}
},
new ExecutionDataflowBlockOptions { MaxDegreeOfParallelism = 5000});