spark 通过ip地址查询所在地(JAVA版)

spark streaming 通过ip地址查询所在地(JAVA版)


前言

最近项目有一个用户地域分析的需求,现在知道ip字段,需要在spark中通过用户的ip查找归属地,我们这里将ip直接转换成对应城市的字符串

首先我们需要一份ip库,字段格式如下:

1.0.1.0|1.0.3.255|16777472|16778239|亚洲|中国|福建|福州||电信|350100|China|CN|119.306239|26.075302
1.0.8.0|1.0.15.255|16779264|16781311|亚洲|中国|广东|广州||电信|440100|China|CN|113.280637|23.125178
1.0.32.0|1.0.63.255|16785408|16793599|亚洲|中国|广东|广州||电信|440100|China|CN|113.280637|23.125178

关于定位在这里我们只需要精确到城市,所以只需要三个字段,ip地址起始值和结束值,还有对应的城市,startip、stopip、city,分别对应3、4、8行

字段对应列数
startip3
stopip4
city8

准备工作

ip库是从淘宝买的,csdn下载地址放在末尾,首先将我们的文件上传到hdfs上

su hdfs
hadoop fs -put ip.txt /user/ip.txt

上传之后的/user/目录


代码时间

下面上代码,首先读取hdfs上ip表,因为ip表可能不全,所以去掉了空值的情况

        // java spark context
        JavaSparkContext jsc = new JavaSparkContext(sparkConf);
        // spark streaming context
        JavaStreamingContext ssc = new JavaStreamingContext(jsc, Durations.milliseconds(4000));
        ssc.checkpoint("/checkpoint");

        ... ...

        List<String> ipCollect = jsc.textFile("hdfs://master:8020/user/ip.txt").collect();
        List<String[]> ipList = new ArrayList<>();
        try {
            for (String line : ipCollect) {
                if (!"".equals(line)) {
                    String[] split = line.split("\\|");
                    if (split[2] != null && split[3] != null && split[7] != null) {
                        String[] ipSection = new String[3];
                        ipSection[0] = split[2];
                        ipSection[1] = split[3];
                        ipSection[2] = split[7];
                        ipList.add(ipSection);
                    }

                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }

然后读取ip表中的数据,将ip表注册成广播

filtered_data.foreachRDD(new VoidFunction2<JavaRDD<Map<String, Object>>, Time>() {
            @Override
            public void call(JavaRDD<Map<String, Object>> rdd, Time time) throws Exception {
            // Get or register the ip Broadcast
            final Broadcast<List<String[]>> ipArray = JavaWordIp.getInstance(new JavaSparkContext(rdd.context()));

             JavaRDD<Row> rowRDD = rdd.map(x -> {
                    try {
                        String ip = "ip";
                        if (x.get(ip) != null || IpUtil.isIpAddress(x.get(ip).toString())) {
                            Long l = IpUtil.ip2long(x.get(ip).toString());
                            String region = IpUtil.binarySearch(ipArray.value(), l);
                            x.put(ip, region);
                        }
                        return x;
                    } catch (Exception e) {
                        System.err.println("error process:  ipJavaRDD" + e.getMessage());
                        throw e;
                    }
                });

这里使用的是二分法查找,具体的代码可以在我的github上下载

下载链接

ip表的数据
http://download.csdn.net/download/qq392039757/10151360

工具类代码
https://github.com/xingzhicn/sparkip

参考代码

http://blog.csdn.net/tianjun2012/article/details/55050144
https://github.com/lionsoul2014/ip2region

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值