MaxCompute分析IP来源最佳实践

MaxCompute分析IP来源最佳实践

本文章主要介绍使用MaxCompute分析IP(示例数据)来源,主要包括四个步骤:

  1. IP地址库数据下载
  2. 表创建与数据上传
  3. 编写Java UDF函数
  4. 使用UDF编写SQL

这里和官方文档的不同在于,使用了Java来实现MaxCompute的UDF,并且使用MaxCompute Studio来进行函数资源的上传和创建(MaxCompute Studio工具的使用见:MaxCompute Studio数据开发工具的使用 ),如果使用DataWorks和PyUDF来进行实现,具体参见这部分MaxCompute文档:使用MaxCompute分析IP来源最佳实践

IP地址库数据下载

获取MaxCompute提供的示例IP地址库数据UTF8格式的不完整的地址库demo,示例如下:

16834560,16834623,"1.0.224.0","1.0.224.63","泰国","普吉府","","","TOT"
16834624,16834815,"1.0.224.64","1.0.224.255","泰国","","","","TOT"
16834816,16835071,"1.0.225.0","1.0.225.255","泰国","普吉府","","","TOT"
16835072,16835199,"1.0.226.0","1.0.226.127","泰国","","","","TOT"
16835200,16841471,"1.0.226.128","1.0.250.255","泰国","普吉府","","","TOT"
...
  • 数据格式为UTF-8。
  • 前四个数据是IP地址的起始地址与结束地址。前两个是十进制整数形式,后两个是点分形式。IP地址段为整数形式,以便计算IP是否属于这个网段。

表创建与数据上传

1. 在MaxCompute Studio中创建SQL script脚本文件,执行如下语句创建表ipresource存放IP地址库数据:

DROP TABLE IF EXISTS ipresource ;

CREATE TABLE IF NOT EXISTS ipresource 
(
    start_ip BIGINT
    ,end_ip BIGINT
    ,start_ip_arg string
    ,end_ip_arg string
    ,country STRING
    ,area STRING
    ,city STRING
    ,county STRING
    ,isp STRING
);

2.  打开MaxCompute客户端odpscmd,执行如下Tunnel命令将本地示例IP地址库数据上传至表ipresource中:

odps@ YITIAN_BJ_MC>tunnel upload /Users/yitian/Documents/MaxCompute/maxcompute-data/ipdata.txt.utf8 ipresource;
Upload session: 202004241706000d47df0b1a8dbb4a
Start upload:/Users/yitian/Documents/MaxCompute/maxcompute-data/ipdata.txt.utf8
Using \r\n to split records
Upload in strict schema mode: true
Total bytes:1805         Split input to 1 blocks
2020-04-24 17:06:00     scan block: '1'
2020-04-24 17:06:00     scan block complete, block id: 1
2020-04-24 17:06:00     upload block: '1'
2020-04-24 17:06:01     upload block complete, block id: 1
upload complete, average speed is 1.8 KB/s
OK

上述命令中,/Users/yitian/Documents/MaxCompute/maxcompute-data/ipdata.txt.utf8为IP地址库数据本地存放路径。更多命令说明请参见Tunnel命令

执行如下语句验证数据是否上传成功:

-- 查询表中数据条数
select count(*) from ipresource;
-- 返回结果
_c0
+----+
23

3. 执行如下SQL语句查看表ipresource前10条的样本数据。

select * from ipresource limit 10;

返回结果如下:

编写Java UDF函数

下面编写Java UDF,将点号分割的IP地址转化为整数类型的IP地址。编写的步骤如下:

  1. 创建MaxCompute Java Module(详见:MaxCompute数据开发快速入门 )
  2. 创建Java UDF
  3. 编写代码
  4. 打包并上传UDF资源
  5. 根据资源创建UDF函数

1. 在新创建的UDF文件中编写如下代码,该代码的功能为:将点式的IP地址转换为整形的IP地址。

public class IpIntegerTransformer extends UDF {
    // TODO define parameters and return type, e.g:  public String evaluate(String a, String b)
    public String evaluate(String ip) {
        String ipNew = ip.replace("\"", "");
        String[] ipStr = ipNew.split("\\.", -1);
        
        long result = 0;
        result += Long.parseLong(ipStr[0]) << 24;
        result += Long.parseLong(ipStr[1]) << 16;
        result += Long.parseLong(ipStr[2]) << 8;
        result += Long.parseLong(ipStr[3]);
        
        return String.valueOf(result);
    }
}

这种转换的原理为:ip地址的每段可以看成是一个0-255的整数,把每段拆分成一个二进制形式,然后按照位置顺序将二进制组合起来,最后得到拼接后的二进制数转变成整数即可。举例:一个ip地址为10.0.3.193,每段数字和相对应的二进制数:
 10                   00001010
  0                    00000000
  3                    00000011
 193                 11000001
组合起来即为:00001010 00000000 00000011 11000001,转换为10进制数就是:167773121。

 使用UDF的测试功能,对该方法进行测试:

上面的运行配置中,将ipresource中的start_ip_arg列中的数据,作为测试数据运行该UDF,运行结果如下: 

16834560
16834624
16834816
16835072
16835200
16841472
16841600
16841664
16841728
16842240
16842272
16842304
16842368
16842384
16842400
16842432
16842624
16842752
16843008
16843264
16844800
16845056
16910592

可见,该UDF的运行结果与示例数据中第一列的值相同,因此该方法可以将点式IP地址,转换为整形IP地址。 

2. UDF资源的打包和上传。

右击刚才创建的IpIntTransfromer文件,选择Deploy to server:

3. 根据资源创建UDF函数:

 

使用UDF编写SQL

完成上述的UDF的打包,上传和创建之后,就可以在SQL Script中使用该UDF,编写sql。

示例1:查询start_ip小于1.2.24.2并且end_ip大于1.2.24.2的IP地址:

select *
from ipresource
where ipint_transformer('1.2.24.2') >= start_ip
and ipint_transformer('1.2.24.2') <= end_ip;

返回结果如下:

start_ip	end_ip	start_ip_arg	end_ip_arg	country	area	city	county	isp
+---------+-------+-------------+-----------+--------+-----+-----+-------+----+
16910592	16941055	"1.2.9.0"	"1.2.127.255"	"中国"	"广东省"	"广州市"	""	"电信"

示例2:查找start_ip大于1.1.0.0,end_ip小于1.1.255.255的IP地址,即:网段范围在1.1.0.0和1.1.255.255之间的IP地址:

select *
from ipresource
where ipint_transformer('1.1.0.0') <= start_ip
and ipint_transformer('1.1.255.255') >= end_ip;

返回结果如下:

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值