需求:
计算每个城市的访问量
ip.txt:
ipaccess.log:
解决:
1 package com.bigdata.spark.core.wc 2 3 import org.apache.spark.rdd.RDD 4 import org.apache.spark.{SparkConf, SparkContext} 5 6 object IpInfor { 7 def main(args:Array[String]):Unit={ 8 //创建Spark运行配置对象 9 val conf=new SparkConf() 10 conf.setMaster("local[1]") 11 conf.setAppName("ipInfor") 12 //创建Spark上下文环境对象(连接对象) 13 val sc=new SparkContext(conf) 14 15 val rdd1: RDD[String] = sc.textFile("E:\\user\\IDEA\\sparkt1\\datas\\ip.txt")//读取文件 --规则数据 16 val rdd2=sc.textFile("E:\\user\\IDEA\\sparkt1\\datas\\ipaccess.log")//读取文件 --日志数据 17 val rdd3= rdd2.map(_.split("\\|")(1)) //访问日志信息 通过"|"进行拆分 只要IP 18 val rdd4 = rdd1.map(a => { 19 //规则库数据,通过"|"截取第2-3-6 --小限度 -- 大限度 --省份 20 val splitData = a.split("\\|") 21 (splitData(2).toLong, splitData(3).toLong, splitData(6))//startIp endIp province 22 }) 23 //将rdd4的信息收集到本地 --收集的规则库数据 24 val ipReles: Array[(Long, Long, String)] = rdd4.collect() 25 26 //将IP地址和规则数据信息进行匹配 27 val res: RDD[Array[(Long, Long, String)]] = rdd3.map(a => { 28 val longIp = ip2Long(a) 29 ipReles.filter(b => { 30 longIp >= b._1 && longIp <= b._2 31 }) 32 }) 33 val provineRes = res.map(a => { 34 if (a == null || a.isEmpty) 35 ("无效数据", 1) 36 else 37 (a(0)._3, 1)//获取省份信息 省份 1 省份 1 省份 1 省份 1 38 }) 39 val finalRDD = provineRes.reduceByKey(_+_) 40 finalRDD.foreach(println) 41 42 } 43 //把IP转换成long类型的方法 125.213.100.123 ------> 2111136891 44 def ip2Long(ip: String): Long = { 45 val fragments = ip.split("[.]") 46 var ipNum = 0L 47 48 for (i <- 0 until fragments.length) { 49 ipNum = fragments(i).toLong | ipNum << 8L 50 51 } 52 val t2 = System.currentTimeMillis() 53 ipNum 54 } 55 }
结果: