利用Scala与spark-sql两种方式分析海量数据
前言:
Mapreduce和Spark的都是并行计算,那么他们有什么相同和区别
相同:两者都是用mr模型来进行并行计算
区别:MapReduce这些并行计算大都是基于非循环的数据流模型,
也就是说,一次数据过程包含从共享文件系统读取数据、进行计算、完成计算、写入计算结果到共享存储中,在计算过程中,不同计算节点之间保持高度并行,
这样的数据流模型使得那些需要反复使用一个特定数据集的迭代算法无法高效地运行。
Spark和Spark使用的RDD就是为了解决这种问题而开发出来的,Spark使用了一种特殊设计的数据结构,称为RDD。
RDD的一个重要特征是,分布式数据集可以在不同的并行环境当中被重复使用,这个特性将Spark和其他并行数据流模型框架(如MapReduce)区别开。
hadoop的job只有map和reduce操作,表达能力比较欠缺而且在mr过程中会重复的读写hdfs,造成大量的io操作,多个job需要自己管理关系。 spark的迭代计算都是在内存中进行的,API中提供了大量的RDD操作如join,groupby
本次所分析数据部分截取
字段分别为 ip 时间 操作方式以及访问地址 返回状态码 数据量字节数:
36.57.154.177 [12/Aug/2020:01:21:39+0800] "POST/dataman/zkau" 200 63
36.57.154.177 [12/Aug/2020:01:21:40+0800] "GET/dataman/image/main/new/sousuo_selected.png" 304 -
36.57.154.177 [12/Aug/2020:01:21:42+0800] "POST/dataman/zkau" 200 63
36.57.154.177 [12/Aug/2020:01:21:51+0800] "POST/dataman/zkau" 200 62
36.57.154.177 [12/Aug/2020:01:21:51+0800] "POST/dataman/zkau" 200 107
36.57.154.177 [12/Aug/2020:01:21:51+0800] "POST/dataman/zkau" 200 63
36.57.154.177 [12/Aug/2020:01:21:51+0800] "POST/dataman/zkau" 200 62
36.57.154.177 [12/Aug/2020:01:21:51+0800] "POST/dataman/zkau" 200 107
36.57.154.177 [12/Aug/2020:01:21:51+0800] "POST/dataman/zkau" 200 63
1:计算独立IP数:
spark-sql解决:
结果截图:
Scala代码解决:
package com.zgy.tran
import org.apache.spark.{SparkConf, SparkContext}
object AloneIpCount {
def main(args: Array[String]): Unit = {
val conf = new SparkConf()
.setMaster("local")
.setAppName("SparkMap")
val sc = new SparkContext(conf)
val linesRDD = sc.textFile("F:\\BaiduNetdiskDownload\\webcrawler\\data\\tran\\localhost_access_log.txt");
val value = linesRDD.map(t=>t.split(" ")(0))
.map(ip=>(ip,1)).distinct()
.count()
println(value)
}
}
结果截图:
2:统计每个图片独立IP数 (图片为地址中含有.png)
spark-sql解决:
结果截图:
Scala代码解决:
package com.zgy.tran
import org.apache.spark.{SparkConf, SparkContext}
object PngCount {
def main(args: Array[String]): Unit = {
val conf = new SparkConf()
.setMaster("local")
.setAppName("SparkMap")
val sc = new SparkContext(conf)
val linesRDD = sc.textFile("F:\\BaiduNetdiskDownload\\webcrawler\\data\\tran\\localhost_access_log.txt");
val png = linesRDD.map(t => t.split(" ")(2))
.filter(p=>p.endsWith("png\""))
.map(p2=>(p2,1))
val value = png.reduceByKey(_+_)
.foreach(println)
}
}
结果截图:
3:统计一天中每个小时的流量
spark-sql解决:
结果截图:
Scala代码解决:
package com.zgy.tran
import org.apache.spark.{SparkConf, SparkContext}
object HourFlow {
def main(args: Array[String]): Unit = {
val conf = new SparkConf()
.setMaster("local")
.setAppName("SparkMap")
val sc = new SparkContext(conf)
val linesRDD = sc.textFile("F:\\BaiduNetdiskDownload\\webcrawler\\data\\tran\\localhost_access_log.txt");
val value = linesRDD.map(t=>t.split(" ")(1))
.map(rn=>rn.substring(1,15))
.map(ln=>(ln,1))
.reduceByKey(_+_)
.foreach(println)
}
}
结果截图: