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;
返回結果如下: