C# 加快大批量IP的反向DNS查找

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

出于分析目的,我想在大批量IP上执行反向DNS查找。“大”的意思是,每小时至少数万。我正在寻找提高处理速度的方法,即降低每批的处理时间

将的异步版本包装到可等待的任务中已经有了很大的帮助(与顺序请求相比),导致了appox的吞吐量。100-200 IP/秒:

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服务器


顺便说一句,我假设在封面下,是由异步方法使用的-如果我错了,请纠正我。

您好这里有一些提示,您可以改进:

  • 在本地缓存查询,因为此信息通常不会更改 几天甚至几年。这样你就不必每次都解决问题了
  • 大多数DNS服务器将自动缓存信息,以便下次解析 很快。通常缓存为4小时,至少在Windows服务器上是默认值。 这意味着,如果您在短时间内批量运行此流程,它的性能会更好 如果您在允许cahce过期的一天内多次解析地址
  • 很好,您正在使用任务并行性,但仍然要求相同的DNS服务器 在您的计算机上配置。我认为让两台机器使用不同的DNS服务器将 改进流程
  • 我希望这能有所帮助。

    • 和往常一样,我建议使用的,而不是一次触发所有请求并等待所有请求完成。使用具有高
      MaxDegreeOfParallelism
      ActionBlock
      可以让
      TPL
      自行决定并发触发多少调用,从而更好地利用资源:

    var block=新动作块(
    异步ip=>
    { 
    尝试
    {
    var host=(wait Dns.GetHostEntryAsync(ip)).HostName;
    如果(!string.IsNullOrWhitespace(主机))
    {
    hosts[ip]=主机;
    }
    }
    抓住
    {
    返回;
    }
    },
    新的ExecutionDataflowBlockOptions{MaxDegreeOfParallelism=5000});
    
    • 我还建议添加一个缓存,并确保不会多次解析同一ip

    • 当您使用.net的
      Dns
      类时,它在Dns(例如LLMNR)旁边包含一些回退,这使得它非常慢。如果您所需要的只是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});