• 售前

  • 售后

热门帖子
入门百科

详解如何使用Spark和Scala分析Apache访问日记

[复制链接]
贰十岁装成熟装s 显示全部楼层 发表于 2021-10-26 13:46:58 |阅读模式 打印 上一主题 下一主题
安装

首先须要安装好Java和Scala,然后下载Spark安装,确保PATH 和JAVA_HOME 已经设置,然后须要使用Scala的SBT 构建Spark如下:
  1. $ sbt/sbt assembly
复制代码
构建时间比力长。构建完成后,通过运行下面下令确证安装成功:
  1. $ ./bin/spark-shell
复制代码
  1. scala> val textFile = sc.textFile("README.md") // 创建一个指向 README.md 引用
  2. scala> textFile.count // 对这个文件内容行数进行计数
  3. scala> textFile.first // 打印出第一行
复制代码
Apache访问日志分析器

首先我们须要使用Scala编写一个对Apache访问日志的分析器,所幸已经有人编写完成,下载Apache logfile parser code。使用SBT进行编译打包:
  1. sbt compile
  2. sbt test
  3. sbt package
复制代码
打包名称假设为AlsApacheLogParser.jar。
然后在Linux下令行启动Spark:
  1. // this works
  2. $ MASTER=local[4] SPARK_CLASSPATH=AlsApacheLogParser.jar ./bin/spark-shell
复制代码
对于Spark 0.9,有些方式并不起效:
  1. // does not work
  2. $ MASTER=local[4] ADD_JARS=AlsApacheLogParser.jar ./bin/spark-shell
  3. // does not work
  4. spark> :cp AlsApacheLogParser.jar
复制代码
上传成功后,在Spark REPL创建AccessLogParser 实例:
  1. import com.alvinalexander.accesslogparser._
  2. val p = new AccessLogParser
复制代码
如今就可以像之前读取readme.cmd一样读取apache访问日志accesslog.small:
  1. scala> val log = sc.textFile("accesslog.small")
  2. 14/03/09 11:25:23 INFO MemoryStore: ensureFreeSpace(32856) called with curMem=0, maxMem=309225062
  3. 14/03/09 11:25:23 INFO MemoryStore: Block broadcast_0 stored as values to memory (estimated size 32.1 KB, free 294.9 MB)
  4. log: org.apache.spark.rdd.RDD[String] = MappedRDD[1] at textFile at <console>:15
  5. scala> log.count
  6. (a lot of output here)
  7. res0: Long = 100000
复制代码
分析Apache日志

我们可以分析Apache日志中404有多少个,创建方法如下:
  1. def getStatusCode(line: Option[AccessLogRecord]) = {
  2. line match {
  3.   case Some(l) => l.httpStatusCode
  4.   case None => "0"
  5. }
  6. }
复制代码
此中Option[AccessLogRecord]是分析器的返回值。

然后在Spark下令利用用如下:
  1. log.filter(line => getStatusCode(p.parseRecord(line)) == "404").count
复制代码
这个统计将返回httpStatusCode是404的行数。

深入挖掘

下面如果我们想知道哪些URL是有题目的,好比URL中有一个空格等导致404错误,显然须要下面步骤:
      
  • 过滤出所有 404 记录  
  • 从每个404记录得到request字段(分析器哀求的URL字符串是否有空格等)  
  • 不要返回重复的记录
创建下面方法:
  1. // get the `request` field from an access log record
  2. def getRequest(rawAccessLogString: String): Option[String] = {
  3. val accessLogRecordOption = p.parseRecord(rawAccessLogString)
  4. accessLogRecordOption match {
  5.   case Some(rec) => Some(rec.request)
  6.   case None => None
  7. }
  8. }
复制代码
将这些代码贴入Spark REPL,再运行如下代码:
  1. log.filter(line => getStatusCode(p.parseRecord(line)) == "404").map(getRequest(_)).count
  2. val recs = log.filter(line => getStatusCode(p.parseRecord(line)) == "404").map(getRequest(_))
  3. val distinctRecs = log.filter(line => getStatusCode(p.parseRecord(line)) == "404").map(getRequest(_)).distinct
  4. distinctRecs.foreach(println)
复制代码
总结

对于访问日志简朴分析固然是要grep比力好,但是更复杂的查询就须要Spark了。很难判定 Spark在单个体系上的性能。这是由于Spark是针对分布式体系大文件。

以上就是本文的全部内容,希望对各人的学习有所帮助,也希望各人多多支持草根技术分享。

帖子地址: 

回复

使用道具 举报

分享
推广
火星云矿 | 预约S19Pro,享500抵1000!
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

草根技术分享(草根吧)是全球知名中文IT技术交流平台,创建于2021年,包含原创博客、精品问答、职业培训、技术社区、资源下载等产品服务,提供原创、优质、完整内容的专业IT技术开发社区。
  • 官方手机版

  • 微信公众号

  • 商务合作