hive ip解析


Hive 自定義udf --ip地址解析出歸屬地

1.問題背景:現在我們的流量表里存有用戶的IP地址,有需求需要將ip地址的歸屬地解析出來。結構是 國家-省份-城市-運營商

2.目前使用的是開源的ip庫,調用三方接口不太適合hive udf使用並且都是收費的。

3.開源數據庫調研了純真數據庫 發現ip地址解析的結果誤差比較大,並且返回的結構不太友好。后來使用的是一個開源項目ip2region 。具體介紹可以看下該項目的gitee地址。ip2region 這個數據庫大概有70萬條,比純真的數據庫要全面,並且返回結果的結構比較統一 (_城市Id|國家|區域|省份|城市|ISP_)非常有利於我們進行結果的改造。

4.使用該數據庫

1.首先將數據庫下載下來,在該項目data 目錄下ip2region.db ,放到hdfs上

2.編寫udf 函數

1.pom中引入

<dependency>
   <groupId>org.lionsoul</groupId>
   <artifactId>ip2region</artifactId>
   <version>1.7.2</version>
</dependency>

<dependency>
	<groupId>org.apache.hive</groupId>
    <artifactId>hive-exec</artifactId>
    <version>2.1.1</version>
    <scope>provided</scope>
 </dependency>
 <dependency>
    <groupId>org.apache.hadoop</groupId>
    <artifactId>hadoop-common</artifactId>
    <version>2.7.3</version>
    <scope>provided</scope>
 </dependency>
 <dependency>
     <groupId>org.apache.hadoop</groupId>
     <artifactId>hadoop-hdfs</artifactId>
     <version>2.7.3</version>
     <scope>provided</scope>
</dependency>

2.udf

public class Ip2region extends UDF {
    private static Configuration configuration;
    private static FileSystem fileSystem;
    private static InputStream in;

    private static byte[] data;
    static {
        //加載數據
        ByteArrayOutputStream out = null;
        try {
            configuration = new Configuration();
            fileSystem = FileSystem.get(URI.create("hdfs:///jars/hive/ip2region.db"), configuration);
            in = fileSystem.open(new Path("hdfs:///jars/hive/ip2region.db"));
            out = new ByteArrayOutputStream();
            byte[] b = new byte[1024];
            while (in.read(b) != -1) {
                out.write(b);
            }
            // 提高性能,將ip2region.db一次從hdfs中讀取出來,緩存到data字節數組中以重用,
            // 避免每來一條數據讀取一次ip2region.db
            data = out.toByteArray();
            out.close();
            in.close();
        } catch (Exception e){
            e.printStackTrace();
        }
        finally {
            try {
                if(out != null) {
                    out.close();
                }
                if(in != null) {
                    in.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

    }
    public String evaluate(String ip) throws Exception{
        DbConfig config = new DbConfig();
        DbSearcher searcher = new DbSearcher(config,data);
        DataBlock dataBlock = searcher.memorySearch(ip);
        String[] split = dataBlock.getRegion().split("\\|");
        String addr = convert(split[0])+","+convert(split[2])+","+convert(split[3])+","+convert(split[4]);
        return addr;
    }
    public String convert (String addr) {
        return addr.equals("0") ? "" :addr;
    }

}

3.打包 需要將ip2region 依賴打入到寫的udf中

<build>
        <finalName>hive-udf-ip2region</finalName>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>2.3.2</version>
                <configuration>
                    <source>1.8</source>
                    <target>1.8</target>
                    <encoding>UTF-8</encoding>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-assembly-plugin</artifactId>
                <version>2.3</version>
                <configuration>
                    <descriptorRefs>
                        <descriptorRef>jar-with-dependencies</descriptorRef>
                    </descriptorRefs>
                </configuration>
                <executions>
                    <!--打包的插件配置-->
                    <execution>
                        <id>make-assembly</id>
                        <phase>package</phase>
                        <goals>
                            <goal>assembly</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>

5.使用udf函數

 

將ip庫和 udf的jar 都傳到hdfs上

進入hive

add jar hdfs:///jars/hive/hive-udf-ip2region-jar-with-dependencies.jar;
create temporary function ip2region as 'com.hive.udf.Ip2region';
select ip2region('124.236.223.17');

6.注意:如果ip庫必須傳到hdfs 上,否則分布式跑的時候其他節點會加載不到改數據庫


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM