package com.day_215
import org.apache.spark.{SparkConf, SparkContext}
object IPLocation {
//*****************************将传进来的数转换成10进制的数
def ip2Long(ip: String): Long = {
val fragments = ip.split("[.]")
var ipNum = 0L
for (i <- 0 until fragments.length){
ipNum = fragments(i).toLong | ipNum << 8L
}
ipNum
}
//*****************************8二分查找
def binarySearch(lines: Array[(String, String, String)], ip: Long) : Int = {
var low = 0
var high = lines.length - 1
while (low <= high) {
val middle = (low + high) / 2
if ((ip >= lines(middle)._1.toLong) && (ip <= lines(middle)._2.toLong))
return middle
if (ip < lines(middle)._1.toLong)
high = middle - 1
else {
low = middle + 1
}
}
-1
}
def main(args: Array[String]): Unit = {
//***********广播变量(关键词:broadcast())的思路是:
//1、先将字典表读进来放到每个work中的executor中;进行筛选计算
//2、用collect()算子将最后结果集中到Dirver端
//3、再从dirver端将字典表广播出去
//4、在读取要查找的ip 并转换成十进制数
//5、将ip和字典表 放到二分查找的方法中,查到ip在字典表中的index
//6、把index放到广播变量中查找index上的ip所对应的地址
val conf=new SparkConf().setAppName("Order").setMaster("local[2]")
val sc=new SparkContext(conf)
sc.setLogLevel("ERROR")
//读取字典表中的数据 并把数据进行广播 字典内容: 1.0.1.0|1.0.3.255|16777472|16778239|亚洲|中国|福建|福州||电信|350100|China|CN|119.306239|26.075302
val ipRDD=sc.textFile("F:\\vm\\老師錄屏\\stage4 大数据流式数据分析scala和spark和kafka和sparkstream\\线上教学的资料及录屏\\线上第六天 广播变量完整版\\ip.txt").map(lines=>{
val fields=lines.split("[|]")
val startNum=fields(2)
val endNum=fields(3)
val privence=fields(6)
(startNum,endNum,privence)
})
val ipRulesArr=ipRDD.collect() //将分散的字典表集中到dirver端
val ipBrocast=sc.broadcast(ipRulesArr) //广播出去
//加载数据
val ip=sc.textFile("F:\\vm\\老師錄屏\\stage4 大数据流式数据分析scala和spark和kafka和sparkstream\\线上教学的资料及录屏\\线上第六天 广播变量完整版\\20090121000132.394251.http.format").map(lines=>{
val fields=lines.split("[|]")
(fields(1))
})
val res=ip.map(ip=>{
val ipNum=ip2Long(ip) //将ip转换成十进制数
val index=binarySearch(ipRulesArr,ipNum) //查找ip在字典表中的index
val info=ipBrocast.value(index)._3 //将index放到广播中查找名称
info
})
// println(res.collect.toBuffer)
//求出次数最多的三个省
val wordcountip = res.map((_,1)).reduceByKey(_+_).sortBy(_._2,false).take(3)
println(wordcountip.toBuffer)
sc.stop()
}
}
运用广播变量(关键词:broadcast())查找每个ip所对应的地址,以及每个地址出现的频率;int转十进制的方法;二分查找的方法
猜你喜欢
转载自blog.csdn.net/qq_44472134/article/details/104346451
今日推荐
周排行