运用广播变量(关键词:broadcast())查找每个ip所对应的地址,以及每个地址出现的频率;int转十进制的方法;二分查找的方法

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()
  }
}

发布了64 篇原创文章 · 获赞 40 · 访问量 9520

猜你喜欢

转载自blog.csdn.net/qq_44472134/article/details/104346451