返回介绍

12.4 实战分析

发布于 2024-01-29 22:54:22 字数 9326 浏览 0 评论 0 收藏 0

在互联网企业中,随着业务量、访问量的不断增长,用户产生的数据也越来越大,如何处理大数据的存储与分析问题呢?比如Web服务器的访问log,当日志只有GB单位大小时,我们还可以勉强通过shell、awk进行分析,当达到上百GB,甚至上PB级别时,通过脚本的方式已经力不从心了。另外一个待解决的问题就是数据存储。Hadoop很好地解决了这两个问题,即分布式存储与计算。下面将通过示例介绍如何从Web日志中快速获取访问流量、HTTP状态信息、用户IP信息、连接数/分钟统计等。

12.4.1 示例场景

站点www.website.com共有5台Web设备,日志文件存放位置:/data/logs/日期(20140215)/access.log,日志为默认的Apache定义格式,如:

125.26.28.8 - - [01/Aug/2010:09:56:53 +0700] "GET /teacher/jitra/image/pen.gif HTTP/1.1" 200 12014 "http://www.kpsw.ac.th/teacher/jitra/page4.htm" "Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.1; Trident/4.0; GTB6.5; InfoPath.1; .NET CLR 2.0.50727; yie8)"
125.26.28.8 - - [01/Aug/2010:09:56:53 +0700] "GET /favicon.ico HTTP/1.1" 200 1187 "-" "Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.1; Trident/4.0; GTB6.5; InfoPath.1; .NETCLR 2.0.50727; yie8)"
66.249.65.37 - - [01/Aug/2010:09:57:59 +0700] "GET /picture/49-02/DSC02630.jpg HTTP/1.1" 200 79220 "-" "Googlebot-Image/1.0"
66.249.65.37 - - [01/Aug/2010:09:59:19 +0700] "GET /elearning/index.php?cal_m=2&cal_y=2011 HTTP/1.1" 200 9232 "-" "Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)"

共有12列数据(空格分隔),分别为:①客户端IP;②空白(远程登录名称);③空白(认证的远程用户);④请求时间;⑤UTC时差;⑥方法;⑦资源;⑧协议;⑨状态码;⑩发送字节数;访问来源;客户浏览器信息(不具体拆分)。

接下来在5台Web服务器部署HDFS的客户端,以便定期上传Web日志到HDFS存储平台,最终实现分布式计算。需要安装(JDK配置环境变量)、Hadoop(原版tar包解析即可),详细见12.2相关内容。添加上传日志功能作业到crontab,内容如下:

55 23 * * * /usr/bin/python /home/test/hadoop/hdfsput.py >> /dev/null 2>&1

通过subprocess.Popen方法调用Hadoop HDFS相关外部命令,实现创建HDFS目录及客户端文件上传,详细代码如下:

【/home/test/hadoop/hdfsput.py】

import subprocess
import sys
import datetime
webid="web1"  #HDFS存储日志标志,其他Web服务器分别为web2、web3、web4、web5
currdate=datetime.datetime.now.strftime('%Y%m%d')
logspath="/data/logs/"+currdate+"/access.log"  #日志本地路径
logname="access.log."+webid  #HDFS存储日志名
try:
  subprocess.Popen(["/usr/local/hadoop-1.2.1/bin/hadoop", "dfs", "-mkdir", "hdfs://192.168.1.20:9000/user/root/website.com/"+currdate], stdout=subprocess.PIPE)
#创建HDFS目录,目录格式:website.com/20140205
except Exception,e:
  pass
putinfo=subprocess.Popen(["/usr/local/hadoop-1.2.1/bin/hadoop", "dfs", "-put", logspath, "hdfs://192.168.1.20:9000/user/root/website.com/"+currdate+"/"+logname], stdout=subprocess.PIPE)  #上传本地日志到HDFS
for line in putinfo.stdout:
  print line

在crontab定时作业运行后,5台Web服务器的日志在HDFS上的信息如下:

# /usr/local/hadoop-1.2.1/bin/hadoop dfs -ls /user/root/website.com/20140215
Found 5 items
-rw-r--r--  3 root supergroup  156541746 2014-02-15 23:55 /user/root/website.com/20140215/access.log.web1
-rw-r--r--  3 root supergroup  251245315 2014-02-15 23:53 /user/root/website.com/20140215/access.log.web2
-rw-r--r--  3 root supergroup  134256412 2014-02-15 23:55 /user/root/website.com/20140215/access.log.web3
-rw-r--r--  3 root supergroup  192314554 2014-02-15 23:54 /user/root/website.com/20140215/access.log.web4
-rw-r--r--  3 root supergroup  183267834 2014-02-15 23:55 /user/root/website.com/20140215/access.log.web5

截至目前,数据的分析源已经准备就绪,接下来的工作便是分析了。

12.4.2 网站访问流量统计

网站访问流量作为衡量一个站点的价值、热度的重要标准,另外在CDN服务中流量会涉及计费,如何快速准确分析当前站点的流量数据至关重要,当然,使用Mrjob可以很轻松实现此类需求。下面实现精确到分钟统计网站访问流量,原理是在mapper操作时将Web日志中小时的每分钟作为key,将对应的行发送字节数作为value,在reducer操作时对相同key作累加(sum)统计,详细源码如下:

【/home/test/hadoop/httpflow.py】

from mrjob.job import MRJob
import re
class MRCounter(MRJob):
  def mapper(self, key, line):
     i=0
     for flow in line.split:
        if i==3:  #获取时间字段,位于日志的第4列,内容如“[06/Aug/2010:03:19:44”
          timerow= flow.split(":")
          hm=timerow[1]+":"+timerow[2]  #获取“小时:分钟”,作为key
        if i==9 and re.match(r"\d{1,}", flow):  #获取日志第10列-发送的字节数,
        作为value
          yield hm, int(flow)  #初始化key:value
        i+=1
  def reducer(self, key, occurrences):
     yield key, sum(occurrences)  #相同key“小时:分钟”的value作累加操作
if __name__ == '__main__':
  MRCounter.run

生成Hadoop任务,运行:

# python /home/test/hadoop/httpflow.py -r hadoop --jobconf mapreduce.job.priority=VERY_HIGH -o hdfs:///output/httpflow hdfs:///user/root/website.com/20140215

分析结果见图12-14。

图12-14 任务分析结果(部分截图)

建议将分析结果数据定期入库MySQL,利用MySQL灵活、丰富的SQL支持,可以很方便地对数据进行加工,轻松输出比较美观的数据报表。图12-15为网站一天的流量趋势图。

图12-15 业务流量趋势图

12.4.3 网站HTTP状态码统计

统计一个网站的HTTP状态码比例数据,可以帮助我们了解网站的可用度及健康状态,比如我们关注的200、404、5xx状态等。在此示例中我们利用Mrjob的多步调用的形式来实现,除了基本的mapper、reducer方法外,还可以添加自定义处理方法,在steps中添加调用即可,详细源码如下:

【/home/test/hadoop/httpstatus.py】

from mrjob.job import MRJob
import re
class MRCounter(MRJob):
  def mapper(self, key, line):
     i=0
     for httpcode in line.split:
        if i==8 and re.match(r"\d{1,3}", httpcode):#获取日志中HTTP状态码段,作为key
          yield httpcode, 1 #初始化key:value,value计数为1,方便reducer作累加
        i+=1
  def reducer(self, httpcode, occurrences):
     yield httpcode, sum(occurrences)  #对排序后的key对应的value作sum累加
  def steps(self):
     return [self.mr(mapper=self.mapper),  #在steps方法中添加调用队列
          self.mr(reducer=self.reducer)]
if __name__ == '__main__':
  MRCounter.run

生成hadoop任务,分析数据源保持不变,输出目录改成/output/httpstatus,执行:

# python /home/test/hadoop/httpstatus.py -r hadoop --jobconf mapreduce.job.priority=VERY_HIGH -o hdfs:///output/httpstatus hdfs:///user/root/website.com/20140215

分析结果见图12-16。

图12-16 任务分析结果

我们可以根据结果数据输出比例饼图,如图12-17所示。

图12-17 生成HTTP状态码饼图

12.4.4 网站分钟级请求数统计

一个网站的请求量大小,直接关系到网站的访问质量,非常有必要对该数据进行分析且关注。本示例以分钟为单位对网站的访问数进行统计,原理与12.4.2类似,区别是value初始为1,以便作累加统计,详细源码如下:

【/home/test/hadoop/http_minute_conn.py】

from mrjob.job import MRJob
import re
class MRCounter(MRJob):
  def mapper(self, key, line):
     i=0
     for dt in line.split:
        if i==3:  #获取时间字段,位于日志的第4列,内容如“[06/Aug/2010:03:19:44”
          timerow= dt.split(":")
          hm=timerow[1]+":"+timerow[2]  #获取“小时:分钟”,作为key
          yield hm, 1  #初始化key:value,value计数为1,方便reducer作累加
        i+=1
  def reducer(self, key, occurrences):
     yield key, sum(occurrences)
if __name__ == '__main__':
  MRCounter.run

生成Hadoop任务,输出目录/output/http_minute_conn,执行:

# python /home/test/hadoop/http_minute_conn.py -r hadoop --jobconf mapreduce.job.priority=VERY_HIGH -o hdfs:///output/http_minute_conn hdfs:///user/root/website.com/20140215

分析结果见图12-18。

图12-18 任务分析结果(部分截图)

12.4.5 网站访问来源IP统计

统计用户的访问来源IP可以更好地了解网站的用户分布,同时也可以帮助安全人员捕捉攻击来源。实现原理是定义匹配IP正则字符串作为key,将value初始化为1,执行reducer操作时作累加(sum)统计,详细源码如下:

【/home/test/hadoop/ipstat.py】

from mrjob.job import MRJob
import re
IP_RE = re.compile(r"\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}")  #定义IP正则匹配
class MRCounter(MRJob):
  def mapper(self, key, line):
     #匹配IP正则后生成key:value,其中key为IP地址,value初始值为1
     for ip in IP_RE.findall(line):
        yield ip, 1
  def reducer(self, ip, occurrences):
     yield ip, sum(occurrences)
if __name__ == '__main__':
  MRCounter.run

生成Hadoop任务,输出目录/output/ipstat,执行:

# python /home/test/hadoop/ipstat.py -r hadoop --jobconf mapreduce.job.priority=VERY_HIGH -o hdfs:///output/ipstat hdfs:///user/root/website.com/20140215

分析结果见图12-19。

图12-19 任务分析结果(部分截图)

12.4.6 网站文件访问统计

通过统计网站文件的访问次数可以帮助运维人员了解访问最集中的文件,以便进行有针对性的优化,比如调整静态文件过期策略、优化动态cgi的执行速度、拆分业务逻辑等。实现原理是将访问文件作为key,初始化value为1,执行reducer时作累加(sum)统计,详细源码如下:

【/home/test/hadoop/httpfile.py】

from mrjob.job import MRJob
import re
class MRCounter(MRJob):
  def mapper(self, key, line):
     i=0
     for url in line.split:
        if i==6:    #获取日志中URL文件资源字段,作为key
          yield url, 1
        i+=1
  def reducer(self, url, occurrences):
     yield url, sum(occurrences)
if __name__ == '__main__':
  MRCounter.run

执行结果如图12-20所示。

图12-20 任务分析结果(部分截图)

同理,我们可以使用以上方法对User-Agent域进行分析,包括浏览器类型及版本、操作系统及版本、浏览器内核等信息,为更好地提升用户体验提供数据支持。

参考提示  12.2.1小节原生Python编写mapreduce示例参考http://www.michael-noll.com/tutorials/writing-an-hadoop-mapreduce-program-in-python/。

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文