2021-02-08/09 大数据课程笔记 day19day20 某大型网站日志分析离线系统

该项目旨在分析某大型网站的用户行为,包括用户基本信息、浏览器信息、地域信息、访问深度、外链数据、订单数据和事件。系统采用JS SDK和JAVA SDK收集数据,通过Flume读取Nginx日志,经过ETL处理后存储到Hadoop,最后使用Hive进行数据分析并导出到MySQL。项目涉及数据来源设计、系统架构、JS和JAVA SDK的工作流程,以及数据处理和存储的各个环节。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

时间煮雨
@R星校长

某大型网站日志分析离线系统

项目需求分析

概述

该部分的主要目标就是描述本次项目最终七个分析模块的界面展示。

工作流

  在我们的 demo 展示中,我们使用 jquery+echarts 的方式调用程序后台提供的 rest api 接口,获取 json 数据,然后通过 jquery+css 的方式进行数据展示。工作流程如下:在这里插入图片描述

分析

总述

在本次项目中我们分别从七个大的角度来进行分析,分别为:

用户基本信息分析模块
浏览器信息分析模块
地域信息分析模块
用户浏览深度分析模块
外链数据分析模块
订单分析模块
事件分析模块

下面就每个模块进行最终展示的分析。
注意几个概念:

  1. 用户/访客:表示同一个浏览器代表的用户。唯一标示用户
  2. 会员:表示网站的一个正常的会员用户。
  3. 会话:一段时间内的连续操作,就是一个会话中的所有操作。
  4. PV:访问页面的数量 pageview
  5. 在本次项目中,所有的计数都是去重过的。比如:活跃用户/访客,计算 uuid 的去重后的个数。
用户基本信息分析模块

用户基本信息分析模块主要是从用户/访客和会员两个主要角度分析浏览相关信息,包括但不限于新增用户,活跃用户,总用户,新增会员,活跃会员,总会员以及会话分析等。下面就各个不同的用户信息角度来进行分析:

用户分析

该分析主要分析新增用户、活跃用户以及总用户的相关信息。
新访客:老访客(活跃访客中) = 1:7~10
活跃用户,是相对于“流失用户”的一个概念,是指那些会时不时地光顾下网站,并为网站带来一些价值的用户。
简单理解就是经常访问该网站的用户,如浏览商品了,下单了,收藏了等行为。

新访客数:一天的独立访客中,历史第一次访问您网站的访客数;老访客数:今日之前有过访问,且今日再次访问的访客,记为老访客。在这里插入图片描述

会员分析

该分析主要分析新增会员、活跃会员以及总会员的相关信息。在这里插入图片描述

会话分析

该分析主要分析会话个数、会话长度和平均会话长度相关的信息。在这里插入图片描述

Hourly分析

该分析主要分析每天每小时的用户、会话个数以及会话长度的相关信息。在这里插入图片描述

浏览器信息分析模块

在用户基本信息分析的基础上添加一个浏览器这个维度信息。

浏览器用户分析

同用户分析。在这里插入图片描述

浏览器会员分析

同会员分析。在这里插入图片描述

浏览器会话分析

同会话分析。在这里插入图片描述

浏览器 PV 分析
分析各个浏览器的 pv 值。

在这里插入图片描述

地域信息分析模块

主要分析各个不同省份的用户和会员情况。

活跃访客地域分析

分析各个不同地域的活跃访客数量。在这里插入图片描述

跳出率分析

  分析各个不同地域的跳出率情况。

  一个网站在某一段时间内有 1000 不同访客从这个链接进入,同时这些访客中有 50 个人没有二次浏览行为,直接退出网站,那么针对这个入口网址的跳出率就是 50/1000=5%。在这里插入图片描述

用户访问深度分析模块

  该模块主要分析用户的访问记录的深度,用户在一个会话中访问页面的数量。

  网站访问深度就是用户在一次浏览你的网站的过程中浏览了你的网站的页数。如果用户一次性的浏览了你的网站的页数越多,那么就基本上可以认定,你的网站有他感兴趣的东西。用户访问网站的深度用数据可以理解为网站平均访问的页面数,就是 PV 和 uv 的比值,这个比值越大,用户体验度越好,网站的粘性也越高。
  此处 UV 可以理解为 cookie 中的 UUID 数量。在这里插入图片描述

外链数据分析模块

主要分析各个不同外链端带来的用户访问量数据。

外链就是指在别的网站导入自己网站的链接。导入链接对于网站优化来说是非常重要的一个过程。导入链接的质量(即导入链接所在页面的权重)间接影响了我们的网站在搜索引擎中的权重。
意义在于要不要做这个外链推广。

外链偏好分析

分析各个外链带来的活跃访客数量。在这里插入图片描述

外链会话(跳出率)分析

分析会话相关信息,并计算相关会话跳出率的情况。在这里插入图片描述

订单数据分析模块

主要分析订单的相关情况在这里插入图片描述

事件分析模块

在本次项目中,只选用一个事件案例进行分析,就是订单相关的一个事件分析。
预留模块。在这里插入图片描述

系统架构:在这里插入图片描述

虚拟机分配:

node1 hadoop,hbase,mysql-server,nginx,flume
node2 hadoop,hbase,zookeeper,hiveserver2
node3 hadoop,hbase,zookeeper,hiveserver2,sqoop,
node4 hadoop,hbase,zookeeper,beeline

JS SDK

概述

该文档的主要作用是为了开发人员参考可以参考本文档,了解 js sdk 的集成方式以及提供的各种不同的 api。
注意:不采用 ip 来标示用户的唯一性,我们通过在 cookie 中填充一个 uuid 来标示用户的唯一性。

埋点:
初级埋点:在产品流程关键部位植相关统计代码,用来追踪每次用户的行为,统计关键流程的使用程度。
中级埋点:植入多段动作代码,追踪用户在该模块每个界面上的系列行为,事件之间相互独立
高级埋点:联合公司工程、ETL 采集分析用户全量行为,建立用户画像,还原用户行为模型,作为产品分析、优化的基础。

Js sdk 执行工作流

在我们的 js sdk 中按照收集数据的不同分为不同的事件,比如 pageview 事件等。Js sdk 的执行流程如下:在这里插入图片描述

数据参数说明

在各个不同事件中收集不同的数据发送到 nginx 服务器,但是实际上这些收集到的数据还是有一些共性的。下面将所用可能用到的参数描述如下:

参数名称 类型 描述
en string 事件名称, eg: e_pv
ver string 版本号, eg: 0.0.1
pl string 平台, eg: website,iso,android
sdk string Sdk类型, eg: js java
b_rst string 浏览器分辨率,eg: 1800*678
b_iev string 浏览器信息useragent 火狐控制台输入:window.navigator.userAgent"Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:76.0) Gecko/20100101 Firefox/76.0"
u_ud string 用户/访客唯一标识符
l string 客户端语言
u_mid string 会员id,和业务系统一致
u_sd string 会话id
c_time string 客户端时间
p_url string 当前页面的url
p_ref string 上一个页面的url
tt string 当前页面的标题
ca string Event事件的Category名称
ac string Event事件的action名称
kv_* string Event事件的自定义属性
du string Event事件的持续时间
oid string 订单id
on string 订单名称
cua string 支付金额
cut string 支付货币类型
pt string 支付方式

PC 端事件分析

  针对我们最终的不同分析模块,我们需要不同的数据,接下来分别从各个模块分析,每个模块需要的数据。
  用户基本信息就是用户的浏览行为信息分析,也就是我们只需要 pageview 事件就可以了;
  浏览器信息分析以及地域信息分析其实就是在用户基本信息分析的基础上添加浏览器和地域这个维度信息,其中浏览器信息我们可以通过浏览器的window.navigator.userAgent来进行分析,
  地域信息可以通过 nginx 服务器来收集用户的 ip 地址来进行分析,也就是说 pageview 事件也可以满足这两个模块的分析。
外链数据分析以及用户浏览深度分析我们可以在 pageview 事件中添加访问页面的当前 url 和前一个页面的 url 来进行处理分析,也就是说 pageview 事件也可以满足这两个模块的分析。
  订单信息分析要求 pc 端发送一个订单产生的事件,那么对应这个模块的分析,我们需要一个新的事件 chargeRequest。
  对于事件分析我们也需要一个 pc 端发送一个新的事件数据,我们可以定义为 event。除此之外,我们还需要设置一个 launch 事件来记录新用户的访问。
  pc 端的各种不同事件发送的数据 url 格式如下,其中 url 中后面的参数就是我们收集到的数据:http://bjsxt.com/bjsxt.gif?requestdata
在这里插入图片描述

Launch 事件

当用户第一次访问网站的时候触发该事件,不提供对外调用的接口,只实现该事件的数据收集。在这里插入图片描述

Pageview 事件

当用户访问页面/刷新页面的时候触发该事件。该事件会自动调用,也可以让程序员手动调用。在这里插入图片描述

chargeRequest 事件

当用户下订单的时候触发该事件,该事件需要程序主动调用。在这里插入图片描述在这里插入图片描述

Event 事件

当访客/用户触发业务定义的事件后,前端程序调用该方法。在这里插入图片描述

其他 api 方法

在这里只介绍设置会员 id 的方法,其他的辅助方法到时候编写js的时候再介绍。
设置会员 id在这里插入图片描述

JAVA SDK

概述

该文档的主要作用是为了开发人员参考可以参考本文档,了解 java sdk 的集成方式以及提供的各种不同的方法。注意:由于在本次项目中 java sdk 的作用主要就是发送支付成功/退款成功的信息给 nginx 服务器,所有我们这里提供的是一个简单版本的 java sdk。

Java sdk 执行工作流

订单支付成功的工作流如下所示:(订单退款类似) Controller(比如:servlet)调用该方法
在这里插入图片描述

程序后台事件分析

本项目中在程序后台只会触发 chargeSuccess 事件,本事件的主要作用是发送订单成功的信息给 nginx 服务器。发送格式同 pc 端发送方式, 也是访问同一个 url 来进行数据的传输。格式为:
http://bjsxt.com/bjsxt.jpg?requestdata e_crt
在这里插入图片描述

chargeSuccess 事件

当会员最终支付成功的时候触发该事件,该事件需要程序主动调用。
在这里插入图片描述

参数 类型 是否必填 描述
orderId string 订单id
memberId string 会员id

4.3.2 chargeRefund 事件
当会员进行退款操作的时候触发该事件,该事件需要程序主动调用。
在这里插入图片描述
在这里插入图片描述

集成方式

直接将 java 的 sdk 引入到项目中即可,或者添加到 classpath 中。

数据参数说明

参数描述如下:

参数名称 类型 描述
en string 事件名称, eg: e_cs
ver string 版本号, eg: 0.0.1
pl string 平台, eg: website,javaweb,php
sdk string Sdk类型, eg: java,js
u_mid string 会员id,和业务系统一致
c_time string 客户端时间
oid string 订单id

数据来源设计

项目搭建

  1. 新建一个空项目:在这里插入图片描述
    输入项目名称:在这里插入图片描述
    创建Module:在这里插入图片描述
    选择 JavaEE 版本:在这里插入图片描述在这里插入图片描述在这里插入图片描述
    File->Project Stucture->Modules-> + ->Web在这里插入图片描述
  2. 解压:big_data_log2.zip,并将对应的内容拷贝到刚刚创建的 Module 中
    A. 将 com 包拷贝到 src 目录下。
    B. 向将 web 目录下内容清空,然后将提供代码的 web 目录下的所有内容拷贝到 web 目录下。
    C. 选择 lib 文件夹,右键 Add as Library…
    D. 最终效果入右图所示:在这里插入图片描述

配置 tomcat

  1. apache-tomcat-7.0.69.zip解压到 D:\devsoft
  2. 配置 tomcat
    在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述
  3. 启动项目在这里插入图片描述在这里插入图片描述

代码分析

(function(){…})()

先看js/analytics.js,很可能(function(){....})()看不懂,接下来先讲解它:

  1. 创建 my.js,在 index.jsp 中通过 script 标签引入:
<script type="text/javascript" src="./js/my.js"></script>
  1. 编辑 my.js
function load() {
   
    alert("hello js");
}
load();

(function load2() {
   
    alert("hello js load2");
})();

(function() {
   
    alert("hello js function no name");
})();

三种方式逐步递进,演示后面的时候,需要将前面的内容注释掉。

  1. 然后阅读 analytics.js 的 CookieUtil ,编写代码学习:
    将 my.js 的其它代码都注释掉,并添加以下代码:
(function() {
   
    var myJson={
   
        name:"zhangsan",
        age:25,
        say:function () {
   
            alert("大家好,我是"+this.name+",我今年"+this.age+"岁了");
        }
    };
    //打印myJson的name属性
    alert(myJson.name);
    //调用闭包
    myJson.say();
})();

然后测试。CookieUtil 具体的代码先不用研究。
4. var tracker 分析

columns : {
   
   // 发送到服务器的列名称
   eventName : "en",//事件名称, eg: e_pv
   version : "ver",//版本号, eg: 0.0.1
   platform : "pl",//平台, eg: website,iso,android
   sdk : "sdk",//Sdk类型, eg: js  java
   uuid : "u_ud",//浏览器分辨率,eg: 1800*678
   memberId : "u_mid",//会员id,和业务系统一致
   sessionId : "u_sd",//会话id
   clientTime : "c_time",//客户端时间
   language : "l",//客户端语言
   userAgent : "b_iev",//浏览器信息useragent
   resolution : "b_rst",//浏览器分辨率,eg: 1800*678
   currentUrl : "p_url",//当前页面的url
   referrerUrl : "p_ref",//上一个页面的url
   title : "tt",//当前页面的标题
   orderId : "oid",//订单id
   orderName : "on",//订单名称
   currencyAmount : "cua",//支付金额
   currencyType : "cut",//支付货币类型
   paymentType : "pt",//支付方式
   category : "ca",//Event事件的Category名称
   action : "ac",//Event事件的action名称
   kv : "kv_",//Event事件的自定义属性
   duration : "du"//Event事件的持续时间
},
  1. window.AE
  2. autoLoad()阅读相关的代码,onLaunch事件、onPageView事件会自动触发。
  3. onChargeRequest事件在demo2.jsp中点击按钮触发
  4. onEventDuration事件在demo3.jsp中点击按钮触发
Java代码分析

AnalyticsEngineSDK、SendDataMonitor 看明白之后,运行 Test 类看控制台信息。

nginx 本地存储日志

安装 nginx 或者 tengine

  1. 安装依赖 gcc openssl-devel pcre-devel zlib-devel
    安装:yum install gcc openssl-devel pcre-devel zlib-devel -y
  2. 上传与解压
  3. 配置 Nginx
    ./configure
  4. 编译与安装
    make && make install
    默认安装目录:
    /usr/local/nginx

配置 nginx 的 init 启动服务

  1. 在/etc/init.d/目录新建nginx,编辑如下内容:
[root@node1 tengine-2.1.0]# cd /etc/init.d/
[root@node1 init.d]# vim nginx
#!/bin/bash
#
# nginx - this script starts and stops the nginx daemon
#
# chkconfig:   - 85 15 
# description:  Nginx is an HTTP(S) server, HTTP(S) reverse \
#               proxy and IMAP/POP3 proxy server
# processname: nginx
# config:      /etc/nginx/nginx.conf
# config:      /etc/sysconfig/nginx
# pidfile:     /var/run/nginx.pid
 
# Source function library.
. /etc/rc.d/init.d/functions
 
# Source networking configuration.
. /etc/sysconfig/network
 
# Check that networking is up.
[ "$NETWORKING" = "no" ] && exit 0
 
nginx="/usr/local/nginx/sbin/nginx"
prog=$(basename $nginx)
 
NGINX_CONF_FILE="/usr/local/nginx/conf/nginx.conf"
 
[ -f /etc/sysconfig/nginx ] && . /etc/sysconfig/nginx
 
lockfile=/var/lock/subsys/nginx
make_dirs() {
   
   # make required directories
   user=`nginx -V 2>&1 | grep "configure arguments:" | sed 's/[^*]*--user=\([^ ]*\).*/\1/g' -`
   options=`$nginx -V 2>&1 | grep 'configure arguments:'`
   for opt in $options; do
       if [ `echo $opt | grep '.*-temp-path'` ]; then
           value=`echo $opt | cut -d "=" -f 2`
           if [ ! -d "$value" ]; then
               # echo "creating" $value
               mkdir -p $value && chown -R $user $value
           fi
       fi
   done
}
 
start() {
   
    [ -x $nginx ] || exit 5
    [ -f $NGINX_CONF_FILE ] || exit 6
    make_dirs
    echo -n $"Starting $prog: "
    daemon $nginx -c $NGINX_CONF_FILE
    retval=$?
    echo
    [ $retval -eq 0 ] && touch $lockfile
    return $retval
}
 
stop() {
   
    echo -n $"Stopping $prog: "
    killproc $prog -QUIT
    retval=$?
    echo
    [ $retval -eq 0 ] && rm -f $lockfile
    return $retval
}
 
restart() {
   
    configtest || return $?
    stop
    sleep 1
    start
}
 
reload() {
   
    configtest || return $?
    echo -n $"Reloading $prog: "
    killproc $nginx -HUP
    RETVAL=$?
    echo
}
 
force_reload() {
   
    restart
}
 
configtest() {
   
  $nginx -t -c $NGINX_CONF_FILE
}
 
rh_status() {
   
    status $prog
}
 
rh_status_q() {
   
    rh_status >/dev/null 2>&1
}
 
case "$1" in
    start)
        rh_status_q && exit 0
        $1
        ;;
    stop)
        rh_status_q || exit 0
        $1
        ;;
    restart|configtest)
        $1
        ;;
    reload)
        rh_status_q || exit 7
        $1
        ;;
    force-reload)
        force_reload
        ;;
    status)
        rh_status
        ;;
    condrestart|try-restart)
        rh_status_q || exit 0
            ;;
    *)
        echo $"Usage: $0 {start|stop|status|restart|condrestart|try-restart|reload|force-reload|configtest}"
        exit 2
esac
  1. 并赋予可执行权限:
[root@node1 init.d]# chmod +x nginx
  1. 添加该文件到系统服务中去
[root@node1 init.d]# chkconfig --add nginx 
  1. 查看是否添加成功
[root@node1 init.d]# chkconfig --list nginx
  1. 启动,停止,重新装载
service nginx start|stop|restart
  1. 设置开机启动 nginx
[root@node1 init.d]# chkconfig nginx on
  1. 测试,打开浏览器,输入:http://192.168.20.71/ 出现 tengine 欢迎页面表示安装配置成功

日志定义

查看默认记录的日志
[root@node1 init.d]# whereis nginx
nginx: /usr/local/nginx
[root@node1 init.d]# cd /usr/local/nginx/
[root@node1 nginx]# ls
client_body_temp  html     modules     scgi_temp
conf              include  proxy_temp  uwsgi_temp
fastcgi_temp      logs     sbin
[root@node1 nginx]# ls logs/
access.log  error.log  nginx.pid
[root@node1 nginx]# cd logs/
[root@node1 logs]# pwd
/usr/local/nginx/logs
[root@node1 logs]# tail -f access.log 
192.168.20.1 - - [15/May/2020:22:48:32 +0800] "GET / HTTP/1.1" 200 555 "-" "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.109 Safari/537.36"
配置 tengine 的日志格式

官方文档地址:

http://tengine.taobao.org/nginx_docs/cn/docs/http/ngx_http_log_module.html
http://tengine.taobao.org/nginx_docs/cn/docs/http/ngx_http_core_module.html#variables

http_host 显示服务器所在的地址
编辑 nginx.conf 文件:

[root@node1 conf]# pwd
/usr/local/nginx/conf
[root@node1 conf]# vim nginx.conf
log_format my_format '$remote_addr^A$msec^A$http_host^A$request_uri';
#http://node1/log.gif?fdsafdsa
location /log.gif {
   
     default_type  image/gif;
 access_log  /opt/data/access.log  my_format;
}

重启加载 nginx

[root@node1 conf]# service nginx reload
the configuration file /usr/local/nginx/conf/nginx.conf syntax is ok
configuration file /usr/local/nginx/conf/nginx.conf test is successful
Reloading nginx: 【ok】
测试
  1. 查看新指定的日志目录和日志文件是否新建成功
[root@node1 conf]# cd /opt/
[root@node1 opt]# ls
apps  data  hadoop-2.6.5  hbase-0.98
[root@node1 opt]# cd data/
[root@node1 data]# ls
access.log
  1. 测试日志是否记录:http://node1/log.gif
    404 解决办法,在/usr/local/nginx/html目录下上传一张 log.gif 图片:
[root@node1 html]# pwd
/usr/local/nginx/html
[root@node1 html]# ls
50x.html  index.html  log.gif
[root@node1 data]# tail -f access.log 
192.168.20.1^A1589556277.121^Anode1^A/log.gif
  1. 测试日志是否记录:http://localhost:8080/demo2.jsp
    访问页面发现日志没有记录,修改analytics.js:在这里插入图片描述
  2. 查看日志信息是否完成:
192.168.20.1^A1589557481.745^Anode1^A/log.gif?en=e_pv&p_url=https%3A%2F%2F2.zoppoz.workers.dev%3A443%2Fhttp%2Flocalhost%3A8080%2Fdemo4.jsp&p_ref=https%3A%2F%2F2.zoppoz.workers.dev%3A443%2Fhttp%2Flocalhost%3A8080%2Fdemo2.jsp&tt=%E6%B5%8B%E8%AF%95%E9%A1%B5%E9%9D%A24&ver=1&pl=%E5%A4%A7234470100&sdk=js&u_ud=46D00DCD-187C-4BA8-8014-358F8DE85474&u_mid=zhangsan&u_sd=E96DC9DE-2590-4E95-B6C3-3E74BCFD88EF&c_time=1589557480505&l=zh-CN&b_iev=Mozilla%2F5.0%20(Windows%20NT%2010.0%3B%20Win64%3B%20x64%3B%20rv%3A76.0)%20Gecko%2F20100101%20Firefox%2F76.0&b_rst=1920*1080
  1. Java 测试
    运行\com\sxt\log\test\Test.java,查看日志文件,能够记录下来。

Flume 读取 nginx 的本地 log

Flume概述:

介绍

官网地址:http://flume.apache.org
本课程选择版本对应的官方文档:
http://flume.apache.org/releases/content/1.6.0/FlumeUserGuide.html
官方介绍:

  1. Apache Flume 是一个分布式、可靠和可用的系统,用于有效地收集、聚合和将大量日志数据从许多不同的来源转移到集中式数据存储。
  2. Apache Flume 的使用不仅限于日志数据聚合。 由于数据源是可定制的,Flume可以用来传输大量的事件数据,包括但不限于网络流量数据、社交媒体生成的数据、电子邮件消息和几乎任何可能的数据源。
  3. Apache Flume 是 Apache 软件基金会的顶级项目。
系统需求在这里插入图片描述

java 环境 - java 1.6 或更高版本(推荐 Java 1.7)
内存 - sources、channels 和 sinks 所用的足够的内存
磁盘空间 - channels 和 sinks 用到的足够的磁盘空间
目录权限 - flume 的 agent 用到的目录读写权限

Data flow model在这里插入图片描述

安装与配置

  1. 上传 apache-flume-1.6.0-bin.tar.gznode1/opt/apps 目录下
  2. 解压并重命名
[root@node1 apps]# tar -zxvf apache-flume-1.6.0-bin.tar.gz -C /opt/
[root@node1 apps]# cd /opt
[root@node1 opt]# mv apache-flume-1.6.0-bin/ flume 
  1. 删除 docs 目录
[root@node1 opt]# ls
apps  data  flume  hadoop-2.6.5  hbase-0.98
[root@node1 opt]# cd flume/
[root@node1 flume]# ls 
bin  CHANGELOG  conf  DEVNOTES  docs  lib  LICENSE  NOTICE  README  RELEASE-NOTES  tools
[root@node1 flume]# rm -rf docs/
  1. 修改配置
[root@node1 conf]# mv flume-env.sh.template flume-env.sh
[root@node1 conf]# vim flume-env.sh 
export JAVA_HOME=/usr/java/jdk1.8.0_221-amd64
  1. 配置 flume 环境变量,并让配置文件生效
[root@node1 ~]# vim /etc/profile
export FLUME_HOME=/opt/flume
export PATH=$PATH:$JAVA_HOME/bin:$HADOOP_HOME/bin:$HADOOP_HOME/sbin:$HBASE_HOME/bin:$FLUME_HOME/bin
[root@node1 ~]# source /etc/profile
  1. 验证安装是否成功
[root@node1 ~]# flume-ng version
Flume 1.6.0
Source code repository: https://git-wip-us.apache.org/repos/asf/flume.git
Revision: 2561a23240a71ba20bf288c7c2cda88f443c2080
Compiled by hshreedharan on Mon May 11 11:15:44 PDT 2015
From source with checksum b29e416802ce9ece3269d34233baf43f 
  1. A simple example
    在这里,我们给出一个示例配置文件,描述一个单节点Flume部署。 此配置允许用户生成事件并随后将其记录到控制台。
[root@node1 ~]# vim option.properties
# example.conf: A single-node Flume configuration
# Name the components on this agent
a1.sources = r1
a1.sinks = k1
a1.channels = c1

# Describe/configure the source
a1.sources.r1.type = netcat
a1.sources.r1.bind = node1
a1.sources.r1.port = 44444

# Describe the sink
a1.sinks.k1.type = logger  
# Use a channel which buffers events in memory
a1.channels.c1.type = memory  #内存
a1.channels.c1.capacity = 1000  #容量1000条
a1.channels.c1.transactionCapacity = 100 #每次传输100条

# Bind the source and sink to the channel
a1.sources.r1.channels = c1  #将source和channel连接
a1.sinks.k1.channel = c1  #量sink和channel连接

配置时不带中文注释。

  1. 查看帮助
[root@node1 conf]# flume-ng help
Usage: /opt/flume/bin/flume-ng <command> [options]...

  -Dproperty=value          sets a Java system property value指定java的系统属性值
  -Xproperty=value          sets a Java -X option
 
agent options:
  --name,-n <name>          the name of this agent (required)指定代理的名称
  --conf-file,-f <file>     specify a config file (required if -z missing)如果不指定-z选项,则必须指定配置文件
  --zkConnString,-z <str>   specify the ZooKeeper connection to use 
  1. 启动
[root@node1 ~]#flume-ng agent -n a1 --conf-file option.properties -Dflume.root.logger=INFO,console

在这里插入图片描述在这里插入图片描述
测试

  1. 打开一个连接 node2 的 xshell 终端,安装 telnet
[root@node2 ~]# yum install telnet -y
[root@node2 ~]# telnet node1 44444
Trying 192.168.20.71...
Connected to node1.
Escape character is '^]'.
OK
A
hello gtjin
OK
  1. 查看 node1 的变化
20/05/16 16:12:22 INFO sink.LoggerSink: Event: {
    headers:{
   } body: 41 0D                                           A. }
20/05/16 16:02:23 INFO sink.LoggerSink: Event: {
    headers:{
   } body: 68 65 6C 6C 6F 20 67 74 6A 69 6E 0D             hello gtjin. }

Setting multi-agent flow串联在这里插入图片描述

  1. Ctrl+c 关闭 node1 的 flume,并将安装包远程拷贝到 node3
[root@node1 ~]# cd /opt/
[root@node1 opt]# ls
apps  data  flume  hadoop-2.6.5  hbase-0.98
[root@node1 opt]# scp -r flume/ node3:/opt/
  1. node3 上配置环境变量
[root@node3 ~]# vim /etc/profile
export FLUME_HOME=/opt/flume
export
PATH=$PATH:$JAVA_HOME/bin:$ZOOKEEPER_HOME/bin:$HADOOP_HOME/bin:$HADOOP_HOME/sbin:$HIVE_HOME/bin:$HBASE_HOME/bin:$FLUME_HOME/bin
[root@node3 ~]# source /etc/profile
  1. 将 node1 上配置文件 option.properties 拷贝一份 option1.properties ,并修改:
    参考参数:
    http://flume.apache.org/releases/content/1.6.0/FlumeUserGuide.html#avro-sink
# example.conf: A single-node Flume configuration

# Name the components on this agent
a1.sources = r1
a1.sinks = k1
a1.channels = c1

# Describe/configure the source
a1.sources.r1.type = netcat
a1.sources.r1.bind = node1
a1.sources.r1.port = 44444

# Describe the sink
a1.sinks.k1.type = avro
a1.sinks.k1.hostname = node3 
a1.sinks.k1.port = 10086

# Use a channel which buffers events in memory
a1.channels.c1.type = memory
a1.channels.c1.capacity = 1000
a1.channels.c1.transactionCapacity = 100

# Bind the source and sink to the channel
a1.sources.r1.channels = c1
a1.sinks.k1.channel = c1
  1. 将 node1 上的 option.properties 拷贝到 node3 上,并修改
    参考官网:
    http://flume.apache.org/releases/content/1.6.0/FlumeUserGuide.html#avro-source
    node1上操作
[root@node1 ~]# scp option.properties node3:/root
option.properties                                        100%  541     0.5KB/s   00:00

node3 上操作

[root@node3 ~]# mv option.properties option3.properties 
[root@node3 ~]# vim option3.properties
# Name the components on this agent
a1.sources = r1
a1.sinks = k1
a1.channels = c1

# Describe/configure the source
a1.sources.r1.type = avro
a1.sources.r1.bind = node3
a1.sources.r1.port = 10086

# Describe the sink
a1.sinks.k1.type = logger

# Use a channel which buffers events in memory
a1.channels.c1.type = memory
a1.channels.c1.capacity = 1000
a1.channels.c1.transactionCapacity = 100

# Bind the source and sink to the channel
a1.sources.r1.channels = c1
a1.sinks.k1.channel = c1
  1. 启动 node3 上的 flume (由于 node1 发送给 node3 所以先启动 node3)
flume-ng agent -n a1 --conf-file option3.properties -Dflume.root.logger=INFO,console

再复制一个 xshell 终端:

[root@node3 ~]# ss -nal
State       Recv-Q Send-Q      Local Address:Port        Peer Address:Port 
LISTEN      0      128                    :::22                    :::*     
LISTEN      0      128                     *:22                     *:*     
LISTEN      0      100                   ::1:25                    :::*     
LISTEN      0      100             127.0.0.1:25                     *:*     
LISTEN      0      50       ::ffff:192.168.20.73:10086                 :::*  
  1. 启动 node1 上的 flume
flume-ng agent -n a1 --conf-file option1.properties -Dflume.root.logger=INFO,console 
  1. Node2 上发消息给 node1
[root@node2 ~]# telnet node1 44444
Trying 192.168.20.71...
Connected to node1.
Escape character is '^]'.
a
OK
b
OK
c
OK
  1. Node1 上没有显示信息,而是 node3 上显示信息,这是因为 node1 接收到消息后,传递给了 node3
20/05/16 18:41:01 INFO sink.LoggerSink: Event: {
    headers:{
   } body: 61 0D                                           a. }
20/05/16 18:41:01 INFO sink.LoggerSink: Event: {
    headers:{
   } body: 62 0D                                           b. }
20/05/16 18:41:01 INFO sink.LoggerSink: Event: {
    headers:{
   } body: 63 0D                                           c. } 
  1. 为什么需要串联呢?
    日志收集中一个非常常见的场景是大量的日志生成客户端向连接到存储子系统的几个消费代理发送数据。 例如,从数百个 Web 服务器收集的日志发送给十几个写入 HDFS 集群的代理在这里插入图片描述
    Flume 支持将事件流复用到一个或多个目的地。 这是通过定义一个可以复制或选择性地将事件路由到一个或多个通道的流复用器来实现的在这里插入图片描述

source 种类

  1. Avro Source
  2. Thrift Source
  3. Exec Source
  4. Spooling Directory Source
  5. Kafka Source
  6. NetCat Source
exec source 案例

  Exec source runs a given Unix command on start-up and expects that process to continuously produce data on standard out (stderr is simply discarded, unless property logStdErr is set to true). If the process exits for any reason, the source also exits and will produce no further data. This means configurations such as cat [named pipe] or tail -F [file] are going to produce the desired results where as datewill probably not - the former two commands produce streams of data where as the latter produces a single event and exits.

  Exec source 在启动时运行给定的 Unix 命令,并期望该进程继续在标准输出上生成数据(stderr 被简单地丢弃,除非属性日志 Std Err 设置为 true)。 如果进程出于任何原因退出,源也将退出,不会产生进一步的数据。 这意味着配置,如 cat[命名管道] 或 tail-F[文件] 将产生所需的结果,其中 as date 可能不会-前两个命令产生数据流,其中后者产生单个事件并退出。在这里插入图片描述
Example for agent named a1:

a1.sources = r1
a1.channels = c1
a1.sources.r1.type = exec
a1.sources.r1.command = tail -F /var/log/secure
a1.sources.r1.channels = c1

具体实现步骤:

  1. 先停掉 node1 和 node3 上的 flume
  2. 将 node1 上的 option.properties 拷贝 option_exec.properties ,并修改:
[root@node1 ~]# cp option.properties option_exec.properties
[root@node1 ~]# vim option_exec.properties 
# Describe/configure the source
a1.sources.r1.type = exec
a1.sources.r1.command = tail -F /root/log.txt

# Describe the sink
  1. 启动 node1 上的 flume
flume-ng agent -n a1 --conf-file option_exec.properties -Dflume.root.logger=INFO,console 
  1. 复制一个 node1 连接的 xshell 终端
[root@node1 ~]# echo "hello bjsxt" >> log.txt
[root@node1 ~]# echo "hello" >> log.txt
  1. 然后在启动 flume 的终端中查看信息
20/05/16 21:29:37 INFO sink.LoggerSink: Event: {
    headers:{
   } body: 68 65 6C 6C 6F 20 62 6A 73 78 74                hello bjsxt }
20/05/16 21:29:59 INFO sink.LoggerSink: Event: {
    headers:{
   } body: 68 65 6C 6C 6F                                  hello }
Spooling Directory Source 案例

此源可以通过将要摄取的文件放入磁盘上的“假脱机”目录中来摄取数据。 此源将监视新文件的指定目录,并将在出现新文件时从新文件中解析事件。 事件解析逻辑可插拔… 在一个给定的文件被完全读入通道后,它被重命名以指示完成(或可选地删除)在这里插入图片描述
Example for an agent named agent-1:

a1.channels = ch-1
a1.sources = src-1
a1.sources.src-1.type = spooldir
a1.sources.src-1.channels = ch-1
a1.sources.src-1.spoolDir = /var/log/apache/flumeSpool
a1.sources.src-1.fileHeader = true

fileHeader 值为 true 表示显示信息从哪个文件中读取的,false 不显示。
具体配置步骤:

  1. 先停掉node1上的flume(ctrl+c)
  2. 将node1上的 option.properties拷贝option_sdir.properties,并修改:
[root@node1 ~]# cp option.properties option_sdir.properties
[root@node1 ~]# vim option_sdir.properties 


# Describe/configure the source
a1.sources.r1.type = spooldir
a1.sources.r1.spoolDir = /root/log
a1.sources.r1.fileHeader = true

# Describe the sink
  1. 启动 node1 上的 flume
flume-ng agent -n a1 --conf-file option_sdir.properties -Dflume.root.logger=INFO,console 

启动后抛出以下异常:

java.lang.IllegalStateException: Directory does not exist: /root/log

这是因为目录没有创建,创建目录后再次启动,则解决了。

[root@node1 ~]# mkdir log
[root@node1 ~]# flume-ng agent -n a1 --conf-file option_sdir.properties -Dflume.root.logger=INFO,console
  1. 复制一个 node1 连接的 xshell 终端,/root/log 目录下拷贝文本文件
[root@node1 ~]# cp log.txt log/
  1. 然后在启动 flume 的终端中查看信息
20/05/16 22:07:24 INFO sink.LoggerSink: Event: {
    headers:{
   file=/root/log/log.txt} body: 68 65 6C 6C 6F 20 62 6A 73 78 74                hello bjsxt }
20/05/16 22:07:24 INFO sink.LoggerSink: Event: {
    headers:{
   file=/root/log/log.txt} body: 68 65 6C 6C 6F                                  hello }
20/05/16 22:07:24 INFO avro.ReliableSpoolingFileEventReader: Last read took us just up to a file boundary. Rolling to the next file, if there is one.
20/05/16 22:07:24 INFO avro.ReliableSpoolingFileEventReader: Preparing to move file /root/log/log.txt to /root/log/log.txt.COMPLETED
  1. 然后 cd 到 /root/log 目录下查看信息
[root@node1 ~]# cd log/
[root@node1 log]# ls
install.log.COMPLETED  log.txt.COMPLETED
  1. 先停掉 node1 上的 flume(ctrl+c)
  2. 修改option_sdir.properties:
[root@node1 ~]# cp option.properties option_sdir.properties
[root@node1 ~]# vim option_sdir.properties 
# Describe/configure the source
a1.sources.r1.type = spooldir
a1.sources.r1.spoolDir = /root/log
a1.sources.r1.fileHeader = true
a1.sources.r1.fileSuffix = .sxt
# Describe the sink
  1. 启动 node1 上的 flume
flume-ng agent -n a1 --conf-file option_sdir.properties -Dflume.root.logger=INFO,console 

文件又被重新加载了依次。

  1. 进入 /root/log 目录查看
[root@node1 log]# ls
install.log.COMPLETED.sxt  log.txt.COMPLETED.sxt

flume sinks

HDFS Sink (使用较多)

参考网址:
http://flume.apache.org/releases/content/1.6.0/FlumeUserGuide.html#flume-sinks在这里插入图片描述
支持的逃逸字符:

别名 描述
%t Unix时间戳,毫秒
%{host} 替换名为"host"的事件header的值。支持任意标题名称。
%a 星期几的短名,即Mon, Tue, …
%A 星期几的全名,即Monday, Tuesday, …
%b 月份短名,即Jan, Feb, …
%B 月份全名,即January, February, …
%c 时间和日期,即Thu Mar 3 23:05:25 2005
%d day of month (01)
%e day of month without padding (1)
%D date; same as %m/%d/%y
%H hour (00…23)
%I hour (01…12)
%j day of year (001…366)
%k 小时 ( 0…23)
%m 月份 (01…12)
%n 不加前缀的月份 (1…12)
%M 分钟(00…59)
%p locale’s equivalent of am or pm
%s seconds since 1970-01-01 00:00:00 UTC
%S second (00…59)
%y 年份最后两位 (00…99)
%Y year (2010)
%z +hhmm数字时区 (for example, -0400)
属性名称 默认值 说明
channel -
type - 组件类型名称,必须是 hdfs
hdfs.path - HDFS路径,如hdfs://mycluster/flume/mydata
hdfs.filePrefix FlumeData flume在hdfs目录中创建文件的前缀
hdfs.fileSuffix - flume在hdfs目录中创建文件的后缀。
hdfs.inUsePrefix - flume正在写入的临时文件的前缀
hdfs.inUseSuffix .tmp flume正在写入的临时文件的后缀
hdfs.rollInterval 30 多长时间写一个新的文件 (0 = 不写新的文件),单位秒
hdfs.rollSize 1024 文件多大写新文件单位字节(0: 不基于文件大小写新文件)
hdfs.rollCount 10 当写一个新的文件之前要求当前文件写入多少事件(0 = 不基于事件数写新文件)
hdfs.idleTimeout 0 多长时间没有新增事件则关闭文件(0 = 不自动关闭文件)单位为秒
hdfs.batchSize 100 写多少个事件开始向HDFS刷数据
hdfs.codeC - 压缩格式:gzip, bzip2, lzo, lzop, snappy
hdfs.fileType SequenceFile 当前支持三个值:SequenceFile,DataStream,CompressedStream。(1)DataStream不压缩输出文件,不要设置codeC (2)CompressedStream 必须设置codeC
hdfs.maxOpenFiles 5000 最大打开多少个文件。如果数量超了则关闭最旧的文件
hdfs.minBlockReplicas - 对每个hdfs的block设置最小副本数。如果不指定,则使用hadoop的配置的值。1
hdfs.writeFormat - 对于sequence file记录的类型。Text或者Writable(默认值)
hdfs.callTimeout 10000 为HDFS操作如open、write、flush、close准备的时间。如果HDFS操作很慢,则可以设置这个值大一点儿。单位毫秒
hdfs.threadsPoolSize 10 每个HDFS sink的用于HDFS io操作的线程数 (open, write, etc.)
hdfs.rollTimerPoolSize 1 每个HDFS sink使用几个线程用于调度计时文件滚动。
hdfs.round false 支持文件夹滚动的属性。是否需要新建文件夹。如果设置为true,则会影响所有的基于时间的逃逸字符,除了%t。
hdfs.roundValue 1 该值与roundUnit一起指定文件夹滚动的时长,会四舍五入
hdfs.roundUnit second 控制文件夹个数。多长时间生成新文件夹。可以设置为- second, minute 或者 hour.
hdfs.timeZone Local Time Name of the timezone that should be used for resolving the directory path, e.g. America/Los_Angeles.
hdfs.useLocalTimeStamp false 一般设置为true,使用本地时间。如果不使用本地时间,要求flume发送的事件header中带有时间戳。该时间用于替换逃逸字符

案例1:每 5 秒在 hdfs 上创建一个新的文件夹

  1. 启动 hadoop 集群上的 hdfs
  2. 先停掉 node1 上的 flume(ctrl+c)
  3. 将 node1 上的 option_sdir.properties 拷贝 option_hdfs1.properties,并修改:
[root@node1 ~]# cp option_sdir.properties  option_hdfs1.properties
[root@node1 ~]# vim option_hdfs1.properties 
# Describe/configure the source
a1.sources.r1.type = spooldir
a1.sources.r1.spoolDir = /root/log
a1.sources.r1.fileHeader = true
a1.sources.r1.fileSuffix = .sxt
# Describe the sink
a1.sinks.k1.type = hdfs
# 时间会四舍五入
a1.sinks.k1.hdfs.path = /flume/events/%y-%m-%d/%H%M/%S
a1.sinks.k1.hdfs.filePrefix = events-
a1.sinks.k1.hdfs.round = true
a1.sinks.k1.hdfs.roundValue = 5
a1.sinks.k1.hdfs.roundUnit = second
a1.sinks.k1.hdfs.useLocalTimeStamp=true

# Use a channel which buffers events in memory
.....

如果不配置a1.sinks.k1.hdfs.useLocalTimeStamp=true,flume在启动(存在未被处理的文件时)或执行步骤6的时候抛以下异常:在这里插入图片描述

  1. 启动 node1 上的 flume
flume-ng agent -n a1 --conf-file option_hdfs1.properties -Dflume.root.logger=INFO,console 
  1. 通过浏览器node2:50070访问 hdfs 目录,发现 /flume 并不存在。
  2. 复制一个 node1 连接的 xshell 终端,/root/log 目录下拷贝文本文件
[root@node1 ~]# cp log.txt log/
[root@node1 ~]# cp hh.txt log/
[root@node1 ~]# cp wc.txt log/
  1. 然后在启动 flume 的终端中查看信息在这里插入图片描述
  2. 通过浏览器 node2:50070 访问 hdfs 目录,发现 /flume 出现了在这里插入图片描述在这里插入图片描述在这里插入图片描述
    注意:如果你的电脑比较慢可以添加一个属性:
a1.sinks.k1.hdfs.callTimeout=60000

案例2:每100条记录写到一个文件中

# Describe the sink
a1.sinks.k1.type = hdfs
# 时间会四舍五入
a1.sinks.k1.hdfs.path = /flume/events/%y-%m-%d/%H%M
a1.sinks.k1.hdfs.filePrefix = events-
a1.sinks.k1.hdfs.rollInterval=0
a1.sinks.k1.hdfs.rollSize=0
# 10个记录写到一个文件中,然后滚动输出
a1.sinks.k1.hdfs.rollCount=10
a1.sinks.k1.hdfs.round = true
a1.sinks.k1.hdfs.roundValue = 2
a1.sinks.k1.hdfs.roundUnit = minute
a1.sinks.k1.hdfs.useLocalTimeStamp=true
a1.sinks.k1.hdfs.callTimeout=60000

# Use a channel which buffers events in memory
......

案例3:五秒写入到一个文件中

.....
# Describe the sink
a1.sinks.k1.type = hdfs
# 时间会四舍五入
a1.sinks.k1.hdfs.path = /flume/events/%y-%m-%d/%H%M/
a1.sinks.k1.hdfs.filePrefix = events-
a1.sinks.k1.hdfs.rollInterval=5
a1.sinks.k1.hdfs.rollSize=0
a1.sinks.k1.hdfs.rollCount=0
a1.sinks.k1.hdfs.round = true
a1.sinks.k1.hdfs.roundValue = 2
a1.sinks.k1.hdfs.roundUnit = minute
a1.sinks.k1.hdfs.useLocalTimeStamp=true
a1.sinks.k1.hdfs.callTimeout=60000

# Use a channel which buffers events in memory
......
Hive Sink (使用较多)
属性名 默认值 说明
channel -
type - 组件类型名称,必须是 hive
hive.metastore - 元数据仓库地址,如 thrift://node3:9083
hive.database - 数据库名称
hive.table - 表名
hive.partition - 逗号分割的分区值,标识写到哪个分区 可以包含逃逸字符 如果表分区字段为:(continent: string, country :string, time : string) 则"Asia,India,2020-05-26-01-21"表continent为Asia country为India,time是2020-05-26-01-21
callTimeout 10000 Hive和HDFS的IO操作超时时间,比如openTxn,write,commit,abort等操作。单位毫秒
batchSize 15000 一个hive的事务允许写的事件最大数量。
roundUnit minute 控制多长时间生成一个文件夹的单位:second,minute,hour
HBase Sink (使用较多)
属性名称 默认值 描述
channel -
type - 组件类型名称,必须是hbase
table - hbase的表名
columnFamily - 列族的名称
zookeeperQuorum - 对应于hbase-site.xml中hbase.zookeeper.quorum的值,指定zookeeper集群地址列表。
其它 Sink
  1. Logger Sink
  2. Avro Sink(使用较多)
  3. Thrift Sink(使用较多)
a1.sinks.k1.type=thrift
a1.sinks.k1.hostname=node3    连谁?
a1.sinks.k1.port=8888          对方端口
  1. File Roll Sink
  2. ElasticSearchSink(使用较多)
  3. Kafka Sink(使用较多)

flume channel

  1. Memory Channel
a1.channels = c1
a1.channels.c1.type = memory
a1.channels.c1.capacity = 10000
a1.channels.c1.transactionCapacity = 10000
a1.channels.c1.byteCapacityBufferPercentage = 20
a1.channels.c1.byteCapacity = 800000
  1. JDBC Channel
a1.channels = c1
a1.channels.c1.type = jdbc
  1. File Channel
    磁盘上的某个文件,速度较慢。
  2. Kafka Channel

思考:
1、flume 如何收集 java 请求数据?
2、项目当中如何来做? 日志存放 /log/ 目录下 以 yyyyMMdd 为子目录 分别存放每天的数据

flume 应用在项目中的配置

  1. node1 上创建配置文件 project
# example.conf: A single-node Flume configuration

# Name the components on this agent
a1.sources = r1
a1.sinks = k1
a1.channels = c1

# Describe/configure the source
a1.sources.r1.type = exec
a1.sources.r1.command = tail -F /opt/data/access.log

# Describe the sink
a1.sinks.k1.type = hdfs
a1.sinks.k1.hdfs.path = /log/%Y%m%d
a1.sinks.k1.hdfs.filePrefix = events-
a1.sinks.k1.hdfs.rollInterval = 0
a1.sinks.k1.hdfs.rollSize = 10240000
a1.sinks.k1.hdfs.rollCount = 0
a1.sinks.k1.hdfs.useLocalTimeStamp = true
a1.sinks.k1.hdfs.callTimeout = 60000
#防止sequence file的前缀字符,修改为DataStream
a1.sinks.k1.hdfs.fileType = DataStream
# 10s关闭hdfs连接。
a1.sinks.k1.hdfs.idleTimeout = 10

# Use a channel which buffers events in memory
a1.channels.c1.type = memory
a1.channels.c1.capacity = 1000
a1.channels.c1.transactionCapacity = 100

# Bind the source and sink to the channel
a1.sources.r1.channels = c1
a1.sinks.k1.channel = c1
  1. 启动 node1 上 flume
flume-ng agent -n a1 --conf-file project -Dflume.root.logger=INFO,console
  1. 查看日志收集结果 node2:50070在这里插入图片描述
  2. 将文件下载,打开查看
    a1.sinks.k1.hdfs.fileType = DataStream参数配置,文件内容没有默认多余的内容了。
  3. 然后运行项目,访问网页,点击链接产生日志,然后再 node2:50070 查看。

flume 如何收集 java 请求数据

演示步骤:

  1. 解压 flume 包拷贝 lib 下的所有 jar 包到项目的 lib 文件夹下
  2. 选择 Idea 项目中 lib 文件夹–>右键–>Add as Library
  3. com/sxt/log/test/AvroClient.java类中的注释去掉,并修改端口
    client.init(“node3”, 10086);
    代码分析 AvroClient
  4. 启动 node3 上的 flume:
flume-ng agent -n a1 --conf-file option3.properties -Dflume.root.logger=INFO,console
  1. 运行AvroClient.java类
  2. 查看node3上flume日志

ETL在这里插入图片描述

解析思路:

  1. 通过^A进行拆分,不足四部分的数据不符合要求,过滤掉。
  2. ?后面的内容按照 & 进行拆分,参数en的值如果不是6种事件类型的过滤掉。
192.168.100.1^A1574736498.958^Anode1
192.168.100.1^A1574736498.958^Anode1^A/log.gif?en=e_e&ca=event%E7%9A%84category%E5%90%8D%E7    %A7%B0&ac=event%E7%9A%84action%E5%90%8D%E7%A7%B0&kv_key1=value1&kv_key2=value2&du=1245&ver=    1&pl=website&sdk=js&u_ud=8D4F0D4B-7623-4DB2-A17B-83AD72C2CCB3&u_mid=zhangsan&u_sd=9C7C0951-    DCD3-47F9-AD8F-B937F023611B&c_time=1574736499827&l=zh-CN&b_iev=Mozilla%2F5.0%20(Windows%20N    T%2010.0%3B%20Win64%3B%20x64)%20AppleWebKit%2F537.36%20(KHTML%2C%20like%20Gecko)%20Chrome%2    F78.0.3904.108%20Safari%2F537.36&b_rst=1360*768

================================================
192.168.100.1 换算成地域
1574736498.958 时间
浏览器相关信息提取处理

项目搭建

  1. 将代码 /big_data_etl.zip 解压到项目 logpro 目录下
  2. 使用已存在的 big_data_etl 创建 Module。

解析IP地址到地域

用于解析IP地址到地域。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值