Hadoop部署实践之日志文件数据利用hive、mysql、sqoop导出

项目概述

首先通过国内某技术学习论坛的数据日志,由于日志文件的数量较大,我们统计数量就会相较复杂,所以我们需要利用python开发的mapper reducer进行数据处理,再将处理过后的文件导入hive,利用查询创表语句查询并导出出我们所需要的数据,再利用sqoop把所创建好的表导入到mysql当中,在mysql当中就能查询出我们所需要的数据。

总体设计

第一步:hadoop环境部署和源数据准备。
第二步:使用python开发的mapper reducer进行数据处理。
第三步:创建hive数据库,将处理的数据导入hive数据库。
第四步:将分析数据导入mysql。

详细实现步骤操作纪要

hadoop环境准备

  • hadoop
  • hive
  • mysql
  • sqoop

HDFS相应操作

1.首先我们需要启动hdfs
start-all.sh
2.把日志文件拷入本地,再用hdfs进行上传
hdfs dfs -mkdir -p /project/techbbs
hdfs dfs -put /home/hadoop/logs /project/techbbs

使用python开发mapreduce脚本对日志数据进行清理。

为了更加方便的统计出我们所需的数据我们需要使用hadoop-streming运行mapper reduce程序
1.首先我们需要准备mapper.py和reduce.py的python代码
mapper.py的python代码

#!/usr/bin/env python3
# ($HADOOP_HOME/mapper.py)
import sys
import time
#  解析英文时间字符串
#
#  @param string
#  @return
#  @throws ParseException
# /
def  parseDateFormat(string):
    timeArray = time.strptime(string, "%d/%B/%Y:%H:%M:%S %z")
    otherStyleTime = time.strftime("%Y-%m-%d %H:%M:%S", timeArray)
    return otherStyleTime


#
# 解析日志的行记录
#
# @param line
# @return 数组含有5个元素,分别是ip、时间、url、状态、流量
#
def parse( line):
    ip = parseIP(line)
    time = parseTime(line)
    url = parseURL(line)
    status = parseStatus(line)
    traffic = parseTraffic(line)
    return [ip, time, url, status, traffic]


def parseTraffic( line):
    strip = line[line.rfind("\"") + 1:len(line)].strip()
    traffic = strip.split(" ")[1]
    return traffic


def parseStatus( line):
    strip = line[line.rfind("\"") + 1].strip()
    status = strip.split(" ")[0]
    return status


def parseURL( line):
    first = line.index("\"")
    last = line.rfind("\"")
    url = line[first + 1: last]
    return url


def parseTime( line):
    first = line.index("[")
    last = line.index("]")
    time = line[first + 1: last].strip()
    date = parseDateFormat(time)
    return date


def parseIP( line):
    ip = line.split("- -")[0].strip()
    return ip



for inx, line in enumerate(sys.stdin):  # 遍历读入数据的每一行
    parsed = parse(line)  # 将行尾行首的空格去除
    #step1.过滤掉静态资源访问请求
    if parsed[2].startswith("GET /static/") or parsed[2].startswith("GET /uc_server"):
        continue;
    #step2.过滤掉开头的指定字符串
    if parsed[2].startswith("GET /"):
        parsed[2] = parsed[2][len("GET /"):len(parsed[2])]
    else :
        if parsed[2].startswith("POST /"):
            parsed[2] = parsed[2][len("POST /"):len(parsed[2])]
    #step3.过滤掉结尾的特定字符串
    if parsed[2].endswith(" HTTP/1.1"):
        parsed[2] = parsed[2][0:(len(parsed[2])-len(" HTTP/1.1"))]

    print('%s\t%s,%s,%s' % (inx,parsed[0],parsed[1],parsed[2]))

reduce.py的python代码

#!/usr/bin/env python3
# ($HADOOP_HOME/reducer.py)
from operator import itemgetter
import sys
for line in sys.stdin:
    words = line.strip()  # 去除字符串首尾的空白字符
    count,word = words.split('\t')  # 按照制表符分隔单词和数量
    print('%s' % (word))

查看python版本
python --version
切换python版本
alias python=’/usr/bin/python3’

2.把所准备好的mapper.y和reduce.py拷入/home/hadoop/python_script目录

进入目录
cd /home/hadoop/python_script
对mapper.py和reducer.py添加权限
chmod 777 mapper.py
chmod 777 reducer.py

创建脚本文件run_2013-05-30.sh和run_2013-05-31.sh

hadoop jar "/home/hadoop/hadoop-2.7.3/share/hadoop/tools/lib/hadoop-streaming-2.7.3.jar"  \
-files /home/hadoop/python_script/mapper.py,/home/hadoop/python_script/reducer.py \
-mapper /home/hadoop/python_script/mapper.py \
-reducer /home/hadoop/python_script/reducer.py \
-input /project/techbbs/logs/access_2013_05_30.log \
-output /home/hadoop/wsq/result/2013_05_30
hadoop jar "/home/hadoop/hadoop-2.7.3/share/hadoop/tools/lib/hadoop-streaming-2.7.3.jar"  \
-files /home/hadoop/python_script/mapper.py,/home/hadoop/python_script/reducer.py \
-mapper /home/hadoop/python_script/mapper.py \
-reducer /home/hadoop/python_script/reducer.py \
-input /project/techbbs/logs/access_2013_05_31.log \
-output /home/hadoop/wsq/result/2013_05_31

3.当我们创建好了mapper.py、reduce.py、run_2013-05-30.sh、run_2013-05-31.sh的python文件和脚本文件过后就可以对日志进行清洗

./run_2013-05-30.sh

4.我们可以在http://localhost:50070/explorer.html#/当中进行查看文件是否清洗成功

根据结果文件结构建立hive数据库表

1.首先在结果文件上创建分区表

create external table wsq(ip string, atime string, url string) partitioned by (logdate string) row format delimited fields terminated by ‘,’ location ‘/home/hadoop/wsq/result’;
按日期添加分区
alter table wsq add partition(logdate=‘2013_05_30’) location’/home/hadoop/wsq/result/2013_05_30’;在这里插入图片描述在这里插入图片描述

使用Hive对结果表进行数据分析统计

1查询PV量(定义:页面浏览量即为PV(Page View),是指所有用户浏览页面的总和,一个独立用户每打开一个页面就被记录1 次)

由于pv为用户浏览页面的总和,所以我们只需要对第一列进行求和查询则为日志文件的pv量,所以我们可以先利用创建一个pv表
create table wsq_pv_2013_05_30 as select count(1) as PV from wsq where logdate=‘2013_05_30’;
查询所创建的pv
select * from wsq_pv_2013_05_30;

2.查询注册用户数(该论坛的用户注册页面为member.php,而当用户点击注册时请求的又是member.php?mod=register的url。计算公式:对访问member.php?mod=register的url,计数。)

create table wsq_reguser_2013_05_30 as select count(1) as reguser from wsq where logdate = ‘2013_05_30’ and instr(url,‘member.php?mod=register’)>0;
查询所创建的reguser表
select * from wsq_reguser_2013_05_30;

3.查询独立IP数(定义:一天之内,访问网站的不同独立 IP 个数加和。其中同一IP无论访问了几个页面,独立IP 数均为1。)

由于独立ip数不论访问几个页面都为1,所以我们查询时只需要使用distinct关键词去除重复的ip进行求和。
create table wsq_ip_2013_05_30 as select count(distinct ip) as IP from wsq where logdate = ‘2013_05_30’;
查询所创建的ip表
select * from wsq_ip_2013_05_30;

4.查询跳出用户数(定义:只浏览了一个页面便离开了网站的访问次数占总的访问次数的百分比,即只浏览了一个页面的访问次数 / 全部的访问次数汇总。)

跳出用户为只浏览一个页面就离开网站,所以我们可以进行复合查询,首先用group by分组查询统计ip,在用having对分组所统计的ip表为1次的进行二次筛选,再统计刚才所查表第一列的总和
create table wsq_jumper_2013_05_30 as select count(1) as jumper from (select count(ip) as times from wsq where logdate=‘2013_05_30’ group by ip having times=1) e;
查询所创建的jumper表
select * from wsq_jumper_2013_05_30;

使用Sqoop将hive分析结果表导入mysql

1.把上面所创建的pv,reguser,ip,jumper进行合并创建为一个表。

由于为防止大数据集群稳定性,类似非全等join(非inner join)是禁止的,禁用了SemanticException笛卡尔产品。所以我们需要先对hive进行参数设置
set hive.strict.checks.cartesian.product=flase;
set hive.mapred.mode=nonstrict;
create table wsq_2013_05_30 as select ‘2013_05_30’,a.pv,b.reguser,c.ip,d.jumper from wsq_pv_2013_05_30 a join wsq_reguser_2013_05_30 b on 1=1 join wsq_ip_2013_05_30 c on 1=1 join wsq_jumper_2013_05_30 d on 1=1;

2.创建mysql表

mysql -u root -p
create database wsq;

use wsq;
create table wsq_logs_stat(logdate varchar(10) primary key,pv int,reguser int,ip int,jumper int);

3.将hive结果文件导入mysql

sqoop export --connect jdbc:mysql://127.0.0.1:3306/wsq --username root --password root --table wsq_logs_stat --fields-terminated-by ‘\001’ --export-dir ‘/user/hive/warehouse/wsq_2013_05_30’

select * from wsq_logs_stat;

同理2013_05_31的日志文件重复上述步骤就可以导出数据

学习总结

1.此次实践操作我们首先需要熟练关于hdfs的创建表语句已经上传语句,然后对相应的python版本写出hadoop-streaming的mapper.py以及reducer.py的python代码,创建好脚本文件便可清洗出日志文件的内容。
2.再通过hive的sql的查询语句对所需要的数据进行查询,由于我们后续需要将所查的数据导入到mysql中,所以我们可以直接创建查数据结果后的表方便后续导入。
3.最后在利用sqoop导入mysql当中,进入mysql查询就能得到我们所要的数据了。
4.同理为了不分别创建多个日志文件所查询出的结果,我们也可以使用group by直接对总文件的所有表进行查询分区岂可。
5.利于hadoop操作大大减轻了我们最常规的查询方法,并且可以更加准确快速的得出我们所想要的结果。

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值