日志分析实战之清洗日志小实例6:获取uri点击量排序并得到最高的url

问题导读 1.读取日志的过程中,发生异常本文是如何解决的? 2.读取后,如何过滤异常的记录? 3.如何实现统计点击最高的记录? 日志分析实战之清洗日志小实例5:实现获取不能访问url http://www.aboutyun.com/forum.php?mod=viewthread&tid=22911 下面我们开始统计链接的点击量,并做排序。 我们统计记录的时候,为了防止空记录等异常的情况,我们创建一条空记录

[Bash shell] 纯文本查看 复制代码

?

val nullObject = AccessLogRecord("", "", "", "", "GET /foo HTTP/1.1", "", "", "", "")

下面我们开始找点击量最高的链接。 首先获取我们想要的uri

[Scala] 纯文本查看 复制代码

?

val uriCounts = log.map(p.parseRecord(_).getOrElse(nullObject).request)
                  .map(_.split(" ")(1))
                  .filter(_ != "/foo")

上面的代码做一个简单解释: p.parseRecord(_)解析记录 p.parseRecord(_).getOrElse(nullObject)如何没有取到值,则使用nullObject,也就是我们上面定义的对象 p.parseRecord(_).getOrElse(nullObject).request也就是我们取到uri .map(_.split(" ")(1))是取到我们过滤的url,过滤掉不想要的版本等信息 .filter(_ != "/foo")则是再次过滤掉/foo[也就是空记录] 这样就获取了uri,然后我们输出

[Scala] 纯文本查看 复制代码

?

uriCounts.collect.foreach(print)

下面我们统计点击量

[Scala] 纯文本查看 复制代码

?

val uriCounts = log.map(p.parseRecord(_).getOrElse(nullObject).request)
                  .map(_.split(" ")(1))
                  .map(uri => (uri, 1))
                  .reduceByKey((a, b) => a + b)

rdd转换为数组

[Scala] 纯文本查看 复制代码

?

val uriToCount = uriCounts.collect

数组转换为序列并排序

[Scala] 纯文本查看 复制代码

?

import scala.collection.immutable.ListMap
val uriHitCount = ListMap(uriToCount.toSeq.sortWith(_._2 > _._2):_*)

############################# 这里留下一个问题,如果上面元素不是2,而是为sortWith(_._1 > _._1)是对什么排序

[Scala] 纯文本查看 复制代码

?

import scala.collection.immutable.ListMap
val uriHitCount = ListMap(uriToCount.toSeq.sortWith(_._1 > _._1):_*)

#############################

输出

[Scala] 纯文本查看 复制代码

?

uriHitCount.take(10).foreach(println)

上面便是排序的结果 点击最高的uri 如果想得出点击最高的uri

[Scala] 纯文本查看 复制代码

?

uriHitCount.take(1).foreach(println)

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 知识补充: Scala代码看上去很少,但是内容却是很丰富的。上面用到的相关知识,这里补充,供大家能看懂上面代码 getOrElse: println(a.get("k1").getOrElse("default")) //根据key读取元素,不存在就替换成默认值 在Spark中写法是:persons.getOrElse("Spark",1000) //如果persons这个Map中包含有Spark,取出它的值,如果没有,值就是1000。 reduce、reduceByKey reduce(binary_function) reduce将RDD中元素前两个传给输入函数,产生一个新的return值,新产生的return值与RDD中下一个元素(第三个元素)组成两个元素,再被传给输入函数,直到最后只有一个值为止。

[Scala] 纯文本查看 复制代码

?

val c = sc.parallelize(1 to 10)
c.reduce((x, y) => x + y)//结果55

具体过程,RDD有1 2 3 4 5 6 7 8 9 10个元素, 1+2=3 3+3=6 6+4=10 10+5=15 15+6=21 21+7=28 28+8=36 36+9=45 45+10=55 reduceByKey(binary_function) reduceByKey就是对元素为KV对的RDD中Key相同的元素的Value进行binary_function的reduce操作,因此,Key相同 的多个元素的值被reduce为一个值,然后与原RDD中的Key组成一个新的KV对。 val a = sc.parallelize(List((1,2),(1,3),(3,4),(3,6))) a.reduceByKey((x,y) => x + y).collect //结果 Array((1,5), (3,10)) Seq Sequence都有一个预定义的顺序。 scala> Seq(1, 1, 2) res3: Seq[Int] = List(1, 1, 2) (注意返回的结果是一个List。Seq是一个trait;List是它的一个实现类。Seq对象是一个工厂对象,正如你所看到 的,它会创建一个List。) 集合之间可以相互进行转换。 def toArray : Array[A] def toArray [B >: A] (implicit arg0: ClassManifest[B]) : Array[B] def toBuffer [B >: A] : Buffer[B] def toIndexedSeq [B >: A] : IndexedSeq[B] def toIterable : Iterable[A] def toIterator : Iterator[A] def toList : List[A] def toMap [T, U] (implicit ev: <:<[A, (T, U)]) : Map[T, U] def toSeq : Seq[A] def toSet [B >: A] : Set[B] def toStream : Stream[A] def toString () : String def toTraversable : Traversable[A] 我们可以把一个Map转换成一个数组,然后得到一个键值对数组。 scala> Map(1 -> 2).toArray res41: Array[(Int, Int)] = Array((1,2)) sortWith 排序操作(sorted, sortWith, sortBy)根据不同的条件对序列元素进行排序。更多排序内容推荐参考 Scala的map实现key和value排序及各种排序比较等知识讨论 http://www.aboutyun.com/forum.php?mod=viewthread&tid=22942

原文发布于微信公众号 - about云(wwwaboutyuncom)

原文发表时间:2017-10-21

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏技术点滴

编译器构造

编译器构造 一、 编译器简介 前面谈到静态链接器构造的基本流程,最后提到所构造的链接器若要能正常工作的前提是需要构造一个能生成符合链接器输入文件格式的编译器,本...

2528
来自专栏Java后端技术栈

那些鲜为人知的序列化和反序列化底层实现原理!

序列化和反序列化作为Java里一个较为基础的知识点,大家心里也有那么几句要说的,但我相信很多小伙伴掌握的也就是那么几句而已,如果再深究问一下Java如何实现序列...

842
来自专栏从零开始学自动化测试

python笔记14-读取yaml配置文件

yaml简介 1.yaml [ˈjæməl]: Yet Another Markup Language :另一种标记语言。yaml 是专门用来写配置文件的语言,...

5778
来自专栏我是业余自学C/C++的

redis_3.0.7_sds.c_sdsempty_so_on

1043
来自专栏编程

Python入门白皮书#P01 Lists

文档: 我们以Google Python Exercises作为练习素材。 参考对应的文档 https://developers.google.com/edu/...

2026
来自专栏编程心路

想学习php的,不如来这里看看

win+R打开命令行,cmd进DOS窗口 DOS命令开启关闭Apache和Mysql Apache启动关闭命令

1253
来自专栏大内老A

ModelBinder——ASP.NET MVC Model绑定的核心

Model的绑定体现在从当前请求提取相应的数据绑定到目标Action方法的参数。通过前面的介绍我们知道Action方法的参数通过ParameterDescrip...

2359
来自专栏用户2442861的专栏

Python基础学习笔记之(二)(华工大神)

         Python中每一个.py脚本定义一个模块,所以我们可以在一个.py脚本中定义一个实现某个功能的函数或者脚本,这样其他的.py脚本就可以调用...

1214
来自专栏行者悟空

Spark的共享变量

1414
来自专栏数据科学

redis流计算

使用了tornado的异步和streamz的流处理两个库,需要redis 5.0以上版本

2265

扫码关注云+社区

领取腾讯云代金券