基于Spark的大规模日志分析
摘要:本篇文章将从一个实际项目出发,分享如何使用 Spark 进行大规模日志分析,并通过代码演示加深读者的理解。
本文分享自华为云社区《【实战经验分享】基于Spark的大规模日志分析【上进小菜猪大数据系列】》,作者:上进小菜猪。
随着互联网的普及和应用范围的扩大,越来越多的应用场景需要对海量数据进行高效地处理和分析,这就要求我们必须具备大数据技术方面的知识和技能。本篇文章将从一个实际项目出发,分享如何使用 Spark 进行大规模日志分析,并通过代码演示加深读者的理解。
1.数据来源
我们的项目是针对某购物网站的访问日志进行分析,其中主要包含以下几个字段:
- IP:访问的客户端 IP 地址
- Time:访问时间
- Url:访问的 URL 地址
- User-Agent:浏览器标识符
原始数据规模约为 100GB,我们需要对其进行清洗、统计和分析,以得到有用的信息和价值。
2. 数据清洗
由于原始数据存在缺失值、异常值、重复值等问题,因此我们需要进行数据清洗,主要包括以下步骤:
- 将原始数据进行格式转换,方便后续处理
- 对 IP、Time、Url 和 User-Agent 字段进行解析和提取
- 去除不合法的记录和重复的记录
具体代码实现如下:
import org.apache.spark.{SparkConf, SparkContext}
import java.text.SimpleDateFormat
import java.util.Locale
object DataCleaning {
def main(args: Array[String]) {
val conf = new SparkConf().setAppName("DataCleaning")
val sc = new SparkContext(conf)
val data = sc.textFile("hdfs://master:9000/log/access.log")
// 定义时间格式及地区信息
val dateFormat = new SimpleDateFormat("dd/MMM/yyyy:HH:mm:ss Z", Locale.ENGLISH)
// 数据清洗
val cleanData = data.map(line => {
val arr = line.split(" ")
if (arr.length >= 9) {
// 解析 IP
val ip = arr(0)
// 解析时间,转换为 Unix 时间戳
val time = dateFormat.parse(arr(3) + " " + arr(4)).getTime / 1000
// 解析 URL
val url = urlDecode(arr(6))
// 解析 UserAgent
val ua = arr(8)
(ip, time, url, ua)
}
}).filter(x => x != null).distinct()
// 结果输出
cleanData.saveAsTextFile("hdfs://master:9000/cleanData")
sc.stop()
}
// URL 解码
def urlDecode(url: String): String = {
java.net.URLDecoder.decode(url, "utf-8")
}
}
3. 数据统计
对于大规模数据的处理,我们可以使用 Spark 提供的强大的分布式计算能力,以提高处理效率和减少计算时间。
我们这里使用 Spark SQL 统计每个 URL 的访问量,并输出前 10 个访问量最高的 URL,代码如下:
import org.apache.spark.{SparkConf, SparkContext}
import org.apache.spark.sql.SQLContext
case class LogRecord(ip: String, time: Long, url: String, ua: String)
object DataAnalysis {
def main(args: Array[String]) {
val conf = new SparkConf().setAppName("DataAnalysis")
val sc = new SparkContext(conf)
val sqlContext = new SQLContext(sc)
// 读取清洗后的数据
val cleanData = sc.textFile("hdfs://master:9000/cleanData").filter(x => x != null)
// 将数据转换为 DataFrame
import sqlContext.implicits._
val logDF = cleanData.map(_.split(",")).map(p => LogRecord(p(0), p(1).toLong, p(2), p(3))).toDF()
// 统计每个 URL 的访问量,并按访问量降序排序
val topUrls = logDF.groupBy("url").count().sort($"count".desc)
// 输出前 10 个访问量最高的 URL
topUrls.take(10).foreach(println)
sc.stop()
}
}
4. 数据可视化
数据可视化是将处理和分析后的数据以图表或图像的方式展示出来,有利于我们直观地观察数据的规律和趋势。
我们这里采用 Python 的 Matplotlib 库将前 10 个访问量最高的 URL 可视化,代码如下:
import matplotlib.pyplot as plt
# 读取数据
with open('topUrls.txt', 'r') as f:
line = f.readline()
urls = []
counts = []
while line and len(urls) < 10:
url, count = line.strip().split(',')
urls.append(url)
counts.append(int(count))
line = f.readline()
# 绘制直方图
plt.bar(range(10), counts, align='center')
plt.xticks(range(10), urls, rotation=90)
plt.xlabel('Url')
plt.ylabel('Count')
plt.title('Top 10 Url')
plt.show()
在进行数据清洗前,需要先对原始日志数据进行筛选,选取需要分析的字段。然后进行数据清洗,去掉不必要的空格、特殊字符等,使数据更加规整,并增加可读性。
下面是数据清洗的代码示例:
val originalRdd = spark.sparkContext.textFile("path/to/logfile")
val filteredRdd = originalRdd.filter(line => {
val tokens = line.split("\t")
tokens.length >= 10 &&
tokens(0).matches("\d{4}-\d{2}-\d{2}") &&
tokens(1).matches("\d{2}:\d{2}:\d{2}") &&
tokens(2).matches("\d+") &&
tokens(3).matches("\d+") &&
tokens(4).matches("\d+") &&
tokens(5).matches("\d+") &&
tokens(6).matches(".+") &&
tokens(7).matches(".+") &&
tokens(8).matches(".+") &&
tokens(9).matches(".+")
})
val cleanedRdd = filteredRdd.map(line => {
val tokens = line.split("\t")
val timestamp = s"${tokens(0)} ${tokens(1)}"
val request = tokens(6).replaceAll(""", "")
val responseCode = tokens(8).toInt
(timestamp, request, responseCode)
})
在上述代码中,我们首先读取原始日志数据,并使用filter函数过滤掉不符合条件的行;然后使用map函数将数据转换为元组的形式,并进行清洗。其中,元组的三个元素分别是时间戳、请求内容和响应状态码。
接下来,让我们来介绍一下如何使用Spark进行数据统计。
数据统计是大规模数据分析中非常重要的一个环节。Spark提供了丰富的聚合函数,可用于对数据进行各种统计分析。
下面是对清洗后的数据进行统计分析的代码示例:
import org.apache.spark.sql.functions._
val df = spark.createDataFrame(cleanedRdd).toDF("timestamp", "request", "responseCode")
val totalCount = df.count()
val errorsCount = df.filter(col("responseCode") >= 400).count()
val successCount = totalCount - errorsCount
val topEndpoints = df.groupBy("request").count().orderBy(desc("count")).limit(10)
topEndpoints.show()
在上面的代码中,我们首先将清洗后的数据转换为DataFrame,然后使用count函数计算总记录数和错误记录数,并计算成功记录数。最后使用groupBy和orderBy函数按照请求内容,对数据进行分组统计,并打印出请求次数最多的前10个端点。
通过可视化,我们可以清楚地看到前 10 个访问量最高的 URL 地址及其访问量,这对于进一步分析和优化网站的性能和用户体验具有重要的意义。
总结起来,这就是我们的一个大数据实战项目,我们使用 Spark 统计了购物网站的访问量,并通过 Python 的 Matplotlib 库将结果可视化。这个过程中,我们运用了数据清洗、Spark SQL 统计和可视化等技术,为大规模数据的处理和分析提供了有效的解决方案。
基于Spark的大规模日志分析的更多相关文章
- 基于Spark的网站日志分析
本文只展示核心代码,完整代码见文末链接. Web Log Analysis 提取需要的log信息,包括time, traffic, ip, web address 进一步解析第一步获得的log信息,如 ...
- 基于 Spark 的文本情感分析
转载自:https://www.ibm.com/developerworks/cn/cognitive/library/cc-1606-spark-seniment-analysis/index.ht ...
- 使用Spark进行搜狗日志分析实例——map join的使用
map join相对reduce join来说,可以减少在shuff阶段的网络传输,从而提高效率,所以大表与小表关联时,尽量将小表数据先用广播变量导入内存,后面各个executor都可以直接使用 pa ...
- 使用Spark进行搜狗日志分析实例——统计每个小时的搜索量
package sogolog import org.apache.spark.rdd.RDD import org.apache.spark.{SparkConf, SparkContext} /* ...
- spark提交异常日志分析
java.lang.NoSuchMethodError: org.apache.spark.sql.SQLContext.sql(Ljava/lang/String;)Lorg/apache/spar ...
- 使用Spark进行搜狗日志分析实例——列出搜索不同关键词超过10个的用户及其搜索的关键词
package sogolog import org.apache.hadoop.io.{LongWritable, Text} import org.apache.hadoop.mapred.Tex ...
- 基于Spark的均值漂移算法在网络舆情聚类中的应用
知网链接 原文链接 张京坤, 王怡怡 软件导刊 2020年19卷第9期 页码:190-195 DOI:10.11907/rjdk.192529 出版日期:2020-9-15 摘 要: 为了改善网 ...
- Linux 日志分析工具之awstats
一.awstats 是什么 官方网站:AWStats is a free powerful and featureful tool that generates advanced web, strea ...
- MySQL 数据库慢查询日志分析脚本
这个脚本是基于pt-query-digest做的日志分析脚本,变成可视化的格式. 目录结构是 ./mysql_data/log./mysql_data/log/tmp./slow_query # co ...
- 苏宁基于Spark Streaming的实时日志分析系统实践 Spark Streaming 在数据平台日志解析功能的应用
https://mp.weixin.qq.com/s/KPTM02-ICt72_7ZdRZIHBA 苏宁基于Spark Streaming的实时日志分析系统实践 原创: AI+落地实践 AI前线 20 ...
随机推荐
- 第三届材料化学与复合材料国际学术会议(MCCM 2022)
大会官网:http://www.meeting-mccm.org/ 大会时间:2022年12月16-18日 大会地点:中国-珠海 截稿日期:详情见官网(2022年10月14日) 接受/拒稿通知:投稿后 ...
- 端口转发、Http Tunnel、内网穿透
原文链接:https://www.yuque.com/tec-nine/architecture/mgxc71 SSH 命令帮助 命令行选项有: -a 禁止转发认证代理的连接. -A 允许转发认证代理 ...
- LRU缓存替换策略及C#实现
目录 LRU缓存替换策略 核心思想 不适用场景 算法基本实现 算法优化 进一步优化 Benchmark LRU缓存替换策略 缓存是一种非常常见的设计,通过将数据缓存到访问速度更快的存储设备中,来提高数 ...
- [数据库]MYSQL之存储过程
一 存储过程的特点 MySQL 5.0 版本开始支持存储过程 1.1 定义 存储过程(Stored Procedure)是一种在数据库中存储复杂程序,以便外部程序调用的一种数据库对象. 存储过程是为了 ...
- 多态、抽象、Object类
1.方法重写要求:方法名相同.参数类型相同.返回值相同或其子类返回值相同,子类修饰符要不小于父类 2.方法重载要求:方法名相同.参数类型不同.返回值没有改变.修饰符无关 3.多态的前提是继承.多态是定 ...
- Disruptor-简单使用
前言 Disruptor是一个高性能的无锁并发框架,其主要应用场景是在高并发.低延迟的系统中,如金融领域的交易系统,游戏服务器等.其优点就是非常快,号称能支撑每秒600万订单.需要注意的是,Disru ...
- LeeCode哈希问题(二)
LeeCode 454: 四数相加II 题目描述 给你四个整数数组 nums1.nums2.nums3 和 nums4,数组长度均为 n ,请你计算有多少个元组 (i, j, k, l) 能满足: \ ...
- gradle下载
gradle下载:https://services.gradle.org/distributions/src.zip源码 .bin.zip安装文件.all.zip源码+安装文件 配置环境变量.
- RedisTemplate在拦截器前没有注入的问题
RedisTemplate为null的问题 最近在搭建一个项目,然后项目框架采用的是spring boot,然后登录我就使用新学习的JWT嘛,然后就想着在请求进来的时候使用拦截器先对传进来的token ...
- MySQL WorkBench更换界面成中文的方法
菜单页面更换 文章目录 菜单页面更换 汉化文件的xml文件我放在下面的网盘中了 1.找到MySQL的安装位置, 总结 汉化文件的xml文件我放在下面的网盘中了 1.找到MySQL的安装位置, 具体安装 ...