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;

返回結果如下:

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章