数仓建设之IP库的匹配

一、业务前提

       介绍:在数据仓库建设中,用到IP库匹配的场景不在少数,比如电商行业用户地址、通信行业用户定位、媒体行业用户分布等等。

【历史】:在此之前的实现思路如下:
1)通过自定义UDF读取使用tunnel来读取odps中的ip信息表
2)然后将读取的信息封装或者直接写入一个list中
3)对数据按照ip的{start_ip,end_ip}进行全局排序。【此处start_ip和end_ip都是转化为long类型之后的值】
4)设置udf的传入参数为ip地址,返回具体的国省市信息

【现在】:由于某些原因,之前的IP库信息不全,所以采取了新型的IP库,旧IP库信息大概50万条数据,新IP库扩到了1400万条数据。发生了如下几个问题:
1)IP库信息扩大,使用tunnel读取数据时间增加,导致tunnel连接数居高不下,影响其他同步任务以及调度任务、前端查询任务
2)数据量太大,经常发生内存不足的报错,或者是运行时间太长,占用资源不释放导致其他任务无法一直处于等待期

二、解决过程

01)增加运行资源

set odps.sql.planner.mode = lot;
set odps.sql.mapper.memory=10240;
set odps.sql.udf.jvm.memory=8192;
set odps.isolation.session.enable = true;

结果:任务运行后,可以正常执行,但是因为拉数据时启动tunnel实例数据量太多【tunnel实例数上限2500】引起了其他部门查询报错以及本部门其他任务调度等待时间超时报错。

02)通过增加切分块大小,减少实例数

set odps.sql.planner.mode = lot;
set odps.stage.mapper.split.size=256;
set odps.sql.mapper.memory=10240;
set odps.sql.udf.jvm.memory=8192;
set odps.isolation.session.enable = true;

结果:任务运行完成,本部门和其他部门也没有异常报出,但是任务执行时间较长,担心如果按这个逻辑上限会影响任务调度和下游数据产出。

03)明细表和ip库通过join方式

left join 
      (
        select * from project.ip_basic_info order by ip_start asc
      ) ips on UDF_IP_TO_INT(IP) BETWEEN IPS.IP_START AND UDF_IP_TO_INT(IP)

结果:任务执行超时,无法返回结果。因为不等式join会导致数据都分发到一个节点上执行,对于数十亿的数据这显然是不可取的。

04)mapjoin内存方式

结果:IP库数据量多达1400万,大小已达到1个G,无法作为hash table来存储到内存中,因为hash table的表大小为10M,切分表也不太现实,步骤繁琐,且后期不好维护。

05)将IP库展开,进行等式join

①将IP库信息的每一条数据进行展开如下

public String evaluate(LongWritable ip_start, LongWritable ip_end) {
    
    
        for(long i = ip_start.get();i<=ip_end.get();i++){
    
    
            builder.append(i+",");
        }
        return builder.substring(0,builder.length()-1);
    }

测试:
public static void main(String[] args) {
    
    
        Ip_to_Expand test = new Ip_to_Expand();
        LongWritable start = new LongWritable(3410411776l);
        LongWritable end = new LongWritable(3410412031l);
        test.evaluate(start,end);
    }
输出:3410411776,3410411777,3410411778,3410411779,3410411780,3410411781。。。。

②展开后,每个IP地址都对应一条国家省份城市信息,这样就可以避免范围匹配

③使用join等式连接

结果:在展开过程中,由于本身IP范围数据量庞大,一方面展开后数据量更为庞大,预估计可能超过明细表的数据,维度表的数据大于明细表的数据,方法也不可取。另外一方面在运行过程中,展开函数最终报错无法运行。

06)IP库作为资源

tunnel拉去数据较慢,所以将IP库信息切分为3个文件,上传到Odps中作为资源,下发给每个实例,省去tunnel资源

结论:目前正在测试中。。。

三、集思广益

        如果各位大大有什么好的思路和见解,欢迎在评论区讨论哈~~~不胜感激Thanks♪(・ω・)ノ

猜你喜欢

转载自blog.csdn.net/weixin_41998764/article/details/118863104