Azure HDInsight 上的 Spark 群集配合自定义的Python来分析网站日志
一、前言:本文是个实践博客,演示如何结合使用自定义库和 HDInsight 上的 Spark 来分析日志数据。 我们使用的自定义库是一个名为 iislogparser.py的 Python 库。
- 每步的输入和对应的输出
- 纠正了原文中一个因版本引起的小问题
前提:你先在Azure HDinsight上有一个Apache Spark集群,(似乎现在只能是2.*版本的spark了)
二、将原始数据另存为 RDD
在本部分中,将使用与 HDInsight 中的 Apache Spark 群集关联的 Jupyter 笔记本来运行用于处理原始示例数据并将其保存为 Hive 表的作业。 示例数据是所有群集在默认情况下均会提供的 .csv 文件 (hvac.csv)。 将数据保存为 Hive 表后,下一节将使用 Power BI 和 Tableau 等 BI 工具连接 Hive 表。
1. 在 Azure 门户上的启动板中,单击 Spark 群集的磁贴(如果已将它固定到启动板)。 也可以单击“全部浏览” > “HDInsight 群集”导航到群集。
2. 在 Spark 群集边栏选项卡中单击“群集仪表板”,然后单击“Jupyter Notebook”。 出现提示时,请输入群集的管理员凭据。
3. 创建新的笔记本。 单击“新建”,然后单击“PySpark”。
4. 随即创建新笔记本,并以 Untitled.pynb 名称打开。 单击顶部的笔记本名称,并输入一个友好名称。
5. 使用笔记本是使用 PySpark 内核创建的,因此不需要显式创建任何上下文。 运行第一个代码单元格时,系统自动创建 Spark 和 Hive 上下文。 首先,可以导入此方案所需的类型。 将以下代码段粘贴到空白单元格中,并按 SHIFT + ENTER。
from pyspark.sql import Row
from pyspark.sql.types import *
6. 使用群集上已可用的示例日志数据创建 RDD。 可以从 \HdiSamples\HdiSamples\WebsiteLogSampleData\SampleLog\909f2b.log 中访问与群集关联的默认存储帐户中的数据。
logs = sc.textFile('wasb:///HdiSamples/HdiSamples/WebsiteLogSampleData/SampleLog/909f2b.log')
此处的日志格式大致为:
#Software: Microsoft Internet Information Services 8.0
#Fields: date time s-sitename cs-method cs-uri-stem cs-uri-query s-port cs-username c-ip cs(User-Agent) cs(Cookie) cs(Referer) cs-host sc-status sc-substatus sc-win32-status sc-bytes cs-bytes time-taken
2014-01-01 02:01:09 SAMPLEWEBSITE GET /blogposts/mvc4/step2.png X-ARR-LOG-ID=2ec4b8ad-3cf0-4442-93ab-837317ece6a1 80 - 1.54.23.196 Mozilla/5.0+(Windows+NT+6.3;+WOW64)+AppleWebKit/537.36+(KHTML,+like+Gecko)+Chrome/31.0.1650.63+Safari/537.36 - http://weblogs.asp.net/sample/archive/2007/12/09/asp-net-mvc-framework-part-4-handling-form-edit-and-post-scenarios.aspx www.sample.com 200 0 0 53175 871 46
2014-01-01 02:01:09 SAMPLEWEBSITE GET /blogposts/mvc4/step3.png X-ARR-LOG-ID=9eace870-2f49-4efd-b204-0d170da46b4a 80 - 1.54.23.196 Mozilla/5.0+(Windows+NT+6.3;+WOW64)+AppleWebKit/537.36+(KHTML,+like+Gecko)+Chrome/31.0.1650.63+Safari/537.36 - http://weblogs.asp.net/sample/archive/2007/12/09/asp-net-mvc-framework-part-4-handling-form-edit-and-post-scenarios.aspx www.sample.com 200 0 0 51237 871 32
2014-01-01 02:21:19 SAMPLEWEBSITE GET /blogposts/mvcrouting/step11.jpg X-ARR-LOG-ID=117d64f4-5bf4-44e0-9ef5-669737d69adc 80 - 115.64.147.147 Mozilla/5.0+(Macintosh;+Intel+Mac+OS+X+10_9_1)+AppleWebKit/537.36+(KHTML,+like+Gecko)+Chrome/31.0.1650.63+Safari/537.36 ARRAffinity=909f2bd5d754dbde10a14dff095f3fbe3b22ca6b04cccdaf15bd58ecb51e1fe4;+WAWebSiteSID=7613e9e104a04a31a798554d8954622c http://weblogs.asp.net/sample/archive/2007/12/03/asp-net-mvc-framework-part-2-url-routing.aspx www.sample.com 200 0 0 30944 976 15
7. 检索示例日志集以验证上一步是否成功完成。
logs.take(5)
应该会看到与下面类似的输出:
[u'#Software: Microsoft Internet Information Services 8.0',
u'#Fields: date time s-sitename cs-method cs-uri-stem cs-uri-query s-port cs-username c-ip cs(User-Agent) cs(Cookie) cs(Referer) cs-host sc-status sc-substatus sc-win32-status sc-bytes cs-bytes time-taken',
u'2014-01-01 02:01:09 SAMPLEWEBSITE GET /blogposts/mvc4/step2.png X-ARR-LOG-ID=2ec4b8ad-3cf0-4442-93ab-837317ece6a1 80 - 1.54.23.196 Mozilla/5.0+(Windows+NT+6.3;+WOW64)+AppleWebKit/537.36+(KHTML,+like+Gecko)+Chrome/31.0.1650.63+Safari/537.36 - http://weblogs.asp.net/sample/archive/2007/12/09/asp-net-mvc-framework-part-4-handling-form-edit-and-post-scenarios.aspx www.sample.com 200 0 0 53175 871 46',
u'2014-01-01 02:01:09 SAMPLEWEBSITE GET /blogposts/mvc4/step3.png X-ARR-LOG-ID=9eace870-2f49-4efd-b204-0d170da46b4a 80 - 1.54.23.196 Mozilla/5.0+(Windows+NT+6.3;+WOW64)+AppleWebKit/537.36+(KHTML,+like+Gecko)+Chrome/31.0.1650.63+Safari/537.36 - http://weblogs.asp.net/sample/archive/2007/12/09/asp-net-mvc-framework-part-4-handling-form-edit-and-post-scenarios.aspx www.sample.com 200 0 0 51237 871 32',
u'2014-01-01 02:01:09 SAMPLEWEBSITE GET /blogposts/mvc4/step4.png X-ARR-LOG-ID=4bea5b3d-8ac9-46c9-9b8c-ec3e9500cbea 80 - 1.54.23.196 Mozilla/5.0+(Windows+NT+6.3;+WOW64)+AppleWebKit/537.36+(KHTML,+like+Gecko)+Chrome/31.0.1650.63+Safari/537.36 - http://weblogs.asp.net/sample/archive/2007/12/09/asp-net-mvc-framework-part-4-handling-form-edit-and-post-scenarios.aspx www.sample.com 200 0 0 72177 871 47']
三、使用自定义 Python 库分析日志数据
1. 在上面的输出中,前几行包括标头信息,其余的每一行均与此标头中描述的架构相匹配。 分析此类日志可能很复杂。 因此,可使用自定义 Python 库 (iislogparser.py),它能使分析这类日志变得容易得多。 默认情况下,此库包含在 /HdiSamples/HdiSamples/WebsiteLogSampleData/iislogparser.py处 HDInsight 上的 Spark 群集中。但是,此库不在 PYTHONPATH
中,因此不能通过 import iislogparser
等导入语句来使用它。 要使用此库,必须将其分发给所有辅助角色节点。 运行以下代码段。
sc.addPyFile('wasb:///HdiSamples/HdiSamples/WebsiteLogSampleData/iislogparser.py')
2. 如果日志行是标题行,则 iislogparser
提供返回 None
的函数 parse_log_line
,并且在遇到日志行时返回 LogLine
类的实例。 使用 LogLine
类从 RDD 中仅提取日志行:
def parse_line(l):
import iislogparser
return iislogparser.parse_log_line(l)
logLines = logs.map(parse_line).filter(lambda p: p is not None).cache()
3. 检索一些提取的日志行,以验证该步骤是否成功完成。
logLines.take(2)
输出应如下所示:
2014-01-01 02:01:09 SAMPLEWEBSITE GET /blogposts/mvc4/step3.png X-ARR-LOG-ID=9eace870-2f49-4efd-b204-0d170da46b4a 80 - 1.54.23.196 Mozilla/5.0+(Windows+NT+6.3;+WOW64)+AppleWebKit/537.36+(KHTML,+like+Gecko)+Chrome/31.0.1650.63+Safari/537.36 - http://weblogs.asp.net/sample/archive/2007/12/09/asp-net-mvc-framework-part-4-handling-form-edit-and-post-scenarios.aspx www.sample.com 200 0 0 51237 871 32]
4. 反过来,LogLine
类具有一些有用的方法,如 is_error()
,可返回日志条目是否具有错误代码。 使用此类计算提取日志行中的错误数,然后将所有错误记录到另一个文件中。
errors = logLines.filter(lambda p: p.is_error())
numLines = logLines.count()
numErrors = errors.count()
print 'There are', numErrors, 'errors and', numLines, 'log entries'
errors.map(lambda p: str(p)).saveAsTextFile('wasb:///HdiSamples/HdiSamples/WebsiteLogSampleData/SampleLog/909f2b-2.log')
应该看到如下输出:
There are 30 errors and 646 log entries
5. 还可使用 Matplotlib 构造数据的可视化效果。 例如,如果要找出请求长时间运行的原因,可能需要查找平均执行时间最长的文件。 下面的代码片段检索执行请求花费时间最长的前 25 个资源。
def avgTimeTakenByKey(rdd):
return rdd.combineByKey(lambda line: (line.time_taken, 1),
lambda x, line: (x[0] + line.time_taken, x[1] + 1),
lambda x, y: (x[0] + y[0], x[1] + y[1]))\
.map(lambda x: (x[0], float(x[1][0]) / float(x[1][1])))
avgTimeTakenByKey(logLines.map(lambda p: (p.cs_uri_stem, p))).top(25, lambda x: x[1])
应该看到如下输出:
[(u'/blogposts/mvc4/step13.png', 197.5),
(u'/blogposts/mvc2/step10.jpg', 179.5),
(u'/blogposts/extractusercontrol/step5.png', 170.0),
(u'/blogposts/mvc4/step8.png', 159.0),
(u'/blogposts/mvcrouting/step22.jpg', 155.0),
(u'/blogposts/mvcrouting/step3.jpg', 152.0),
(u'/blogposts/linqsproc1/step16.jpg', 138.75),
(u'/blogposts/linqsproc1/step26.jpg', 137.33333333333334),
(u'/blogposts/vs2008javascript/step10.jpg', 127.0),
(u'/blogposts/nested/step2.jpg', 126.0),
(u'/blogposts/adminpack/step1.png', 124.0),
(u'/BlogPosts/datalistpaging/step2.png', 118.0),
(u'/blogposts/mvc4/step35.png', 117.0),
(u'/blogposts/mvcrouting/step2.jpg', 116.5),
(u'/blogposts/aboutme/basketball.jpg', 109.0),
(u'/blogposts/anonymoustypes/step11.jpg', 109.0),
(u'/blogposts/mvc4/step12.png', 106.0),
(u'/blogposts/linq8/step0.jpg', 105.5),
(u'/blogposts/mvc2/step18.jpg', 104.0),
(u'/blogposts/mvc2/step11.jpg', 104.0),
(u'/blogposts/mvcrouting/step1.jpg', 104.0),
(u'/blogposts/extractusercontrol/step1.png', 103.0),
(u'/blogposts/sqlvideos/sqlvideos.jpg', 102.0),
(u'/blogposts/mvcrouting/step21.jpg', 101.0),
(u'/blogposts/mvc4/step1.png', 98.0)]
6. 还可以图绘形式显示此信息。 创建绘图的第一步是创建一个临时表 AverageTime。 该表按照时间对日志进行分组,以查看在任何特定时间是否存在任何异常延迟峰值。
avgTimeTakenByMinute = avgTimeTakenByKey(logLines.map(lambda p: (p.datetime.minute, p))).sortByKey()
schema = StructType([StructField('Minutes', IntegerType(), True),
StructField('Time', FloatType(), True)])
avgTimeTakenByMinuteDF = spark.createDataFrame(avgTimeTakenByMinute, schema)
avgTimeTakenByMinuteDF.registerTempTable('AverageTime')
Warning:原文doc中的sqlContext.createDataFrame 需要改为spark.createDataFrame,不然会遇到'StructField' object has no attribute '_get_object_id'的报错
7. 接下来可以运行以下 SQL 查询以获取 AverageTime 表中的所有记录。
%%sql -o averagetime
SELECT * FROM AverageTime
后接 -o averagetime 的 %%sql magic 可确保查询输出本地保存在 Jupyter 服务器上(通常在群集的头结点)。 输出作为 Pandas 数据帧进行保存,指定名称为 averagetime
8. 现可使用 Matplotlib(用于构造数据效果可视化的库)创建绘图。 因为必须从本地保存的 averagetime 数据帧中创建绘图,所以代码片段必须以 %%local
magic 开头。 这可确保代码在 Jupyter 服务器上本地运行。
%%local
%matplotlib inline
import matplotlib.pyplot as plt
plt.plot(averagetime['Minutes'], averagetime['Time'], marker='o', linestyle='--')
plt.xlabel('Time (min)')
plt.ylabel('Average time taken for request (ms)')
plt.grid(True)
9. 完成运行应用程序之后,应该要关闭笔记本以释放资源。 为此,请在笔记本的“文件”菜单中,单击“关闭并停止”。 这将会关闭 notebook。
Azure HDInsight 上的 Spark 群集配合自定义的Python来分析网站日志的更多相关文章
- Azure HDInsight 和 Spark 大数据实战(一)
What is HDInsight? Microsoft Azure HDInsight 是基于 Hortonoworks Data Platform (HDP) 的 Hadoop 集群,包括Stor ...
- 在 Azure HDInsight 中安装和使用 Spark
Spark本身用Scala语言编写,运行于Java虚拟机(JVM).只要在安装了Java 6以上版本的便携式计算机或者集群上都可以运行spark.如果您想使用Python API需要安装Python解 ...
- Windows Azure HDInsight 支持预览版 Hadoop 2.2 群集
Windows Azure HDInsight 支持预览版 Hadoop 2.2 群集 继去年 10 月推出 Windows Azure HDInsight 之后,我们宣布 Windows Az ...
- Azure HDInsight与Hadoop周边系统集成
Sunwei 9 Dec 2014 1:54 AM 传统的Hadoop系统提供给用户2个非常优秀的框架,MR计算框架和HDFS存储框架,尽管MR已经显得有些老迈而缓慢,但是HDFS还是很多应用系统的 ...
- Windows Azure HDInsight 现已正式发布!
今天,我们宣布正式发布 Windows Azure HDInsight 服务.HDInsight 是 Microsoft 提供的基于 Hadoop 的服务,为云提供 100% 的 Apache Had ...
- Windows Azure HDInsight 使用技巧
Windows Azure HDInsight是一个面向大数据的PaaS服务,是PaaS版本的Hadoop.HDInsight是微软与Hortonworks合作的产物.可以理解为Hortonworks ...
- 在Ubuntu下搭建Spark群集
在前一篇文章中,我们已经搭建好了Hadoop的群集,接下来,我们就是需要基于这个Hadoop群集,搭建Spark的群集.由于前面已经做了大量的工作,所以接下来搭建Spark会简单很多. 首先打开三个虚 ...
- 基于Azure构建PredictionIO和Spark的推荐引擎服务
基于Azure构建PredictionIO和Spark的推荐引擎服务 1. 在Azure构建Ubuntu 16.04虚拟机 假设前提条件您已有 Azure 帐号,登陆 Azure https://po ...
- Azure HDInsight HBase DR解决方案
Sun wei Sat, Feb 28 2015 3:07 AM Apache HBase是目前非常流行的NoSQL数据库,通过HDFS+Zookeep+Master+Region Server的架 ...
随机推荐
- 【教你玩转云计算】在阿里云一键安装快速部署Oracle11g
云计算时代提供了更方便可靠的IAAS,PAAS和SAAS平台.将已有或正在研发的项目迁移到云计算平台,和传统的服务器部署还是存在一些异同点. 本文手把手教你在阿里云平台快速的部署Oracle11g ...
- oracle如何导出和导入数据库/表
oracle如何导出和导入数据库/表 oracle如何将项目中的表导出后在导入自己的数据库中,这是一个完整的操作,对于数据库备份或在本地查看数据验证数据进场用到,一般情况下我都用dos黑窗口进行操作, ...
- linux内核分析第二四学习报告
学生 黎静 课程内容 计算机三大法宝 • 存储程序计算机工作模型,计算机系统最最基础性的逻辑结构: • 函数调用堆栈,高级语言得以运行的基础,只有机器语言和汇编语言的时候堆栈机制对于计算机来说并不那 ...
- 异常 try – finally 注意的地方
finally 异常机制中还有一个重要的部分,就是finally, catch后面可以跟finally语句,语法如下所示: try{ //可能抛出异常 }catch(Exception e){ / ...
- Jmeter 常用断言使用
响应断言 可根据要测试响应字段和模式匹配规则来设置断言,比如下方截图是匹配返回的结果中是否包含"code:200,",如果包含则表示断言成功,否则失败.响应断言可添加多个,但是多个 ...
- Linux 重启网络提示找不到eth0(no device found for “System eth0”)
一.背景 使用VMWare创建了一个虚拟机(VM1),然后通过拷贝的方式创建了另一台虚拟机(VM2).在第二台虚拟机上设置网卡为固定IP,使用service network restart重启网络的时 ...
- centos7安装浏览器
firefox(火狐) sudo yum install firefox chrome(谷歌) 添加源:sudo wget http://repo.fdzh.org/chrome/google-chr ...
- Golang的位运算操作符的使用
& 位运算 AND | 位运算 OR ^ 位运算 XOR &^ 位清空 (AND NOT) << 左移 >> 右移 感觉位运算操作符虽然在平时用得并不多,但是在 ...
- python 协程库gevent学习--gevent数据结构及实战(三)
gevent学习系列第三章,前面两章分析了大量常用几个函数的源码以及实现原理.这一章重点偏向实战了,按照官方给出的gevent学习指南,我将依次分析官方给出的7个数据结构.以及给出几个相应使用他们的例 ...
- 关于python 自带csv库的使用心得 附带操作实例以及excel下乱码的解决
因为上次帮我们产品处理过一个文件,他想生成能excel处理操作的.但是上次由于时间非常紧张,所以并没有处理好. 正好无聊就来好好研究一下 ,找算法要了几个 csv文件.来好好玩一玩. 全篇使用了pyt ...