专栏首页用户3288143的专栏【快速入门大数据】Hadoop项目实战-用户行为日志

【快速入门大数据】Hadoop项目实战-用户行为日志

文章目录

用户日志

用处

分析行为 推荐

日志生成渠道

服务端Ngnix统计 前端统计Ajax

日志内容

意义

判断购买的推广转化率,及时调整不同区域的投资推广 判断页面包含的子页面是否合理,路径是否合理转化率 分析日志,营销经费合理分配

离线数据处理架构

数据处理流程
1)数据采集
	Flume: web日志写入到HDFS

2)数据清洗
	脏数据
	Spark、Hive、MapReduce 或者是其他的一些分布式计算框架  
	清洗完之后的数据可以存放在HDFS(Hive/Spark SQL)

3)数据处理
	按照我们的需要进行相应业务的统计和分析
	Spark、Hive、MapReduce 或者是其他的一些分布式计算框架

4)处理结果入库
	结果可以存放到RDBMS、NoSQL

5)数据的可视化
	通过图形化展示的方式展现出来:饼图、柱状图、地图、折线图
	ECharts、HUE、Zeppelin

分析日志

可获得到信息 地点、时间、访问设备、访问次数

UserAgent

hadoop jar /home/hadoop/lib/hadoop-train-1.0-jar-with-dependencies.jar com.imooc.hadoop.project.LogApp /10000_access.log /browserout

引入解析UserAgent

// 下载克隆
git clone https://github.com/LeeKemp/UserAgentParser.git

// 打包
mvn clean package -DskipTests

// 去target找到该文件jar
cd target/
UserAgentParser-0.0.1.jar

// 后退cd ..重新打包到本地的jar,让idea识别可用
mvn clean install -DskipTest
// 检验本地jar包生成
(base) bennyrhysdeMacBook-Pro:UserAgentParser bennyrhys$ cd /Users/bennyrhys/.m2/repository/com/kumkee/UserAgentParser/0.0.1/
(base) bennyrhysdeMacBook-Pro:0.0.1 bennyrhys$ ls
UserAgentParser-0.0.1.jar	UserAgentParser-0.0.1.pom	_remote.repositories

引入pom本地依赖

处理10000条数据的100条

// 提取100条数据
head -n 100 10000_access.log > 100_access.log
// 检测数据条数
wc -l 100_access.log 

单体实现

UserAgentTest

package com.bennyrhys.hadoop.project;

import com.kumkee.userAgent.UserAgent;
import com.kumkee.userAgent.UserAgentParser;
import org.apache.commons.lang.StringUtils;
import org.junit.Test;

import java.io.*;
import java.nio.file.Path;
import java.util.HashMap;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * @Author bennyrhys
 * @Date 1/16/21 6:37 PM
 * UserAgent测试类
 */
public class UserAgentTest {
//    public static void main(String[] args) {

    /**
     * 读取文件,根据指定区间,统计浏览器信息
     * @throws IOException
     */
    @Test
    public void testReadFile() throws IOException {
        String path = "/Users/bennyrhys/Desktop/spark-practice/100_access.log";
        BufferedReader reader = new BufferedReader(
          new InputStreamReader(new FileInputStream(new File(path)))
        );
        String line = "";
        HashMap<String, Integer> browserMap = new HashMap<>();

        UserAgentParser userAgentParser = new UserAgentParser();
        while (line != null) {
            line = reader.readLine(); // 一次读入一行数据
            if (StringUtils.isNotBlank(line)) {
                String source = line.substring(getCharacterPosition(line, "\"", 7) + 1);
                UserAgent agent = userAgentParser.parse(source);

                String browser = agent.getBrowser();
                String engine = agent.getEngine();
                String engineVersion = agent.getEngineVersion();
                String os = agent.getOs();
                String platform = agent.getPlatform();
                String version = agent.getVersion();
                boolean mobile = agent.isMobile();

                System.out.println(browser + " " + engine  + " " + engineVersion  + " " + os  + " " + platform  + " " + version  + " " + mobile);

                Integer browserCount = browserMap.get(browser);
                if (browserCount != null) {
                    browserMap.put(browser, browserCount + 1);
                }else {
                    browserMap.put(browser, 1);
                }
            }
        }
        for (Map.Entry<String , Integer> entry : browserMap.entrySet()) {
            System.out.println(entry.getKey() + " : " + entry.getValue());
        }
    }

    /**
     * 测试标识符的定位方法
     */
    @Test
    public void testGetCharacterPosition() {
        String value = "183.162.52.7 - - [10/Nov/2016:00:01:02 +0800] \"POST /api3/getadv HTTP/1.1\" 200 813 \"www.imooc.com\" \"-\" cid=0&timestamp=1478707261865&uid=2871142&marking=androidbanner&secrect=a6e8e14701ffe9f6063934780d9e2e6d&token=f51e97d1cb1a9caac669ea8acc162b96 \"mukewang/5.0.0 (Android 5.1.1; Xiaomi Redmi 3 Build/LMY47V),Network 2G/3G\" \"-\" 10.100.134.244:80 200 0.027 0.027";
        int index = getCharacterPosition(value, "\"", 7);
        System.out.println(index);
    }

    /**
     * 获取字符串中的指定标识字符串出现的索引位置
     */
    private int getCharacterPosition(String value, String operator, int index) {
        Matcher matcher = Pattern.compile(operator).matcher(value);
        int mIdx = 0;
        while (matcher.find()) {
            mIdx++;
            if (mIdx == index) {
                break;
            }
        }
        return matcher.start();
    }

    /**
     * 单元测试:UserAgent 工具类的使用
     */
    @Test
    public void UserAgentParserT1() {
        // String source = "mukewang/5.0.0 (Android 5.1.1; Xiaomi Redmi 3 Build/LMY47V),Network 2G/3G";
        String source = "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.71 Safari/537.36";

        UserAgentParser userAgentParser = new UserAgentParser();
        UserAgent agent = userAgentParser.parse(source);

        String browser = agent.getBrowser();
        String engine = agent.getEngine();
        String engineVersion = agent.getEngineVersion();
        String os = agent.getOs();
        String platform = agent.getPlatform();
        String version = agent.getVersion();
        boolean mobile = agent.isMobile();

        System.out.println(browser + " " + engine  + " " + engineVersion  + " " + os  + " " + platform  + " " + version  + " " + mobile);
    }

//    }
}

hadoop-MapReduce实现

java

package com.bennyrhys.hadoop.project;

import com.bennyrhys.hadoop.mapreduce.WordCount2App;
import com.kumkee.userAgent.UserAgent;
import com.kumkee.userAgent.UserAgentParser;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.io.LongWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Job;
import org.apache.hadoop.mapreduce.Mapper;
import org.apache.hadoop.mapreduce.Reducer;
import org.apache.hadoop.mapreduce.lib.input.FileInputFormat;
import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat;

import java.io.IOException;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * @Author bennyrhys
 * @Date 1/18/21 11:21 AM
 * 使用MapReduce完成需求:通过日志统计浏览器访问次数
 */
public class LogApp {



    /**
     * Map:读取输入的文件
     */
    public static class MyMapper extends Mapper<LongWritable, Text, Text, LongWritable> {

        LongWritable one = new LongWritable(1);

        private UserAgentParser userAgentParser;

        /**
         * setup,只初始化一次
         */
        @Override
        protected void setup(Context context) throws IOException, InterruptedException {
            userAgentParser = new UserAgentParser();
        }

        @Override
        protected void map(LongWritable key, Text value, Context context) throws IOException, InterruptedException {

            // 接收到的每一行数据:其实就是一行日志信息
            String line = value.toString();

            String source = line.substring(getCharacterPosition(line, "\"", 7) + 1);
            UserAgent agent = userAgentParser.parse(source);

            String browser = agent.getBrowser();

            // 通过上下文把map的处理结果输出
            context.write(new Text(browser), one);

        }

        // gc的时候回收
        @Override
        protected void cleanup(Context context) throws IOException, InterruptedException {
            userAgentParser = null;
        }
    }

    /**
     * 获取字符串中的指定标识字符串出现的索引位置
     */
    private static int getCharacterPosition(String value, String operator, int index) {
        Matcher matcher = Pattern.compile(operator).matcher(value);
        int mIdx = 0;
        while (matcher.find()) {
            mIdx++;
            if (mIdx == index) {
                break;
            }
        }
        return matcher.start();
    }

    /**
     * Reduce:归并操作
     */
    public static class MyReducer extends Reducer<Text, LongWritable, Text, LongWritable> {

        @Override
        protected void reduce(Text key, Iterable<LongWritable> values, Context context) throws IOException, InterruptedException {

            long sum = 0;
            for(LongWritable value : values) {
                // 求key出现的次数总和
                sum += value.get();
            }

            // 最终统计结果的输出
            context.write(key, new LongWritable(sum));
        }
    }

    /**
     * 定义Driver:封装了MapReduce作业的所有信息
     */
    public static void main(String[] args) throws Exception {

        //创建Configuration
        Configuration configuration = new Configuration();

        // 准备清理已存在的输出目录
        Path outputPath = new Path(args[1]);
        FileSystem fileSystem = FileSystem.get(configuration);
        if(fileSystem.exists(outputPath)){
            fileSystem.delete(outputPath, true);
            System.out.println("output file exists, but is has deleted");
        }

        //创建Job
        Job job = Job.getInstance(configuration, "LogApp");

        //设置job的处理类
        job.setJarByClass(LogApp.class);

        //设置作业处理的输入路径
        FileInputFormat.setInputPaths(job, new Path(args[0]));

        //设置map相关参数
        job.setMapperClass(LogApp.MyMapper.class);
        job.setMapOutputKeyClass(Text.class);
        job.setMapOutputValueClass(LongWritable.class);

        //设置reduce相关参数
        job.setReducerClass(LogApp.MyReducer.class);
        job.setOutputKeyClass(Text.class);
        job.setOutputValueClass(LongWritable.class);

        //设置作业处理的输出路径
        FileOutputFormat.setOutputPath(job, new Path(args[1]));

        System.exit(job.waitForCompletion(true) ? 0 : 1);
    }
}

pom.xml注意插件 生成包含本地的jar

<?xml version="1.0" encoding="UTF-8"?>

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>

  <groupId>com.bennyrhys.hadoop</groupId>
  <artifactId>hdfs-api</artifactId>
  <version>1.0-SNAPSHOT</version>

  <name>hdfs-api</name>
  <!-- FIXME change it to the project's website -->
  <url>http://www.example.com</url>

  <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <maven.compiler.source>1.7</maven.compiler.source>
    <maven.compiler.target>1.7</maven.compiler.target>
    <hadoop.version>2.6.0-cdh5.7.0</hadoop.version>
  </properties>

  <repositories>
    <repository>
      <id>cloudera</id>
      <url>https://repository.cloudera.com/artifactory/cloudera-repos/</url>
    </repository>
  </repositories>

  <dependencies>

    <dependency>
      <groupId>org.apache.hadoop</groupId>
      <artifactId>hadoop-client</artifactId>
      <version>${hadoop.version}</version>
      <scope>provided</scope>
    </dependency>

    <!--    本地jar包生成:UserAgentParser解析的依赖-->
    <dependency>
      <groupId>com.kumkee</groupId>
      <artifactId>UserAgentParser</artifactId>
      <version>0.0.1</version>
    </dependency>

    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>4.11</version>
      <scope>test</scope>
    </dependency>
  </dependencies>

<!--  mvn assembly:assembly-->
  <build>
    <plugins>
      <plugin>
        <artifactId>maven-assembly-plugin</artifactId>
        <configuration>
          <archive>
            <manifest>
              <mainClass></mainClass>
            </manifest>
          </archive>
          <descriptorRefs>
            <descriptorRef>jar-with-dependencies</descriptorRef>
          </descriptorRefs>
        </configuration>
      </plugin>
    </plugins>
  </build>
</project>
-rw-r--r--  1 bennyrhys  staff  34246 Jan 18 19:36 hdfs-api-1.0-SNAPSHOT-jar-with-dependencies.jar
-rw-r--r--  1 bennyrhys  staff  24436 Jan 18 19:36 hdfs-api-1.0-SNAPSHOT.jar

hadoop 启动hdfs和yarn 上传lib jar,data 日志文件 写启动脚本shell log.sh

hadoop fs -rm -r /browserout
hadoop jar /root/lib/hdfs-api-1.0-SNAPSHOT-jar-with-dependencies.jar com.bennyrhys.hadoop.project.LogApp  hdfs://hadoop01:9000/10000_access.log hdfs://hadoop01:9000/browserout

效果图

总结

用户行为日志:用户每次访问网站时所有的行为数据(访问、浏览、搜索、点击...)
	用户行为轨迹、流量日志


日志数据内容:
1)访问的系统属性: 操作系统、浏览器等等
2)访问特征:点击的url、从哪个url跳转过来的(referer)、页面上的停留时间等
3)访问信息:session_id、访问ip(访问城市)等

2013-05-19 13:00:00     http://www.taobao.com/17/?tracker_u=1624169&type=1      B58W48U4WKZCJ5D1T3Z9ZY88RU7QA7B1        http://hao.360.cn/      1.196.34.243   


数据处理流程
1)数据采集
	Flume: web日志写入到HDFS

2)数据清洗
	脏数据
	Spark、Hive、MapReduce 或者是其他的一些分布式计算框架  
	清洗完之后的数据可以存放在HDFS(Hive/Spark SQL)

3)数据处理
	按照我们的需要进行相应业务的统计和分析
	Spark、Hive、MapReduce 或者是其他的一些分布式计算框架

4)处理结果入库
	结果可以存放到RDBMS、NoSQL

5)数据的可视化
	通过图形化展示的方式展现出来:饼图、柱状图、地图、折线图
	ECharts、HUE、Zeppelin



UserAgent



hadoop jar /home/hadoop/lib/hadoop-train-1.0-jar-with-dependencies.jar com.imooc.hadoop.project.LogApp /10000_access.log /browserout
本文参与 腾讯云自媒体分享计划 ,欢迎热爱写作的你一起参与!
本文分享自作者个人站点/博客:https://blog.csdn.net/weixin_43469680复制
如有侵权,请联系 cloudcommunity@tencent.com 删除。
登录 后参与评论
0 条评论

相关文章

  • 史上最快! 10小时大数据入门实战(六)- Hadoop 项目实战1 用户行为日志概述离线数据处理架构3 项目需求4 UserAgent 类实现5

    JavaEdge
  • 大数据经典学习路线(及供参考)不容错过

    熟练使用Linux,熟练安装Linux上的软件,了解熟悉负载均衡、高可靠等集群相关概念,搭建互联网高并发、高可靠的服务架构;

    用户2292346
  • 史上最新最全面的java大数据学习路线(新手小白必看版本)

    2.1.1 VMware Workstation虚拟软件安装过程、CentOS虚拟机安装过程

    全栈程序员站长
  • 图解大数据 | 导论-大数据生态与应用

    教程地址:http://www.showmeai.tech/tutorials/84

    ShowMeAI
  • 0基础学习大数据,你需要了解的学习路线和方向?

    现在大数据这么火,各行各业想转行大数据,那么问题来了,该往哪方面发展,哪方面最适合自己?

    用户2292346
  • 大数据开发学习,大数据学习路线(完整详细版)[通俗易懂]

    很多初学者,对大数据的概念都是模糊不清的,大数据是什么,能做什么,学的时候,该按照什么线路去学习,学完往哪方面发展,想深入了解,想学习的同学欢迎加入大数据学习...

    全栈程序员站长
  • Hadoop概念学习系列之Hadoop、Spark学习路线(很值得推荐)

    说在前面的话   此笔,对于仅对于Hadoop和Spark初中学者。高手请忽略! 1 Java基础: 视频方面:           推荐《毕向东JAVA基础...

    庞小明
  • 年薪50W大数据工程师入门学习路线

    视频方面: 推荐《毕向东JAVA基础视频教程》。学习hadoop不需要过度的深入,java学习到javase,在Java虚拟机的内存管理、...

    用户1667431
  • 大数据学习过程中需要看些什么书?学习路线

    很多朋友对大数据行业心向往之,却苦于不知道该如何下手。作为一个零基础大数据入门学习者该看哪些书?今天给大家推荐一位知乎网友挖矿老司机的指导贴,作为参考。

    用户2292346
  • Hadoop视频教程汇总

    一 慕课网 1.Hadoop大数据平台架构与实践--基础篇(已学习) 链接:https://www.imooc.com/learn/391 2.Hadoop进阶...

    庞小明
  • 喊了这么多年大数据?你确定了解大数据?

    在科技如此兴盛的时代,人类社会实践产生了海量的全样数据、虚拟化、分布式集群、人工智能和深度学习算法等大数据和云计算技术,这些技术的出现意味着能更好地解决传统数据...

    Java高级架构
  • ​大数据入门学习指南

    大数据入门核心技术栏目是为初学者精心打造入门大数据必学知识整理,内容十分丰富,集合将近200篇高质文章带你轻松学习。

    Lanson
  • 0基础入门大数据开发学习的经典书籍推荐

    本书内容丰富,展示了如何使用Hadoop构建可靠、可伸缩的分布式系统,程序员可从中探索如何分析海量数据集,管理员可以了解如何建立与运行Hadoop集群。

    加米谷大数据
  • 【数据分析】大数据下的用户行为分析

    1. Consumer behaviour is the study of when,why,how and where people do or don't ...

    陆勤_数据人网
  • 不错的大数据课程体系(感谢某机构,希望不属于侵权)

    阶段一、大数据、云计算 - Hadoop大数据开发技术 课程一、大数据运维之Linux基础 本部分是基础课程,帮大家进入大数据领域打好Linux基础,以便更好地...

    用户1220053
  • 2019精炼的大数据技术学习路线

    近年来大数据BigData、人工智能AI、物联网Iot等行业发展迅猛,很多人都想要从事大数据技术开发工作,但是,请问要怎么做,路线是什么?从哪里开始学?学哪些?...

    用户2292346
  • 推荐10本大数据领域必读的经典好书(火速收藏)

    写博客也已经快一年了,从去年的1024到现在金秋10月已纷至沓来。回顾这一年所发布的原创文章,基本都是与大数据主流或者周边的技术为主。本篇博客,...

    大数据梦想家
  • 十分钟走进大数据世界

    大数据(big data),指无法在一定时间范围内用常规软件工具进行捕捉、管理和处理的数据集合,是需要新处理模式才能具有更强的决策力、洞察发现力和流程优化能力的...

    先知先觉
  • 开发大数据基础教程(前端开发入门)

    第一阶段:linux+搜索+hadoop体系Linux大纲这章是基础课程,帮大家进入大数据领域打好Linux基础,以便更好地学习Hadoop,hbase,NoS...

    全栈程序员站长

扫码关注腾讯云开发者

领取腾讯云代金券