本文基于《Spark 最佳实践》第6章 Spark 流式计算。

我们知道网站用户访问流量是不间断的,基于网站的访问日志,即 Web log 分析是典型的流式实时计算应用场景。比如百度统计,它可以做流量分析、来源分析、网站分析、转化分析。另外还有特定场景分析,比如安全分析,用来识别 CC 攻击、 SQL 注入分析、脱库等。这里我们简单实现一个类似于百度分析的系统。

代码见 https://github.com/libaoquan95/WebLogAnalyse

1.模拟生成 web log 记录

在日志中,每行代表一条访问记录,典型格式如下:

46.156.87.72 - - [2018-05-15 06:00:30] "GET /upload.php HTTP/1.1" 200 0 "http://www.baidu.com/s?wd=spark" "Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.2; Trident/6.0)" "-"

分别代表:访问 ip,时间戳,访问页面,响应状态,搜索引擎索引,访问 Agent。

简单模拟一下数据收集和发送的环节,用一个 Python 脚本随机生成 Nginx 访问日志,为了方便起见,不使用 HDFS,使用单机文件系统。

首先,新建文件夹用于存放日志文件

$ mkdir Documents/nginx
$ mkdir Documents/nginx/log
$ mkdir Documents/nginx/log/tmp

然后,使用 Python 脚本随机生成 Nginx 访问日志,并为脚本设置执行权限, 代码见 sample_web_log.py

#!/usr/bin/env python
# -*- coding: utf-8 -*- import random
import time class WebLogGeneration(object): # 类属性,由所有类的对象共享
site_url_base = "http://www.xxx.com/" # 基本构造函数
def __init__(self):
# 前面7条是IE,所以大概浏览器类型70%为IE ,接入类型上,20%为移动设备,分别是7和8条,5% 为空
self.user_agent_dist = {0.0:"Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.2; Trident/6.0)",
0.1:"Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.2; Trident/6.0)",
0.2:"Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; Trident/4.0; .NET CLR 2.0.50727)",
0.3:"Mozilla/4.0 (compatible; MSIE6.0; Windows NT 5.0; .NET CLR 1.1.4322)",
0.4:"Mozilla/5.0 (Windows NT 6.1; Trident/7.0; rv:11.0) like Gecko",
0.5:"Mozilla/5.0 (Windows NT 6.1; WOW64; rv:41.0) Gecko/20100101 Firefox/41.0",
0.6:"Mozilla/4.0 (compatible; MSIE6.0; Windows NT 5.0; .NET CLR 1.1.4322)",
0.7:"Mozilla/5.0 (iPhone; CPU iPhone OS 7_0_3 like Mac OS X) AppleWebKit/537.51.1 (KHTML, like Gecko) Version/7.0 Mobile/11B511 Safari/9537.53",
0.8:"Mozilla/5.0 (Linux; Android 4.2.1; Galaxy Nexus Build/JOP40D) AppleWebKit/535.19 (KHTML, like Gecko) Chrome/18.0.1025.166 Mobile Safari/535.19",
0.9:"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/45.0.2454.85 Safari/537.36",
1:" ",}
self.ip_slice_list = [10, 29, 30, 46, 55, 63, 72, 87, 98,132,156,124,167,143,187,168,190,201,202,214,215,222]
self.url_path_list = ["login.php","view.php","list.php","upload.php","admin/login.php","edit.php","index.html"]
self.http_refer = [ "http://www.baidu.com/s?wd={query}","http://www.google.cn/search?q={query}","http://www.sogou.com/web?query={query}","http://one.cn.yahoo.com/s?p={query}","http://cn.bing.com/search?q={query}"]
self.search_keyword = ["spark","hadoop","hive","spark mlib","spark sql"] def sample_ip(self):
slice = random.sample(self.ip_slice_list, 4) #从ip_slice_list中随机获取4个元素,作为一个片断返回
return ".".join([str(item) for item in slice]) # todo def sample_url(self):
return random.sample(self.url_path_list,1)[0] def sample_user_agent(self):
dist_uppon = random.uniform(0, 1)
return self.user_agent_dist[float('%0.1f' % dist_uppon)] # 主要搜索引擎referrer参数
def sample_refer(self):
if random.uniform(0, 1) > 0.2: # 只有20% 流量有refer
return "-" refer_str=random.sample(self.http_refer,1)
query_str=random.sample(self.search_keyword,1)
return refer_str[0].format(query=query_str[0]) def sample_one_log(self,count = 3):
time_str = time.strftime("%Y-%m-%d %H:%M:%S",time.localtime())
while count >1:
query_log = "{ip} - - [{local_time}] \"GET /{url} HTTP/1.1\" 200 0 \"{refer}\" \"{user_agent}\" \"-\"".format(ip=self.sample_ip(),local_time=time_str,url=self.sample_url(),refer=self.sample_refer(),user_agent=self.sample_user_agent())
print query_log
count = count -1 if __name__ == "__main__":
web_log_gene = WebLogGeneration() #while True:
# time.sleep(random.uniform(0, 3))
web_log_gene.sample_one_log(random.uniform(10, 100))

设置可执行权限的方法如下

$ chmod +x sample_web_log.py

之后,编写 bash 脚本,自动生成日志记录,并赋予可执行权限,代码见 genLog.sh

#!/bin/bash

while [ 1 ]; do
./sample_web_log.py > test.log tmplog="access.`date +'%s'`.log"
cp test.log streaming/tmp/$tmplog
mv streaming/tmp/$tmplog streaming/
echo "`date +"%F %T"` generating $tmplog succeed"
sleep 1
done

赋予权限

$ chmod +x genLog.sh

执行 genLog.sh 查看效果,输入 ctrl+c 终止。

$ ./genLog.sh

2.流式分析

创建 Scala 脚本,代码见 genLog.sh

import org.apache.spark.SparkConf
import org.apache.spark.streaming.{Seconds, StreamingContext} val batch = 10 // 计算周期(秒)
//val conf = new SparkConf().setAppName("WebLogAnalyse").setMaster("local")
//val ssc = new StreamingContext(conf, Seconds(batch))
val ssc = new StreamingContext(sc, Seconds(batch))
val input = "file:///home/libaoquan/Documents/nginx/log" // 文件流
val lines = ssc.textFileStream(input) // 计算总PV
lines.count().print() // 各个ip的pv
lines.map(line => (line.split(" ")(0), 1)).reduceByKey(_+_).print() // 获取搜索引擎信息
val urls = lines.map(_.split("\"")(3)) // 先输出搜索引擎和查询关键词,避免统计搜索关键词时重复计算
// 输出(host, query_keys)
val searchEnginInfo = urls.map( url => {
// 搜索引擎对应的关键字索引
val searchEngines = Map(
"www.google.cn" -> "q",
"www.yahoo.com" -> "p",
"cn.bing.com" -> "q",
"www.baidu.com" -> "wd",
"www.sogou.com" -> "query"
)
val temp = url.split("/")
// Array(http:, "", www.baidu.com, s?wd=hadoop)
if(temp.length > 2){
val host = temp(2)
if(searchEngines.contains(host)){
val q = url.split("//?")
if(q.length > 0) {
val query = q(1)
val arr_search_q = query.split('&').filter(_.indexOf(searchEngines(host) + "=") == 0)
if (arr_search_q.length > 0) {
(host, arr_search_q(0).split('=')(1))
} else {
(host, "")
}
} else{
("", "")
}
} else{
("", "")
}
} else{
("", "")
}
}) // 搜索引擎pv
searchEnginInfo.filter(_._1.length > 0).map(i => (i._1, 1)).reduceByKey(_+_).print() // 关键字pv
searchEnginInfo.filter(_._2.length > 0).map(i => (i._2, 1)).reduceByKey(_+_).print() // 终端pv
lines.map(_.split("\"")(5)).map(agent => {
val types = Seq("iPhone", "Android")
var r = "Default"
for (t <- types) {
if (agent.indexOf(t) != -1)
r = t
}
(r, 1)
}).reduceByKey(_ + _).print() // 各页面pv
lines.map(line => (line.split("\"")(1).split(" ")(1), 1)).reduceByKey(_+_).print() ssc.start()
ssc.awaitTermination()

3.执行

同时开启两个终端,分别执行 genLog.sh 生成日志文件和执行 WebLogAnalyse.scala 脚本进行流式分析。

执行 genLog.sh

$ ./genLog.sh

执行 WebLogAnalyse.scala, 使用 spark-shell 执行 scala 脚本

$ spark-shell --executor-memory 5g --driver-memory 1g --master local  < WebLogAnalyse.scala

效果如下,左边是 WebLogAnalyse.scala,右边是 genLog.sh

Spark 实践——基于 Spark Streaming 的实时日志分析系统的更多相关文章

  1. 苏宁基于Spark Streaming的实时日志分析系统实践 Spark Streaming 在数据平台日志解析功能的应用

    https://mp.weixin.qq.com/s/KPTM02-ICt72_7ZdRZIHBA 苏宁基于Spark Streaming的实时日志分析系统实践 原创: AI+落地实践 AI前线 20 ...

  2. 使用GoAccess构建简单实时日志分析系统

    很早就知道Nginx日志分析工具GoAccess,但之前由于只能静态分析,感觉不太强大.最近发现它能够实时显示报表而且报表也比之前强大很多能做趋势分析.因此果断下载安装.以下是基于CentOS的安装配 ...

  3. centos7搭建ELK开源实时日志分析系统

    Elasticsearch 是个开源分布式搜索引擎它的特点有分布式零配置自动发现索引自动分片索引副本机制 restful 风格接口多数据源自动搜索负载等. Logstash 是一个完全开源的工具他可以 ...

  4. Spark 实践——基于 Spark MLlib 和 YFCC 100M 数据集的景点推荐系统

    1.前言 上接 YFCC 100M数据集分析笔记 和 使用百度地图api可视化聚类结果, 在对 YFCC 100M 聚类出的景点信息的基础上,使用 Spark MLlib 提供的 ALS 算法构建推荐 ...

  5. ELK系列--实时日志分析系统ELK 部署与运行中的问题汇总

    前记: 去年测试了ELK,今年测试了Storm,最终因为Storm需要过多开发介入而放弃,选择了ELK.感谢互联网上各路大神,目前总算是正常运行了. logstash+elasticsearch+ki ...

  6. 手把手教你搭建 ELK 实时日志分析平台

    本篇文章主要是手把手教你搭建 ELK 实时日志分析平台,那么,ELK 到底是什么呢? ELK 是三个开源项目的首字母缩写,这三个项目分别是:Elasticsearch.Logstash 和 Kiban ...

  7. 【转】ELK(ElasticSearch, Logstash, Kibana)搭建实时日志分析平台

    [转自]https://my.oschina.net/itblog/blog/547250 摘要: 前段时间研究的Log4j+Kafka中,有人建议把Kafka收集到的日志存放于ES(ElasticS ...

  8. ELK实时日志分析平台环境部署--完整记录

    在日常运维工作中,对于系统和业务日志的处理尤为重要.今天,在这里分享一下自己部署的ELK(+Redis)-开源实时日志分析平台的记录过程(仅依据本人的实际操作为例说明,如有误述,敬请指出)~ ==== ...

  9. 【Big Data - ELK】ELK(ElasticSearch, Logstash, Kibana)搭建实时日志分析平台

    摘要: 前段时间研究的Log4j+Kafka中,有人建议把Kafka收集到的日志存放于ES(ElasticSearch,一款基于Apache Lucene的开源分布式搜索引擎)中便于查找和分析,在研究 ...

随机推荐

  1. php输出年份

    Copyright <?php echo date('Y');?> by Creditease Corp.All Right Reserved.

  2. 使用java实现hex和ascii码的转换

    几乎很少写JAVA代码,第一是确实不会,第二感觉JAVA写起来不爽(较python.golang),但总有万不得已必须要用java的时候.这里记录下使用java实现的hex十六进制和acsii码之间的 ...

  3. JAVA框架 Spring 和Mybatis整合(动态代理)

    一.使用传统方式的dao的书写方式,不建议.目前采用的是动态代理的方式交给mybatis进行处理. 首先回顾下动态代理要求: 1)子配置文件的中,namespace需要是接口的全路径,id是接口的方法 ...

  4. 安装ubuntu系统 ——分区

    安装ubuntu 系统主要分四个区 目录 建议大小 格式 描述 / 10G-20G ext4 根目录 swap <2048M swap 交换空间 /boot 400M左右 ext4 Linux的 ...

  5. 二分法php

    二分法.分别使用while循环的方法和递归调用的方法. <?php // 二分法的使用数组必须是有序的,或升序,或降序 $arr = array( 1, 3, 5, 7, 9, 13 ); // ...

  6. odoo之ERP系统

    odoo大纲 第一部分:数据库postgressql 大象 第二部分:ORM(API) 第三部分:客户端 用python软件写: .py文件 包含两部分:1.自定义部分,由自己写,定义类和功能. .继 ...

  7. 【MEVN架构】mongodb+ express + vue + nodejs 搭建后台

    前端技术栈:vue2 + vuex + vue-router + webpack + ES6/7 + less + element-ui 服务端技术栈:nodejs + express + mongo ...

  8. 20155301PC平台逆向破解

    20155301PC平台逆向破解 1.掌握NOP, JNE, JE, JMP, CMP汇编指令的机器码 NOP:NOP指令即"空指令".执行到NOP指令时,CPU什么也不做,仅仅当 ...

  9. 20155308《网络对抗》Exp9 Web安全基础实践

    20155308<网络对抗>Exp9 Web安全基础实践 本实践的目标理解常用网络攻击技术的基本原理.Webgoat实践下相关实验. 基础问题回答 SQL注入攻击原理,如何防御? 原理:攻 ...

  10. Qt FFMPEG+OpenCV开启摄像头

    //ffmpegDecode.h #ifndef __FFMPEG_DECODE_H__ #define __FFMPEG_DECODE_H__ #include "global.h&quo ...