Spark範例:統計CSDN不同郵箱的密碼白癡指數

前年的文章,備份

spark編寫了一段統計CSDN中不同郵箱的密碼白癡程序,數據來源於最近被公佈的csdn明文數據,以下代碼重點是spark在編程性上的體驗,性能上比較沒有意思,這點數據單機都能計算,計算結果僅供娛樂。 感謝CSDN提供這麼好的數據樣本

目前網上能找到的spark範例很少,這個算是掃盲吧。寫這段代碼過程順便也熟悉了scala的各種寫法。

代碼主要分3部分:

1、白癡密碼的top分佈

2、白癡密碼指數化,並封裝成廣播變量

3、計算郵箱的密碼白癡程度。

主要用到了spark的廣播變量,例子中使用P2P的廣播方式。

在做collect前做下filter,減少返回的數據量。這裏默認過濾掉重複率1000以下的郵箱,同時認爲重複率1000以上的爲白癡密碼,重複率越高,白癡程度越高。PS:本來是想計算出每個郵箱白癡密碼佔的比例,但是白癡密碼的界限很難設定,重複率100W和1000的還是有區別的,所以用權重的方式,就是將其指數化。

主要用到了map,filter,reduceByKey,broadcast, 目前對spark瞭解程序還不夠,這個實現並不一定是最好的解決方案,也歡迎討論。PS:開始實現了一個更爛的。

直接給代碼。(> 就是 >)

import spark.SparkContext
import org.slf4j.Logger
import org.slf4j.LoggerFactory
import SparkContext._
import scala.collection.mutable.HashMap
 
object CSDNPassword {
  val log = LoggerFactory.getLogger("CSDNPassword");
  def main(args: Array[String]) {
    System.setProperty("spark.broadcast.factory", "spark.broadcast.BitTorrentBroadcastFactory")
    val spark = new SparkContext(args(0), "CSDNPassword", null, Array(args(1)))
 
    val slices = if (args.length > 2) args(2).toInt else 2
    log.info("spark.slices :" + slices)
 
    val file = spark.textFile(args(3), slices).filter(_.contains("@"))
 
    val passwords = file.map { user =>
      val user_s = user.split("#")
      val pw = user_s(1).trim()
      if (pw.length() > 5) (pw, 1) else ("Nil", 0)
    }
 
    val passwordLimit = if(args.length > 4) args(4).toInt else 1000
    val mailLimit = if(args.length > 5) args(5).toInt else 1000
 
    val passwordModel = passwords.reduceByKey(_ + _)
    val filePassoword = passwordModel.filter(_._2 > passwordLimit)//收集出現超過passwordLimit的密碼
    val passwordCollect = filePassoword.collect();    
 
    /**
     * 白癡密碼指數化,(count*1000)/max
     */
    val zhishu = 1000
    val passwordMap = new HashMap[String, Int]()
    val sortPassword = passwordCollect.sortWith((A, B) => A._2 > B._2)
    val max = sortPassword(0)._2
 
    passwordMap += (sortPassword(0)._1 -> zhishu)
    for (i <- 1 to sortPassword.length - 1) {       val weight = (sortPassword(i)._2 * zhishu) / max             passwordMap += (sortPassword(i)._1 -> weight)
    }
    //包裝成廣播變量, 提供給所有work使用
    val passwordMapBro = spark.broadcast(passwordMap)
    log.info("---------------------create broadcast-------------------------")
 
    /////////////////////////////////////////////////////////////////
    val users2 = file.map{ user =>
      val user_s = user.split("#")
      val pw = user_s(1).trim()
      val weight = passwordMapBro.value.getOrElse(pw, 0)//得到密碼白癡程序
      val user2_s = user.split("@")
      if (pw.length() > 5 && user2_s.length > 1) (user2_s(1).toLowerCase(), (1, weight)) else ("Nil",(0,  0))
    }
 
    val user2ReduceByKey = users2.reduceByKey{(a,b)=>
      (a._1 + b._1, a._2 + b._2)
    }
    val yes = user2ReduceByKey.filter(_._2._1 > mailLimit).map{user =>  //過濾出超過mailLimit的郵箱
      (user._1, user._2._2/user._2._1) //除以基數
    }
    //收集,排序
    val arrays = yes.collect()
    val sortMail = arrays.sortWith((A, B) => A._2 > B._2)
    val len = if(sortMail.length > 100) 100 else sortMail.length
    for (i <- 0 to len -1) {
      log.info(i + " mail:" + sortMail(i)._1 + ", 密碼白癡程度:" + sortMail(i)._2)
    }
    spark.stop()
  }
}

計算結果如圖:

統計結果僅供娛樂。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章