使用 Azure 数据湖分析将 IP 映射到位置

Map IP to Location with Azure data lake analytics

我有很多带有 IP 的 avro 文件(网络日志)存储在 Azure Blob 中。我想将 IP 映射到位置。如何使用 Azure 数据湖分析 (ADLA) 做到这一点?

现在我有一个 spark 作业,它使用 Maxmind IP 数据库和一个 java 库,该库读取一个 113MB 的大 .mmdb 文件,其中包含所有 ip 位置数据来执行此查找。我现在正在调查是否可以将这份工作移交给 ADLA

Maxmind也提供了一个c#库,所以这部分没问题。但是,我不清楚如何处理这个需要读取然后用于查找的大 mmdb 文件。显然,为每个 IP 查找读取文件不会很快。如何使用 ADLA 处理这种情况(以及类似情况),或者 ADLA 是否不适合此类操作?

如果我有一个正常的程序运行,我会像这样进行查找:

using (var reader = new Reader("GeoIP2-City.mmdb"))
{
    foreach(var ip in ips)
    {
        var data = reader.Find<Dictionary<string, object>>(ip);
        ...
    }
}

maxmind 数据库可在此处获得:https://dev.maxmind.com/geoip/geoip2/downloadable/(请注意,我已经购买了我当前使用的数据库) 和 c# 库在这里阅读它:https://github.com/maxmind/MaxMind-DB-Reader-dotnet

您可以为此目的使用 U-SQL 的 DEPLOY RESOURCE 语句和 UDO。

首先,必须将文件上传到您的数据湖存储区。然后使用 DEPLOY RESOURCE 告诉 U-SQL 系统将该文件复制到脚本运行的每个顶点。然后您的脚本使用 C# 代码读取文件。

DEPLOY RESOURCE "/helloworld.txt";

@departments =
  SELECT * 
  FROM (VALUES
      (31, "Sales"),
      (33, "Engineering"),
      (34, "Clerical"),
      (35, "Marketing")
    ) AS D( DepID, DepName );


@departments =
     PROCESS @departments
     PRODUCE DepID int,
             DepName string,
             HelloWorld string
     USING new Demo.HelloWorldProcessor();

OUTPUT @departments 
    TO "/departments.tsv"
    USING Outputters.Tsv();

这里是 U-SQL 处理器 UDO。

using Microsoft.Analytics.Interfaces;
using Microsoft.Analytics.Types.Sql;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;

namespace Demo
{
    [SqlUserDefinedProcessor]
    public class HelloWorldProcessor : IProcessor
    {
        private string hw;

        public HelloWorldProcessor()
        {
            this.hw = System.IO.File.ReadAllText("helloworld.txt");
        }

        public override IRow Process(IRow input, IUpdatableRow output)
        {
            output.Set<int>("DepID", input.Get<int>("DepID"));
            output.Set<string>("DepName", input.Get<string>("DepName"));
            output.Set<string>("HelloWorld", hw);
            return output.AsReadOnly();
        }
    }
}