文章目录
大数据的操作过程(纯行为记录)
基础准备
创建一个基础虚拟机,以root用户登录
在家目录下创建bin目录用于存放以后使用的脚本
在opt目录下创建soft目录用于以后保存需要的软件的安装包
在opt目录下创建module目录用于以后存放控件
关闭防火墙
systemctl stop firewalld.service(Centos7/8)
修改主机名为hadoop100
加上映射。(vim /etc/hosts/)
添加类似于
192.168.1.107 hadoop107
192.168.1.108 hadoop108
复制出三台虚拟机名字分别为:hadoop102,hadoop103,hadoop104
给三台虚拟机分别配置ip:
步骤:
vim /etc/sysconfig/network(更改本机名为hadoop2/3/4)
Centos7的话用
vim /etc/hostname
vim /etc/udev/rules.d/70-persistent-net.rules(最后改为eth0,复制地址)
vim /etc/sysconfig/network-scripts/ifcfg-eth0(将复制的地址粘贴上去,更改ip)
Centos7则只需要用第三条命令修改ip即可
注意修改后用
service network restart
重启网卡
然后使用ifconfig检查ip是否修改成功,如果不成功就多重启几次
对三台虚拟机全部执行以上步骤。
对三台虚拟机配置ssh密钥
在hadoop103上:
ssh-keygen -t rsa
后连续三次:
ssh -copy-id hadoop102/3/4
编写脚本(记得以下bin目录中的脚本编写完成后都要修改权限)
在hadoop103的bin目录中添加2个脚本
vim xsync(分发文件用)
vim xcall(在三台虚拟机上都执行同一个指令,并且将情况打印到控制台)
xsync:
\#!/bin/bash
\#验证参数
if(($#!=1))
then
echo 请传入要分发的单个文件!
exit;
fi
\#获取分发文件的绝对路径
dirpath=$(cd -P `dirname $1`; pwd)
filename=$(basename $1)
echo "要分发的文件路径是:$dirpath/$filename"
\#获取当前的用户名
user=$(whoami)
\#分发,前提是集群中的机器都有当前分发文件所在的父目录
for((i=102;i<=104;i++))
do
echo -----------------------hadoop$i---------------------
rsync -rvlt $dirpath/$filename $user@hadoop$i:$dirpath
done
xcall:
\#!/bin/bash
\#验证参数
if(($#==0))
then
echo 请传入要执行的命令!
exit;
fi
echo "要执行的命令是:$@"
\#批量执行
for((i=102;i<=104;i++))
do
echo -----------------------hadoop$i---------------------
ssh hadoop$i $@
done
安装JDK
解压
将jdk的包放到hadoop103的soft中,解压到module中(只需要将压缩包导入即可)
tar -zxvf jdk-8u144-linux-x64.tar.gz -C /opt/module/
加入环境变量
vim /etc/profile 在最后添加如下内容:
\#JAVA_HOME
export JAVA_HOME=/opt/module/jdk1.8.0_144
export PATH=$PATH:$JAVA_HOME/bin
添加后记得刷新
source /etc/profile
分发
然后分发
在module中:
xsync jdk1.8.0_144
还要将/etc/profile分发:
xsync /etc/profile/
同时在每个虚拟机中刷新:
source /etc/profile/
使用jps即可查看当前的java进程。
使用java -version查看当前java版本,使用javac -version 来查看javac的版本,如果不同:
rm -rf /usr/bin/java
再刷新(source /etc/profile)
在家目录中:
vim .bashrc
在末尾添加:
source /etc/profile/
然后分发即可。
接下来使用:
xcall jps
即可查看每台虚拟机的进程情况。
日志生成(模拟的数据)
导入jar包
导入jar包:log-collector-1.0-SNAPSHOT-jar-with-dependencies.jar
将jar包导入hadoop103的/opt/module目录中
同时将此jar包分发:
xsync log-collector-0.0.1-SNAPSHOT-jar-with-dependencies.jar
使用此jar包:
java -cp log-collector-0.0.1-SNAPSHOT-jar-with-dependencies.jar com.atguigu.appclient.AppMain 参数1 参数2
参数1是产生的每条数据的时间间隔(毫秒)
参数2是产生的数据总数目
产生的数据默认输出到 /tmp/logs目录中
在hadoop103的家目录中的bin目录中编写日志生成脚本lg
vim lg
日志和日期的脚本
lg
\#!/bin/bash
\#在hadoop102,hadoop103产生日志
for i in hadoop102 hadoop103
do
ssh $i java -cp /opt/module/log-collector-1.0-SNAPSHOT-jar-with-dependencies.jar com.atguigu.appclient.AppMain $1 $2 > /dev/null 2>&1 &
done
更改时间的日志:dt
在bin目录下创建dt文件用于更改三个虚拟机的时间
vim dt
dt
\#/bin/bash
\#在hadoop102和hadoop103上同步日期为指定的日期
if(($#==0))
then
echo 请输入要修改的时间!
exit;
fi
\#修改系统时间
for i in hadoop102 hadoop103
do
echo ------------同步$i时间--------------
ssh $i "sudo date -s '$@'"
done
dt脚本后接时间如:2021-4-27
同时创建ct脚本用于将时间调回原本的样子
vim ct
ct
\#!/bin/bash
\#将集群的时间都同步为最新的时间
xcall sudo ntpdate -u ntp1.aliyun.com
直接使用即可
Hadoop的安装
将hadoop的包放到soft目录中
解压到module中
随后进行配置
core.site.xml
在文件后方添加:
<!-- 指定HDFS中NameNode的地址 -->
<property>
<name>fs.defaultFS</name>
<value>hdfs://hadoop102:9000</value>
</property>
<!-- 指定Hadoop运行时产生文件的存储目录 -->
<property>
<name>hadoop.tmp.dir</name>
<value>/opt/module/hadoop-2.7.2/data/tmp</value>
</property>
hdfs.site.xml
<!-- 指定Hadoop辅助名称节点主机配置 -->
<property>
<name>dfs.namenode.secondary.http-address</name>
<value>hadoop104:50090</value>
</property>
yarn.site.xml
<property>
<name>yarn.nodemanager.aux-services</name>
<value>mapreduce_shuffle</value>
</property>
<!-- 指定YARN的ResourceManager的地址 -->
<property>
<name>yarn.resourcemanager.hostname</name>
<value>hadoop103</value>
</property>
<!-- 日志聚集功能使能 -->
<property> <name>yarn.log-aggregation-enable</name>
<value>true</value> </property>
<!-- 日志保留时间设置7天 -->
<property>
<name>yarn.log-aggregation.retain-seconds</name>
<value>604800</value>
</property>
Mapred.site.xml
<!-- 历史服务器端地址 -->
<property>
<name>mapreduce.jobhistory.address</name>
<value>hadoop102:10020</value>
</property>
<!-- 历史服务器web端地址 -->
<property>
<name>mapreduce.jobhistory.webapp.address</name>
<value>hadoop102:19888</value>
</property>
<!--第三方框架使用yarn计算的日志聚集功能 -->
<property>
<name>yarn.log.server.url</name>
<value>http://hadoop102:19888/jobhistory/logs</value>
</property>
<!-- 指定MR运行在YARN上 -->
<property>
<name>mapreduce.framework.name</name>
<value>yarn</value>
</property>
配置后进行分发
在/hadoop-2.7.2/etc/hadoop中编写文本
vim slaves
添加如下内容:
hadoop102
hadoop103
hadoop104
时候顺便把hive,zookeeper,flume,kafka也全部解压到module中
将kafka的jar包改名为kafka
将flume的jar包改名为flume
Hive的jar包改名为jar
将/etc/profile后面改为
\#JAVA_HOME
JAVA_HOME=/opt/module/jdk1.8.0.144
ZOOKEEPER_HOME=/opt/module/zookeeper-3.4.10
HADOOP_HOME=/opt/module/hadoop-2.7.2
KAFKA_HOME=/opt/module/kafka
FLUME_HOME=/opt/module/flume
HIVE_HOME=/opt/module/hive
export JAVA_HOME ZOOKEEPER_HOME HADOOP_HOME KAFKA_HOME FLUME_HOME HIVE_HOME
export PATH=$PATH:$JAVA_HOME/bin:$ZOOKEEPER_HOME/bin:$HADOOP_HOME:bin:$HADOOP_HOME/sbin:KAFKA_HOME/bin:$FLUME_HOME/bin:$HIVE_HOME/bin
分发、刷新。
之后在hadoop102上进行格式化
之后在浏览器中输入hadoop102:50070即可查看集群
如果失败重新来:
xcall rm -rf /opt/module/hadoop-2.7.2/data/
xcall rm -rf /opt/module/hadoop-2.7.2/logs/
在bin目录中创建脚本hd
用于群起hadoop集群
\#!/bin/bash
\#hadoop集群的一键启动脚本
if(($#!=1))
then
echo '请输入start|stop参数!'
exit;
fi
\#只允许传入start和stop参数
if [ $1 = start ] || [ $1 = stop ]
then
/opt/module/hadoop-2.7.2/sbin/$1-dfs.sh
/opt/module/hadoop-2.7.2/sbin/$1-yarn.sh
ssh hadoop102 mr-jobhistory-daemon.sh $1 historyserver
else
echo '请输入start|stop参数!'
fi
为hadoop安装LZO压缩
移动
将soft中的lzo复制到module/hadoop-2.7.2/share/hadoop/common中
添加
为core-site/xml添加以下内容:
<property>
<name>io.compression.codecs</name>
<value>
org.apache.hadoop.io.compress.GzipCodec,
org.apache.hadoop.io.compress.DefaultCodec,
org.apache.hadoop.io.compress.BZip2Codec,
org.apache.hadoop.io.compress.SnappyCodec,
com.hadoop.compression.lzo.LzoCodec,
com.hadoop.compression.lzo.LzopCodec
</value>
</property>
<property>
<name>io.compression.codec.lzo.class</name>
<value>com.hadoop.compression.lzo.LzoCodec</value>
</property>
再分发core.-site.xml
Zookeeper的安装
解压
将zookeeper的压缩包解压到module中
进入zookeeper中创建目录datas
将data的路径复制下来
进入zookeeper中的conf中将zoo_sample.cfg 改名为 zoo.cfg
编辑zoo.cfg
将datadir改为data的地址
在后面添加如下内容:
\#######################cluster##########################
server.102=hadoop102:2888:3888
server.103=hadoop103:2888:3888
server.104=hadoop104:2888:3888
之后在datas文件中创建myid文件输入103
分发
在****分发****zookeeper文件
之后在其他虚拟机上更改myid
编写zookeeper的启动脚本:
zk
\#!/bin/bash
if(($#!=1))
then
echo 请输入start或stop或status!
exit;
fi
if [ $1 = start ] || [ $1 = stop ] || [ $1 = status ]
then
xcall zkServer.sh $1
else
echo 请输入start或stop或status!
fi
KAFKA的安装
解压
将soft中的kafka解压到module
接下来配置kafka的文件
cd kafka/config
vim server.properties
把broker.id分别改为102/3/4
将delete的注释解开
将下面的log.dirs的地址改为:
/opt/module/kafka/datas
在到下面将zookeeper.connect改为
hadoop102:2181,hadoop103:2181,hadoop104:2181
分发
退回module将kafka分发
Zookeeper要在kafka前启动
在bin目录下编写kafka的启动脚本kf
\#!/bin/bash
\#只接收start和stop参数
if(($#!=1))
then
echo 请输入start或stop!
exit;
fi
if [ $1 = start ]
then
xcall kafka-server-start.sh -daemon $KAFKA_HOME/config/server.properties
elif [ $1 = stop ]
then xcall kafka-server-stop.sh
else
echo 请输入start或stop!
fi
Flume安装
解压+分发
!!!拦截器+第一层采集通道!!!
进入Hadoop03的flume中创建目录myagents
在myagents中创建test.conf文件
输入
\#a1是agent的名称,a1中定义了一个叫r1的source,如果有多个,使用空格间隔
a1.sources = r1
a1.sinks = k1
a1.channels = c1
\#组名名.属性名=属性值
a1.sources.r1.type=TAILDIR
a1.sources.r1.filegroups=f1
\#读取/tmp/logs/app-yyyy-mm-dd.log ^代表以xxx开头$代表以什么结尾 .代表匹配任意字符
\#+代表匹配任意位置
a1.sources.r1.filegroups.f1=/tmp/logs/^app.+.log$
\#JSON文件的保存位置
a1.sources.r1.positionFile=/opt/module/flume/test/log_position.json
\#定义拦截器
a1.sources.r1.interceptors = i1
a1.sources.r1.interceptors.i1.type = com.atguigu.dw.flume.MyInterceptor$Builder
\#定义sink
a1.sinks.k1.type=logger
\#定义chanel
a1.channels.c1.type=memory
a1.channels.c1.capacity=1000
\#连接组件 同一个source可以对接多个channel,一个sink只能从一个channel拿数据!
a1.sources.r1.channels=c1
a1.sinks.k1.channel=c1
创建f1.conf文件,输入:
\#a1是agent的名称,a1中定义了一个叫r1的source,如果有多个,使用空格间隔
a1.sources = r1
a1.channels = c1 c2
\#组名名.属性名=属性值
a1.sources.r1.type=TAILDIR
a1.sources.r1.filegroups=f1
a1.sources.r1.batchSize=1000
\#读取/tmp/logs/app-yyyy-mm-dd.log ^代表以xxx开头$代表以什么结尾 .代表匹配任意字符
\#+代表匹配任意位置
a1.sources.r1.filegroups.f1=/tmp/logs/^app.+.log$
\#JSON文件的保存位置
a1.sources.r1.positionFile=/opt/module/flume/test/log_position.json
\#定义拦截器
a1.sources.r1.interceptors = i1
a1.sources.r1.interceptors.i1.type = com.atguigu.dw.flume.MyInterceptor$Builder
\#定义ChannelSelector
a1.sources.r1.selector.type = multiplexing
a1.sources.r1.selector.header = topic
a1.sources.r1.selector.mapping.topic_start = c1
a1.sources.r1.selector.mapping.topic_event = c2
\#定义chanel
a1.channels.c1.type=org.apache.flume.channel.kafka.KafkaChannel
a1.channels.c1.kafka.bootstrap.servers=hadoop102:9092,hadoop103:9092,hadoop104:9092
a1.channels.c1.kafka.topic=topic_start
a1.channels.c1.parseAsFlumeEvent=false
a1.channels.c2.type=org.apache.flume.channel.kafka.KafkaChannel
a1.channels.c2.kafka.bootstrap.servers=hadoop102:9092,hadoop103:9092,hadoop104:9092
a1.channels.c2.kafka.topic=topic_event
a1.channels.c2.parseAsFlumeEvent=false
\#连接组件 同一个source可以对接多个channel,一个sink只能从一个channel拿数据!
a1.sources.r1.channels=c1 c2
分发
分发myagents
编写第一层采集通道的脚本f1:
\#!/bin/bash
\#使用start启动脚本,使用stop停止脚本
if(($#!=1))
then
echo 请输入start或stop!
exit;
fi
\#定义cmd用来保存要执行的命令
cmd=cmd
if [ $1 = start ]
then
cmd="nohup flume-ng agent -c $FLUME_HOME/conf/ -n a1 -f $FLUME_HOME/myagents/f1.conf -Dflume.root.logger=DEBUG,console > /home/f1.log 2>&1 &"
elif [ $1 = stop ]
then
cmd="ps -ef | grep f1.conf | grep -v grep | awk '{print \$2}' | xargs kill -9"
else
echo 请输入start或stop!
fi
\#在hadoop102和hadoop103开启采集
for i in hadoop102 hadoop103
do
ssh $i $cmd
done
在家目录创建f1.logs目录
之后执行f1
xcall jps
出现Application则说明启动成功
第二层采集通道
第二层通道在hadoop104启动
在hadoop104的/opt/module/flume/myagents中创建f2.conf:
a1.channels.c2.type=file
a1.channels.c2.checkpointDir=/opt/module/flume/c2/checkpoint
a1.channels.c2.useDualCheckpoints=true
a1.channels.c2.backupCheckpointDir=/opt/module/flume/c2/backupcheckpoint
a1.channels.c2.dataDirs=/opt/module/flume/c2/datas
\#sink
a1.sinks.k1.type = hdfs
\#一旦路径中含有基于时间的转义序列,要求event的header中必须有timestamp=时间戳,如果没有需要将useLocalTimeStamp = true
a1.sinks.k1.hdfs.path = hdfs://hadoop102:9000/origin_data/gmall/log/topic_start/%Y-%m-%d
a1.sinks.k1.hdfs.filePrefix = logstart-
a1.sinks.k1.hdfs.batchSize = 1000
\#文件的滚动
\#60秒滚动生成一个新的文件
a1.sinks.k1.hdfs.rollInterval = 30
\#设置每个文件到128M时滚动
a1.sinks.k1.hdfs.rollSize = 134217700
\#禁用基于event数量的文件滚动策略
a1.sinks.k1.hdfs.rollCount = 0
\#指定文件使用LZO压缩格式
a1.sinks.k1.hdfs.fileType = CompressedStream
a1.sinks.k1.hdfs.codeC = lzop
\#a1.sinks.k1.hdfs.round = true
\#a1.sinks.k1.hdfs.roundValue = 10
\#a1.sinks.k1.hdfs.roundUnit = second
a1.sinks.k2.type = hdfs
a1.sinks.k2.hdfs.path = hdfs://hadoop102:9000/origin_data/gmall/log/topic_event/%Y-%m-%d
a1.sinks.k2.hdfs.filePrefix = logevent-
a1.sinks.k2.hdfs.batchSize = 1000
a1.sinks.k2.hdfs.rollInterval = 30
a1.sinks.k2.hdfs.rollSize = 134217700
a1.sinks.k2.hdfs.rollCount = 0
a1.sinks.k2.hdfs.fileType = CompressedStream
a1.sinks.k2.hdfs.codeC = lzop
\#a1.sinks.k2.hdfs.round = true
\#a1.sinks.k2.hdfs.roundValue = 10
\#a1.sinks.k2.hdfs.roundUnit = second
\#连接组件
a1.sources.r1.channels=c1
a1.sources.r2.channels=c2
a1.sinks.k1.channel=c1
a1.sinks.k2.channel=c2
f2的启动脚本:
\#!/bin/bash
\#使用start启动脚本,使用stop停止脚本
if(($#!=1))
then
echo 请输入start或stop!
exit;
fi
if [ $1 = start ]
then
ssh hadoop104 "nohup flume-ng agent -c $FLUME_HOME/conf/ -n a1 -f $FLUME_HOME/myagents/f2.conf -Dflume.root.logger=INFO,console > /home/f2.log 2>&1 &"
elif [ $1 = stop ]
then
ssh hadoop104 "ps -ef | grep f2.conf | grep -v grep | awk '{print \$2}' | xargs kill -9"
else
echo 请输入start或stop!
fi
在家目录创建f2.log
启动后查看hadoop104的进程,如果有application则启动成功。
创建一键启动脚本(终于来了)(hadoop103上)
onekeyboot:
\#!/bin/bash
\#输入start和stop参数,一键启动或关闭hadoop,zk,kafka集群,启动f1,f2采集通道
if(($#!=1))
then
echo 请输入start或stop!
exit;
fi
\#编写函数,这个函数的功能为返回集群中启动成功的broker的数量
function countKafkaBrokders()
{
count=0
for((i=102;i<=104;i++))
do
result=$(ssh hadoop$i "jps | grep Kafka | wc -l")
count=$[$result+$count]
done
#函数可以定义返回值,如果不定义,返回函数最后一条命令的执行状态(返回0,代表成功,非0,即为异常)
return $count
}
\#启动,注意启动时,各个组件的依赖关系,例如zk必须先于kafka启动,后于kafka关闭
if [ $1 = start ]
then
zk start
hd start
kf start
#保证kafka集群已经启动时,才能启动f1,f2,判断当前kafka集群启动了多少 broker实例
while [ 1 ]
do
countKafkaBrokders
#如果返回值不为3,有可能是机器还尚未执行broker的启动命令,因此继续判断
if(($?==3))
then
break
fi
sleep 2s
done
f1 start
f2 start
#查看启动了哪些进程
xcall jps
elif [ $1 = stop ]
then
f1 stop
f2 stop
kf stop
#在kafka没有停止完成之前,不能停止zk集群
while [ 1 ]
do
countKafkaBrokders
#如果返回值不为0,kafka集群没有停止完成
if(($?==0))
then
break
fi
sleep 2s
done
zk stop
hd stop
#查看还剩了哪些进程
xcall jps
else
echo 请输入start或stop!
fi