spark-topN问题

业务场景 统计ip

加载hdfs数据文件

统计出现频率前N的ip

Spark实例TopN—Spark学习笔记11

正则表达式基础知识

String 类的 r() 方法构造了一个Regex对象。

然后使用 findFirstIn 方法找到首个匹配项。

如果需要查看所有的匹配项可以使用 findAllIn 方法。

Scala 的正则表达式继承了 Java 的语法规则,Java 则大部分使用了 Perl 语言的规则

可以使用 mkString( ) 方法来连接正则表达式匹配结果的字符串,并可以使用管道(|)来设置不同的模式:

1
2
3
val pattern = "Scala".r
val str = "Scala is Scalable and cool"
println(pattern findFirstIn str)

构造ip正则表达式

对于大量转义字符及换行的字符串可以使用三个双引号
简单的正则表达式
((\d+.){3}\d+)
正则是没有办法做数字运算的,如何表示范围?分析ip地址规律,按不同情况分组再组合
((25[0-5]|2[0-4]\d|((1\d{2})|([1-9]?\d))).){3}(25[0-5]|2[0-4]\d|((1\d{2})|([1-9]?\d)))

IP地址的正则表达式写法

如果内容比较复杂,正则表达式可能会匹配冗余内容

1
2
3
var data = sc.textFile("hdfs://toshiba:9000/user/xiaohei/hadoop/access.20120104.log")
var top50 = data.map(line => """(\d+\.){3}\d+""".r.findFirstIn(line).mkString).filter(_!="").map(word => (word,1)).reduceByKey(_+_).map(word=>(word._2,word._1)).sortByKey(false).map(word=>(word._2,word._1)) take 50
top50.foreach(x => println(x))

利用元组位置

1
2
3
4
5
var data = sc.textFile("hdfs://toshiba:9000/user/xiaohei/hadoop/access.20120104.log")
var top10 = data.map(_.split(" ")).map(line => (line(0),1)).reduceByKey(_+_).map(word => (word._2,word._1)).sortByKey(false).map(word => (word._2,word._1)) take 10
top10.foreach(x => println(x))

代码注解

line(0) 表示元组第一个元素

sortByKey(flase)代表逆序 sortByKey 默认值是sortByKey(true)代表升序

将map的k,v互换,变成(value, IP) 这样才能利用sortByKey排序找出top的IPs

互换两次则回原来的格式

引出问题

如何根据value 进行排序?

1
2
3
sortBy(_._x,flase) # 根据元组的第x字段进行排序
var top20 = data.map(_.split(" ")).map(line => (line(0),1)).reduceByKey(_+_).sortBy(_._2,false) take 20
top20.foreach(x => println(x))