Hive UDF - 解析 IP 地址时非常慢

Posted

技术标签:

【中文标题】Hive UDF - 解析 IP 地址时非常慢【英文标题】:Hive UDF - exetremely slow when parsing IP addresses 【发布时间】:2021-09-08 11:22:56 【问题描述】:

我有一列包含 IP 地址。现在我需要将它们解析为国家/城市: select IPUtils('199.999.999.999') 并返回 ['Aisa', 'Hongkong', 'xxx', 'Hongkong']

我编写了一个 hive udf 来执行此操作,但运行速度极慢,如下所示:

INFO : 2021-09-08 18:51:10,817 Stage-2 map = 100%, reduce = 30%, Cumulative CPU 9074.06 sec

map = 100%reduce 的进度每 15 分钟增加 1%

UDF 从项目的资源文件夹中读取文件,所以它可能会一遍又一遍地重复读取文件? udf 如下所示,不胜感激:

public class IPUtil extends UDF 

    public List<String>  evaluate(String  ip)
        try
            ClassLoader classloader = Thread.currentThread().getContextClassLoader();

            // I put the mmdb file in resource folder of the java project
            InputStream is = classloader.getResourceAsStream("GeoLite2-City.mmdb");
            DatabaseReader reader = new DatabaseReader.Builder(is).build();

            InetAddress ipAddress = InetAddress.getByName(ip);
            CityResponse response = reader.city(ipAddress);
            Country country = response.getCountry();
            Subdivision subdivision = response.getMostSpecificSubdivision();
            City city = response.getCity();
            Continent continent = response.getContinent();

            List<String> list = new LinkedList<String>();

            list.add(continent.getNames().get("zh-CN"));
            list.add(country.getNames().get("zh-CN"));
            list.add(subdivision.getNames().get("zh-CN"));
            list.add(city.getNames().get("zh-CN"));

            return list;

         catch (UnknownHostException e) 
            e.printStackTrace();
            return null;
         catch (IOException e) 
            e.printStackTrace();
            return null;
         catch (GeoIp2Exception e) 
            e.printStackTrace();
            return null;
        
    

    @Test
    public void test()throws Exception
        System.out.println(evaluate("175.45.20.138"));
    

【问题讨论】:

这个`InputStream is = classloader.getResourceAsStream("GeoLite2-City.mmdb"); DatabaseReader reader = new DatabaseReader.Builder(is).build();` 可以移到构造函数中...但不会给您带来太大的改进。 嗨@leftjoin 你的回答启发了我!!!我试图将该部分放在一个静态块中,以确保 mmdb 文件仅在类初始化时加载一次。现在整个任务在 7 分钟内完成! 我添加了答案,如果它真的有用,你可以接受/投票 【参考方案1】:

移动这个

InputStream is = classloader.getResourceAsStream("GeoLite2-City.mmdb");
DatabaseReader reader = new DatabaseReader.Builder(is).build();

到类初始化。

【讨论】:

也可以考虑制作静态类变量。

以上是关于Hive UDF - 解析 IP 地址时非常慢的主要内容,如果未能解决你的问题,请参考以下文章

Hive UDF 对 URL 的处理

智能DNS

【性能】DNS 解析时快时慢,我该怎么办?

Hive UDF 在选择中抛出未找到类异常

hive 存储,解析,处理json数据

Spark Hive自定义函数使用解析