基于大数据电商平台日志分析

一、项目介绍

1.1 项目介绍

本次实训,要求使用Hadoop及其生态圈相关的组件来实现企业级大数据开发的整套流程,即数据的采集、数据的存储、数据的分析处理及数据的可视化。其中数据的采集部分会介绍两种方式,一种介绍网络爬虫及其Java代码实现步骤,另外一种是利用学生所掌握的spring mvc技术来构建一个简易的电商平台,采取压测的方式模拟海量日志的产生,通过使用Nginx和tomcat实现动静资源分开部署的方式,采取flume日志采集组件来实现日志的采集,相比网络爬虫,这部分是实训所推荐的一种数据采集的方式;数据的存储部分,将采用MySQL和HDFS来分别存储关系型数据和非关系型数据,其中将会使用到sqoop组件作为MySQL和HDFS之间数据的转换桥梁和通道;数据分析处理部分,采用MapReduce程序实现数据的清洗和分析;数据可视化部分,采用echarts图表来展现。最终的效果是通过压测产生电商系统日志、flume采集日志、MapReduce分析处理日志、sqoop将分析后的结果导入到MySQL中、spring mvc项目前端对分析结果进行可视化,即展现商品的topN信息。

1.2 项目流程

二、项目工作准备

2.1 虚拟机安装

实训的项目主要是进行大数据的实训,所以需要安装Linux,使用VMware Workstation作为虚拟机安装Linux系统,下载虚拟机:

连接:

密码:

创建虚拟机,步骤如下:

下一步

              

下一步

             

 下一步

下一步 

                       

 下一步

                     

 下一步

                   

 接下来,点击编辑虚拟机,需要找到Linux的IOS文件

                  

 找到镜像文件之后,接下来就是安装Linux系统,选择开启虚拟机,虚拟机进行加载Linux进行安装。

 2.2 安装Linux的镜像

 选择安装的语言

                       

下一步:选择安装的形式和设置root用户的密码

                  

 安装好Linux之后进行重启

 重启之后,进行登录,输入用户名和密码

                   

 2.3 远程登录

 Linux一般作为服务器使用,而服务器一般放在机房,你不可能在机房操作你的Linux服务器。这时我们就需要远程登录到Linux服务器来管理维护系统。

Linux系统中是通过SSH服务实现的远程登录功能,默认ssh服务端口号为 22。Window系统上 Linux 远程登录客户端有SecureCRT, Putty, SSH Secure MobaXterm等。这里以MobaXterm作为演示:

 1)安装步骤

官网:https://mobaxterm.mobatek.net/

网盘:

下载好之后进行解压,打开

 点击左上角Session--------SSH

点击下面的SSH,然后第一个则是ip地址,第二个选项则是用户名和密码 

新建对应的用户名和密码,1代表连接的名字2是登录Linux的用户名3是登录Linux的密码

                    

 第一次连接,需要输入登录密码

              

 连接成功。

为后面的操作,我们需要修改几个配置,关闭防火墙,并禁止开机启动。
查看防火墙状态:

systemctl status firewalld

执行关闭命令: 

执行开机禁用防火墙自启命令:

systemctl disable firewalld

 还有进行主机名的修改:

vi /etc/hosts或vi /etc/hostname

创建两个目录,tools是存放所需要的工具包,training是环境的目录

mkdir /tools
mkdir /training

三、Web项目的讲解(Window)

3.1 前台项目

  

3.2 后台项目

四、安装JDK

因为开发需要JDK,所以进行JDK的安装,使用工具MobaXterm将JDK进行上传到tools目录下,然后进行解压

tar -zvxf /tools/jdk-7u80-linux-x64.tar.gz  -C /tarining/

配置环境变量:

vi ~/.bash_profile

添加如下信息

export JAVA_HOME=/training/jdk1.8.0_171
export JRE_HOME=$JAVA_HOME/jre
export CLASSPATH=.:$CLASSPATH:$JAVA_HOME/lib:$JRE_HOME/lib
export PATH=$PATH:$JAVA_HOME/bin:$JRE_HOME/bin

让环境变量生效

source ~/.bash_profile

验证jdk是否安装成功

java -version

五、安装MySQL(Linux)

5.1 安装MySQL YUM源到本地

yum localinstall https://dev.mysql.com/get/mysql57-community-release-el7-9.noarch.rpm

5.2 检查 mysql 源是否安装成功

yum repolist enabled | grep "mysql.*-community.*"

5.3 使用 yum install 命令安装

yum -y install mysql-community-server

5.4 安装完毕后,启动MySQL数据库

systemctl start mysqld

5.5 查看MySQL的启动状态

systemctl status mysqld

5.6 设置开机自启动

systemctl enable mysqld

5.7 重载所有修改过的配置文件

systemctl daemon-reload

5.8 修改root账户默认密码

mysql 安装完成之后,生成的默认密码在 /var/log/mysqld.log 文件中。使用 grep 命令找到日志中的密码。执行:

grep 'temporary password' /var/log/mysqld.log

5.9 修改密码

使用mysql -uroot -p 回车, 输入生成默认的密码,进入MySQL,然后输入下面语句进行密码的修改,密码改为:Ycs_123456.(密码可以自己定义) 输入:

ALTER USER 'root'@'localhost' IDENTIFIED BY 'Ycs_123456.';

5.10 配置root用户远程登录及添加远程登录用户

MySQL默认只允许root帐户在本地登录,如果要在其它机器上连接mysql,两种方式:

a)设置root用户允许远程登录:执行:

GRANT ALL PRIVILEGES ON *.* TO 'root'@'%' IDENTIFIED BY 'Ycs_123456.' WITH GRANT OPTION;
flush privileges;

b)可以添加一个允许远程连接的普通帐户:执行:

GRANT ALL PRIVILEGES ON *.* TO 'william'@'%' IDENTIFIED BY ' Ycs_123456.' WITH GRANT OPTION;  
flush privileges;

5.11 设置默认编码为 utf8

mysql 安装后默认不支持中文,需要修改编码

修改 /etc/my.cnf 配置文件,在相关节点(没有则自行添加)下添加编码配置,执行:

vi /etc/my.cnf

在文件的末尾添加如下信息:

[mysqld]
character-set-server=utf8
[client]
default-character-set=utf8
[mysql]
default-character-set=utf8

5.12 CentOS7下MySQL-5.7使用yum方式卸载

5.12.1 停止MySQL

systemctl stop mysqld

5.12.2 查看已安装的mysql

rpm -qa | grep -i mysql

5.12.3 卸载mysql,依次卸载第2步骤所列出的有关MySQL的安装包

yum remove -y mysql-community-server-5.6.36-2.el7.x86_64

5.12.4 删除mysql相关目录

1)使用命令查看mysql相关的文件目录:find / -name mysql

2)依次删除所查到的目录,命令:rm -rf /xxx/xxx/mysql

六、Nginx的安装(Linux)

6.1 在~下编写安装脚本:

vi nginx_install.sh

添加如下内容

#!/bin/bash
yum install -y gcc
#install pcre
yum install -y pcre-static.x86_64
#install nginx
tar -zvxf  /tools/nginx-1.15.12.tar.gz -C /training/
cd /training/nginx-1.15.12
./configure --prefix=/training/nginx --without-http_gzip_module
make && make install
#set .bash_profile
echo '#nginx' >> ~/.bash_profile
echo 'export PATH=$PATH:/training/nginx/sbin' >> ~/.bash_profile
# source .bash_profile
source ~/.bash_profile

6.2 赋予nginx_intall.sh执行权限

chmod +x nginx_install.sh

6.3 安装nginx,进入到nginx_intall.sh安装的目录,执行:

./nginx_intall.sh

脚本执行安装完后,nginx就安装好了

6.4 编写启动nginx的脚本,在~目录下新建nginx_start.sh,执行:

vi nginx_start.sh

添加如下内容:

#!/bin/bash
cd /training/nginx/sbin
./nginx

6.5 启动nginx,执行

./nginx_start.sh

6.6 验证nginx是否启动成功:

netstat -anop|grep nginx 或者 netstat -anop|grep 80

 6.7 编写停止nginx脚本,在~目录下新建nginx_stop.sh,执行:

vi nginx_stop.sh

添加如下内容:

#!/bin/bash
cd /training/nginx/sbin
./nginx -s stop

6.8 停止nginx,执行

./nginx_stop.sh

6.9 编写热加载nginx脚本,在~目录下新建nginx_reload.sh,执行:

vi nginx_reload.sh

添加如下内容:

#!/bin/bash
cd /training/nginx/sbin
./nginx -s reload

七、前端网站到Nginx

7.1 上传电商网站shop文件夹到/training/nginx/html/目录下

7.2 修改nginx配置文件nginx.conf,执行:

vi /training/nginx/conf/nginx.conf

找到里面的location,内容在其后面添加前端网站的文件名:

 7.3 重新记载nginx,执行:

./nginx_reload.sh

7.4 验证:在浏览器中输入ip地址是否可以访问到网站,输入:

http://虚拟机ip地址/shop/

八、Tomcat的安装(Linux)

8.1 官网下载

官网:https://tomcat.apache.org/,下载Linux版本的

 下载之后,将Tomcat上传到tools目录下

8.2 解压,然后进行环境变量的配置

tar -zvxf /tools/apache-tomcat-8.5.61.tar.gz -C /training/

配置环境变量:

vi ~/.bash_profile

添加以下内容:

#tomcat
export PATH=$PATH:/training/apache-tomcat-8.5.61/bin

环境生效:

source ~/.bash_profile

启动:

startup.sh

8.3 验证

在浏览器输入:

 http://虚拟机ip地址:8080/

或者在命令行里面输入:

netstat -anop|grep 8080

九、后台系统部署到Linux服务器

9.1 打开项目

将代码导入到eclipse或者idea中,将代码中的接口地址、数据库链接地址等修改成服务器地址,具体需要修改的代码如下:

GoodsController.java:

 -  修改上传图片地址为服务器地址

 -  将代码中的localhost或者IP地址改成服务器IP地址

UploadUtils.java:

- 将代码中的localhost或者IP地址改成服务器IP地址

hibernate.properties:

-  修改数据库名及地址为服务器的数据库名及地址

 -  修改数据库用户明、密码为服务器的用户密码

修改webapp目录下的所有html及jsp页面:

 - 将代码中的localhost或者IP地址改成服务器IP地址

 - 如果出现乱码情况,将webapp下的html页面进行补充完整的html 

RemoteExecuteCommand.java

- 将代码的localhost修改服务器的IP地址

- 将用户名修改Linux的用户名

- 将密码修改为登陆Linux用户的密码

打包成war包

上传war至Linux服务器的Tomcat安装目录下的webapp目录下

 启动或重启Tomcat

如果没有创建连接的数据库,需要创建数据库

create database shop default character set utf8;

9.2 配置Tomcat支持UTF-8字符集

由于后台项目页面部分采用了html和jsp结合嵌套的方式,即在jsp中嵌套了html代码段,会存在html代码段显示中文乱码的问题,故需要做配置

1)修改tomcat/conf目录下的server.xml,添加URIEncoding=“UTF-8”配置项,配置位置如下:

<Connector port="8080" protocol="HTTP/1.1"
           connectionTimeout="20000"
           redirectPort="8443" URIEncoding="UTF-8" />
<Connector protocol="AJP/1.3"
           address="::1"
           port="8009"
           redirectPort="8443" URIEncoding="UTF-8" />

2)修改tomcat/conf/web.xml,在 节点中添加如下内容:

<init-param>
            <param-name>fileEncoding</param-name>
            <param-value>UTF-8</param-value>
</init-param>

重启Tomcat

9.3 打开浏览器进行验证

十、AB压测(httpd)安装

10.1 安装httpd

yum install -y httpd

10.2 配置httpd,修改端口号为81,配置如下:

vi /etc/httpd/conf/httpd.conf

修改内容如下:#Listen 80    Listen 81

 启动服务

systemctl enable httpd # 开机自启动
systemctl start httpd # 启动httpd
systemctl status httpd # 查看启动状态

 

 10.3 在~下编写压测脚本ab_test.sh,内容可自行修改,如下:

#!/bin/bash
n=`cat url.txt | wc -l`
for ((i=1;i<=$n;i++))
do
        echo $i
        url=`shuf -n1 url.txt`
        r=`shuf -i 6-100 -n 1`
        c=`shuf -i 1-5 -n 1`
        echo $url
        echo $r
        echo $c
        ##将测试的结果写入到test_ab.log >> results.log &
        ab -n $r -c $c $url >> results.log &
done

执行ab_test.sh脚本,在~目录下产生压测的日志文件results.log,即压测数据成功。

十一、Hadoop安装与配置

10.1 安装Hadoop

把上传到tools目录下的Hadoop进行解压

tar -zvxf /tools/hadoop-2.7.3.tar.gz -C /training/

配置环境变量:

vi ~/.bash_profile

添加如下信息:

export HADOOP_HOME=/training/hadoop-2.7.3
export PATH=$PATH:$HADOOP_HOME/bin:$HADOOP_HOME/sbin

让环境变量生效:

source ~/.bash_profile

验证是否生效:

执行:hdfs 或者hadoop 有相关信息出现即可

10.2 Hadoop运行模式

10.2.1 官方网址

(1)官方网站:

http://hadoop.apache.org/

(2)各个版本归档库地址

https://archive.apache.org/dist/hadoop/common

(3)hadoop2.7.3版本详情介绍

https://hadoop.apache.org/docs/

10.2.2 Hadoop运行模式

(1)本地模式(默认模式):

不需要启用单独进程,直接可以运行,测试和开发时使用。

(2)伪分布式模式:

等同于完全分布式,只有一个节点。

(3)完全分布式模式:

多个节点一起运行。

10.2.3 本地模式案例测试

特点:没有HDFS,只能进行MapReduce计算,而且只操作Linux上的文件

(1)官方wordcount案例(统计文件中单词出现的次数)

进入到hadoop安装目录下的etc/hadoop目录下,编辑:

vi hadoop-env.sh

配置Java环境变量:

export JAVA_HOME=/training/jdk1.8.0_171

接下来可以本地模式,测试前需要创建测试目录和测试文件:

mkdir /demo/input
vi /demo/input/test.txt

输入如下内容: 

I love Guiyang
I love Guizhou
Guiyang is the capital of Guizhou

保存退出,进入到:cd /training/hadoop-2.7.3/share/hadoop/mapreduce/目录下

执行:

hadoop jar hadoop-mapreduce-examples-2.7.3.jar wordcount /demo/input/test.txt /demo/output

查看结果:MapReduce程序的执行结果会默认按照英文单词的字典顺序进行了排序

 进入到/demo/output/目录下查看结果:

 (2)官方grep案例(从一堆文件中找到符合规则的单词)

1.使用上一步所创建的input文件夹

cd /demo/input

2.将Hadoop的xml配置文件复制到input

cp /training/hadoop-2.7.3/etc/hadoop/*.xml /demo/input

3.进入到share目录下执行MapReduce程序

hadoop jar hadoop-mapreduce-examples-2.7.3.jar grep /demo/input  /demo/output 'dfs[a-z.]+'

4.查看输出结果

cat /demo/output/part-r-00000

10.2.4 伪分布模式

特点:具备HDFS全部功能

HDFS:NameNode + DataNode

Yarn:ReourceManager + NodeManager

1)分析:

       (1)准备1台客户机

       (2)安装jdk

       (3)配置环境变量

       (4)安装hadoop

       (5)配置环境变量

       (6)配置集群

       (7)启动、测试集群增、删、查

       (8)在HDFS上执行wordcount案例

2)执行步骤

需要配置hadoop文件如下

(1)配置集群

        (a)配置:hadoop-env.sh

vi hadoop-env.sh

配置Java环境变量:

export JAVA_HOME=/training/jdk1.8.0_171

这一步在hadoop本地模式时已经操作,如果已添加好的,无需再添加,未添加的进行添加

进入到hadoop-2.7.3/etc/hadoop目录下,进行配置hadoop文件

(b)配置:hdfs-site.xml 

hdfs-site.xml:原则是:一般有几个数据节点就配置几个,但是最多不能超多3

<!--表示数据块的冗余度 默认为3-->
<property>
	<name>dfs.replication</name>
	<value>1</value>
</property>

(c)配置:core-site.xml

core-site.xml:(hadoop是主机映射的ip地址)

<!--配置NameNode的通讯地址 9000 是RPC默认的通信端口-->
<property>
	<name>fs.defaultFS</name>
	<value>hdfs://hadoop:9000</value>
</property>			
<!--HDFS数据保存在Linux的哪个目录,默认值是Linux的tmp目录  必须配置,否则会报错/training/hadoop-2.7.3/tmp 必须事先存在-->
<property>
	<name>hadoop.tmp.dir</name>
	<value>/training/hadoop-2.7.3/tmp</value>
</property>

注意:/training/hadoop-2.7.3/tmp 必须提前存在

d)配置:mapper-site.xml

mapper-site.xml:

这个文件事先是不存在的,需要复制一份    

cp mapred-site.xml.template mapred-site.xml
<!--配置MR的运行框架-->
<property>
	<name>mapreduce.framework.name</name>
	<value>yarn</value>
</property>

e)配置:yarn-site.xml

yarn-site.xml:(hadoop是主机映射的ip地址)

<!--Yarn的主节点RM的位置-->
<property>
	<name>yarn.resourcemanager.hostname</name>
	<value>hadoop</value>
</property>

<!--MapReduce运行方式:shuffle洗牌-->
<property>
	<name>yarn.nodemanager.aux-services</name>
	<value>mapreduce_shuffle</value>
</property>	

 (*) 先配置免密码登录

执行为什么要配置免密登录?未配置免密登录前,在hadoop登录需要输入密码,这对以后的工作会产生很多麻烦,所以输入命令

ssh-keygen -t rsa

 按四下回车,出现以下的公钥和私钥

 将公钥和私钥复制到主机ip (hadoop是主机映射的ip地址)

ssh-copy-id hadoop

格式化:HDFS(NameNode)

hdfs namenode -format

 启动hadoop集群

start-all.sh

启动集群没有任何错误,输入jps可以看到集群组件启动

访问:web界面进行验证  (hadoop是主机映射的ip地址)

HDFS:

http://hadoop:50070

 Yarn:

http://hadoop:8088

10.2.5 Hadoop伪分布wordcount例子

编辑test.txt文件放入到本地的/demo/input目录下,写入一些单词

I have a dream that one day this nation will rise up and live out the true meaning of its creed: "We hold these truths to be self-evident, that all men are created equal."
I have a dream that one day on the red hills of Georgia, the sons of former slaves and the sons of former slave owners will be able to sit down together at the table of brotherhood.
I have a dream that one day even the state of Mississippi, a state sweltering with the heat of injustice, sweltering with the heat of oppression, will be transformed into an oasis of freedom and justice.
I have a dream that my four little children will one day live in a nation where they will not be judged by the color of their skin but by the content of their character.

测试需要把文件上传到HDFS上,在HDFS上创建一个目录

hdfs dfs -mkdir -p /root/input

 将本地的文本上传到HDFS上创建的目录

hdfs dfs -put /demo/input/test.txt /root/input

然后进入到haoop-2.7.3/share/hadoop/mapreduce下,执行

hadoop jar hadoop-mapreduce-examples-2.7.3.jar wordcount /root/input/test.txt /root/output

执行成功后,输出结果在HDFS上,输入

hadoop fs -cat /root/output/part-r-00000

查看结果

十一、Flume的安装与配置

11.1 安装Flume

上传flume到/tools目录下,解压安装

tar -zvxf /tools/apache-flume-1.9.0-bin.tar.gz -C /training/

配置环境变量

vi ~/.bash_profile

添加如下内容:

export FLUME_HOME=/training/apache-flume-1.9.0-bin
export PATH=$PATH:$FLUME_HOME/bin

让环境变量生效

source ~/.bash_profile

将hadoop-2.7.3安装路径下的依赖的jar导入到/apache-flume-1.9.0-bin/lib下,需要导入的jar包

share/hadoop/common/hadoop-common-2.7.3.jar
share/hadoop/common/lib/commons-configuration-1.6.jar
share/hadoop/common/lib/hadoop-auth-2.7.3.jar
share/hadoop/hdfs/hadoop-hdfs-2.7.3.jar
share/hadoop/common/lib/htrace-core-3.1.0-incubating.jar
share/hadoop/common/lib/commons-io-2.4.jar

执行代码

cp /training/hadoop-2.7.3/share/hadoop/common/hadoop-common-2.7.3.jar  /training/apache-flume-1.9.0-bin/lib
cp /training/hadoop-2.7.3/share/hadoop/common/lib/commons-configuration-1.6.jar /training/apache-flume-1.9.0-bin/lib
cp  /training/hadoop-2.7.3/share/hadoop/common/lib/hadoop-auth-2.7.3.jar /training/apache-flume-1.9.0-bin/lib
cp  /training/hadoop-2.7.3/share/hadoop/hdfs/hadoop-hdfs-2.7.3.jar /training/apache-flume-1.9.0-bin/lib
cp  /training/hadoop-2.7.3/share/hadoop/common/lib/htrace-core-3.1.0-incubating.jar /training/apache-flume-1.9.0-bin/lib
cp  /training/hadoop-2.7.3/share/hadoop/common/lib/commons-io-2.4.jar /training/apache-flume-1.9.0-bin/lib

验证

bin/flume-ng version

11.2 配置Flume HDFS Sink 

在/training/apache-flume-1.7.0-bin/conf/新建一个flume-hdfs.conf,添加如下内容:

# define the agent
a1.sources=r1
a1.channels=c1
a1.sinks=k1
# define the source
#上传目录类型
a1.sources.r1.type=spooldir
a1.sources.r1.spoolDir=/training/nginx/logs/flumeLogs
#定义自滚动日志完成后的后缀名
a1.sources.r1.fileSuffix=.FINISHED
#根据每行文本内容的大小自定义最大长度4096=4k
a1.sources.r1.deserializer.maxLineLength=4096

# define the sink
a1.sinks.k1.type = hdfs
#上传的文件保存在hdfs的/flumeLogs目录下
a1.sinks.k1.hdfs.path = hdfs://192.168.181.135:9000/flumeLogs/%y-%m-%d/%H/%M/%S
a1.sinks.k1.hdfs.filePrefix=access_log
a1.sinks.k1.hdfs.fileSufix=.log
a1.sinks.k1.hdfs.batchSize=1000
a1.sinks.k1.hdfs.fileType = DataStream
a1.sinks.k1.hdfs.writeFormat= Text 
# roll 滚动规则:按照数据块128M大小来控制文件的写入,与滚动相关其他的都设置成0
#为了演示,这里设置成500k写入一次
a1.sinks.k1.hdfs.rollSize= 512000
a1.sinks.k1.hdfs.rollCount=0
a1.sinks.k1.hdfs.rollInteval=0
#控制生成目录的规则:一般是一天或者一周或者一个月一次,这里为了演示设置10秒 
a1.sinks.k1.hdfs.round=true
a1.sinks.k1.hdfs.roundValue=10
a1.sinks.k1.hdfs.roundUnit= second    
#是否使用本地时间
a1.sinks.k1.hdfs.useLocalTimeStamp=true   
#define the channel
a1.channels.c1.type = memory
#自定义event的条数
a1.channels.c1.capacity = 500000
#flume事务控制所需要的缓存容量1000条event
a1.channels.c1.transactionCapacity = 1000

#source channel sink cooperation
a1.sources.r1.channels = c1
a1.sinks.k1.channel = c1

注意:

- 需要先在/training/nginx/logs/创建flumeLogs

- 需要在hdfs的根目录/下创建flumeLogs

- hdfs://192.168.181.135(虚拟机的IP地址)

修改conf/flume-env.sh(该文件事先是不存在的,需要复制一份)

cp flume-env.sh.template flume-env.sh

添加一下内容:

#设置JAVA_HOME:
export JAVA_HOME = /training/jdk1.8.0_171          
#修改默认的内存:  
export JAVA_OPTS="-Xms1024m -Xmx1024m -Xss256k -Xmn2g -XX:+UseParNewGC -XX:+UseConcMarkSweepGC -XX:-UseGCOverheadLimit"  

11.3 启动flume

启动Flume进行测试,将 /training/nginx/logs/access.log 复制到/training/nginx/logs/flumeLogs/access_201904251200.log

进入到/training/apache-flume-1.7.0-bin目录下,执行命令启动:

bin/flume-ng agent --conf ./conf/ -f ./conf/flume-hdfs.conf --name a1 -Dflume.root.logger=INFO,console

之后到Hadoop的控制台http://192.168.181.135:50070/flumeLogs 查看有没有数据

 如有数据存在,那说明flume启动成功

 为了项目的实现,我们编写Linux脚本rollingLog.sh,实现/training/nginx/logs/access.log日志的自动滚动

在~目录下新建rollingLog.sh,并添加如下内容:vi ~/rollingLog.sh

#!/bin/bash
#定义日期格式
dataformat=`date +%Y-%m-%d-%H-%M-%S`
#复制access.log并重命名
cp /training/nginx/logs/access.log /training/nginx/logs/access_$dataformat.log
host=`hostname`
sed -i 's/^/'${host}',&/g' /training/nginx/logs/access_$dataformat.log
#统计日志文件行数
lines=`wc -l < /training/nginx/logs/access_$dataformat.log`
#将格式化的日志移动到flumeLogs目录下
mv /training/nginx/logs/access_$dataformat.log /training/nginx/logs/flumeLogs
#清空access.log的内容
sed -i '1,'${lines}'d' /training/nginx/logs/access.log
#重启nginx , 否则 log can not roll.
kill -USR1 `cat /training/nginx/logs/nginx.pid`
##返回给服务器信息
ls -al /training/nginx/logs/flumeLogs/

为了方便后面的项目,编写启动Flume脚本 flume_start.sh,启动Flume:vi ~/flume_start.sh

#!/bin/bash
/training/apache-flume-1.9.0-bin/bin/flume-ng agent -c /training/apache-flume-1.9.0-bin/conf/ -f /training/apache-flume-1.9.0-bin/conf/flume-hdfs.conf -n a1 -Dflume.root.logger=INFO,console &

编写停止Flume脚本 flume_stop.sh,停止Flume:vi ~/flume_stop.sh

#!/bin/bash
JAR="flume"
#停止flume函数
echo "begin stop flume process.."
num=`ps -ef|grep java|grep $JAR|wc -l`
echo "当前已经启动的flume进程数:$num"
if [ "$num" != "0" ];then
#正常停止flume
ps -ef|grep java|grep $JAR|awk '{print $2;}'|xargs kill
echo "进程已经关闭..."
else
echo "服务未启动,无须停止..."
fi

编写重启Flume脚本 flume_to_hdfs.sh,综合了前两个脚本:vi ~/flume_to_hdfs.sh

#!/bin/bash
#先停止正在启动的flume
./flume_stop.sh
#用法:nohup ./start-dishi.sh >output 2>&1 &
nohup ./flume_start.sh > nohup_output.log 2>&1 &
echo "启动flume成功……"

十二、MapReduce工程

12.1 MapReduce代码编写

(1)创建MapReduce工具

(2)导入Hadoop的依赖包

(3)写代码

 导入Maven依赖包

<dependencies>
        <dependency>
            <groupId>org.apache.hadoop</groupId>
            <artifactId>hadoop-common</artifactId>
            <version>2.7.3</version>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>org.apache.hadoop</groupId>
            <artifactId>hadoop-hdfs</artifactId>
            <version>2.7.3</version>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>org.apache.hadoop</groupId>
            <artifactId>hadoop-mapreduce-client-common</artifactId>
            <version>2.7.3</version>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>org.apache.hadoop</groupId>
            <artifactId>hadoop-mapreduce-client-core</artifactId>
            <version>2.7.3</version>
            <scope>provided</scope>
        </dependency>
    </dependencies>

 创建类LogMapper类:LogMapper.java

package com.niit;

import org.apache.hadoop.io.IntWritable;
import org.apache.hadoop.io.LongWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Mapper;

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

/**
 * @author yangchengshuai
 * @create 2021-01-09
 */
public class LogMapper extends Mapper<LongWritable, Text,Text, IntWritable> {
    // 按指定模式在字符串查找
    String pattern = "\\=[0-9a-z]*";
    // 创建 Pattern 对象
    Pattern r = Pattern.compile(pattern);
    protected void map(LongWritable key, Text value, Context context) throws IOException, InterruptedException {
        String data = value.toString();
        // 现在创建 matcher 对象
        Matcher m = r.matcher(data);
        if (m.find()) {
            String idStr = m.group(0);
            String id = idStr.substring(1);
            context.write(new Text(id),new IntWritable(1));
        }
    }
}

创建LogReducer类:LogReducer.java

package com.niit;

import org.apache.hadoop.io.IntWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Reducer;

import java.io.IOException;

/**
 * @author yangchengshuai
 * @create 2021-01-09
 */
public class LogReducer  extends Reducer<Text, IntWritable,Text, IntWritable> {
    @Override
    protected void reduce(Text key, Iterable<IntWritable> values, Context context) throws IOException, InterruptedException {
        int sum = 0;
        for (IntWritable v: values) {
            sum += v.get();
        }
        context.write(key,new IntWritable(sum));
    }
}

创建LogJob类:LogJob.java

package com.niit;


import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.io.IntWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Job;
import org.apache.hadoop.mapreduce.lib.input.FileInputFormat;
import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat;

/**
 * @author yangchengshuai
 * @create 2021-01-09
 */
public class LogJob  {
    public static void main(String[] args) throws Exception  {
        Job job = Job.getInstance(new Configuration());
        job.setJarByClass(LogJob.class);

        job.setMapperClass(LogMapper.class);
        job.setMapOutputKeyClass(Text.class);
        job.setMapOutputValueClass(IntWritable.class);

        job.setReducerClass(LogReducer.class);
        job.setOutputKeyClass(Text.class);
        job.setOutputValueClass(IntWritable.class);

        FileInputFormat.setInputPaths(job,new Path(args[0]));
        FileOutputFormat.setOutputPath(job,new Path(args[1]));

        boolean completion = job.waitForCompletion(true);
    }
}

添加log4j.properties文件在资源目录下即resources,文件内容如下

### 配置根 ###
log4j.rootLogger = debug,console,fileAppender
## 配置输出到控制台 ###
log4j.appender.console = org.apache.log4j.ConsoleAppender
log4j.appender.console.Target = System.out
log4j.appender.console.layout = org.apache.log4j.PatternLayout
log4j.appender.console.layout.ConversionPattern = %d{ABSOLUTE} %5p %c:%L - %m%n
### 配置输出到文件 ###
log4j.appender.fileAppender = org.apache.log4j.FileAppender
log4j.appender.fileAppender.File = logs/logs.log
log4j.appender.fileAppender.Append = false
log4j.appender.fileAppender.Threshold = DEBUG,INFO,WARN,ERROR
log4j.appender.fileAppender.layout = org.apache.log4j.PatternLayout
log4j.appender.fileAppender.layout.ConversionPattern = %-d{yyyy-MM-dd HH:mm:ss} [ %t:%r ] - [ %p ] %m%n

打jar包,提交集群运行

为方便操作,编写脚本exec_mr.sh来执行MR程序:vi ~/exec_mr.sh

#!/bin/bash

#执行MapReduce程序
dataformat=`date +%Y-%m-%d-%H-%M-%S`
/training/hadoop-2.7.3/bin/hadoop jar log.jar $(cat mr_input_path.txt) /output/result/$dataformat
/training/hadoop-2.7.3/bin/hdfs dfs -cat /output/result/$dataformat/part-r-00000 > mr_result.txt
echo $(cat mr_result.txt)

十三、SQOOP安装配置

13.1 按照SQOOP

上传sqoop-1.4.7.bin__hadoop-2.6.0.tar.gz到/tools目录下

tar -zvxf sqoop-1.4.7.bin__hadoop-2.6.0.tar.gz -C /training/

配置环境变量

vi ~/.bash_profile

添加一下内容:

#sqoop
export SQOOP_HOME=/training/sqoop-1.4.7.bin__hadoop-2.6.0
export PATH=$PATH:$SQOOP_HOME/bin

让环境变量生效

source ~/.bash_profile

13.2 配置sqoop文件(两个文件)

修改configure-sqoop

vi /training/sqoop-1.4.7.bin__hadoop-2.6.0/bin/configure-sqoop

将出现HCAT_HOME和ACCUMULO_HOME部分内容注释掉

修改sqoop-site.xml和sqoop-env.sh

vi /training/sqoop-1.4.7.bin__hadoop-2.6.0/conf/sqoop-site.xml
vi /training/sqoop-1.4.7.bin__hadoop-2.6.0/conf/sqoop-env.sh

sqoop-site.xml内容如下:

<?xml version="1.0"?>
<?xml-stylesheet type="text/xsl" href="configuration.xsl"?>
<configuration>

  <property>
    <name>sqoop.metastore.client.enable.autoconnect</name>
    <value>true</value>
    <description>If true, Sqoop will connect to a local metastore
      for job management when no other metastore arguments are
      provided.
    </description>
  </property>
  <property>
    <name>sqoop.metastore.client.autoconnect.url</name>
    <value>jdbc:hsqldb:file:/tmp/sqoop-meta/meta.db;shutdown=true</value>
    <description>The connect string to use when connecting to a
      job-management metastore. If unspecified, uses ~/.sqoop/.
      You can specify a different path here.
    </description>
  </property>
  <property>
    <name>sqoop.metastore.client.autoconnect.username</name>
    <value>SA</value>
    <description>The username to bind to the metastore.
    </description>
  </property>
  <property>
    <name>sqoop.metastore.client.autoconnect.password</name>
    <value></value>
    <description>The password to bind to the metastore.
    </description>
  </property>
  <property>
    <name>sqoop.metastore.client.record.password</name>
    <value>true</value>
    <description>If true, allow saved passwords in the metastore.
    </description>
  </property>
  <property>
    <name>sqoop.metastore.server.location</name>
    <value>/tmp/sqoop-metastore/shared.db</value>
    <description>Path to the shared metastore database files.
    If this is not set, it will be placed in ~/.sqoop/.
    </description>
  </property>

  <property>
    <name>sqoop.metastore.server.port</name>
    <value>16000</value>
    <description>Port that this metastore should listen on.
    </description>
  </property>
  
</configuration>

sqoop-env.sh内容如下:

#Set path to where bin/hadoop is available
export HADOOP_COMMON_HOME=/training/hadoop-2.7.3
#Set path to where hadoop-*-core.jar is available
export HADOOP_MAPRED_HOME=/training/hadoop-2.7.3

将MySQL数据库的驱动(使用5.x版本,不要使用高版本的)上传到sqoop安装目录下的lib目录下,由于sqoop缺少java-json.jar包进行解析json,也需要上传到sqoop安装目录下的lib目录下

cp /tools/mysql-connector-java-5.1.44-bin.jar /training/sqoop-1.4.7.bin__hadoop-2.6.0/lib
cp /tools/java-json.jar /training/sqoop-1.4.7.bin__hadoop-2.6.0/lib

13.3 验证
sqoop version
13.4 创建数据库表t_mr_result

CREATE TABLE `t_mr_result` (
  `goodsId` varchar(150) COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '商品ID',
  `goodsViewCount` int(50) DEFAULT NULL COMMENT '商品浏览总数'
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci

13.4 编写sqoop从hadoop导出数据到MySQL的脚本

#!/bin/bash
/training/sqoop-1.4.7.bin__hadoop-2.6.0/bin/sqoop export \
--connect jdbc:mysql://192.168.112.129:3306/shop \
--username root \
--password Ycs_123456. \
--input-fields-terminated-by '\t' \
--table t_mr_result \
--export-dir $(cat result_path.txt)
--class-name UpsertMrResult --update-key goodsId --update-mode allowinsert

十四、集成调试

  • 5
    点赞
  • 28
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值