MaxCompute分析IP来源最佳实践
本文章主要介绍使用MaxCompute分析IP(示例数据)来源,主要包括四个步骤:
- IP地址库数据下载
- 表创建与数据上传
- 编写Java UDF函数
- 使用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地址。编写的步骤如下:
- 创建MaxCompute Java Module(详见:MaxCompute数据开发快速入门 )
- 创建Java UDF
- 编写代码
- 打包并上传UDF资源
- 根据资源创建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;
返回结果如下: