基于Apache的电商数据仓库(二)

欢迎

你好!这是我历经1个半月的学习(Apache和CDH),做完的一个项目,本次和你们分享一下Apache版。
感谢您的阅读!
第1章~第4章在基于Apache的电商数据仓库(一)
第5章~第5章在基于Apache的电商数据仓库(二)
第6章~第8章在基于Apache的电商数据仓库(三)
第8章~第9章在基于Apache的电商数据仓库(四)
第10章~第12章在基于Apache的电商数据仓库(五)
第13章~第13章在基于Apache的电商数据仓库(六)
第14章~第14章在基于Apache的电商数据仓库(七)

第5章 数据采集

需准备:

  1. 白板机3台。配置好静态ip,关防火墙,创建cluster用户并给予root权限,主机映射,ssh免密,日期时间同步等
  2. jdk-8u144-linux-x64.tar.gz。并安装好,配置profile,.bashrc,将上一章的jar包写成脚本等

5.1 hadoop安装

  • 5.1.1 规划
  1. HDFS主要配置两大node:namenode和DataNode。
  2. yarn主要配置两大manager:resourcemanager和nodemanager。
  3. hadoop102配置NN和DN;hadoop103配置DN;hadoop104配置DN和SNN(secondarynamenode)
  4. hadoop102配置NM;hadoop103配置RN和NM;hadoop104配置NM
  • 5.1.2 安装

正常tar安装即可

  • 5.1.3 配置xml
  1. 配置集群
***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***
<property>
		<name>dfs.replication</name>
		<value>3</value>
</property>

<!-- 指定Hadoop辅助名称节点主机配置 -->
<property>
      <name>dfs.namenode.secondary.http-address</name>
      <value>hadoop104:50090</value>
</property>
***yarn-site.xml***
<!-- reducer获取数据的方式 -->
<property>
		<name>yarn.nodemanager.aux-services</name>
		<value>mapreduce_shuffle</value>
</property>

<!-- 指定YARN的ResourceManager的地址 -->
<property>
		<name>yarn.resourcemanager.hostname</name>
		<value>hadoop103</value>
</property>
**配置历史日志服务**


***mapred-site.xml***
<property>
<name>mapreduce.jobhistory.address</name>
<value>hadoop102:10020</value>
</property>
<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>


***yarn-site.xml***
<!-- 日志聚集功能使能 -->
<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.framework.name</name>
  <value>yarn</value>
</property>
  1. 配置slaves
vim /opt/module/hadoop-2.7.2/etc/hadoop/slaves

hadoop102
hadoop103
hadoop104
  1. 分发到haodop103和hadoop104
  2. 配置HADOOP_HOME(bin和sbin)
  • 5.1.4 格式化NN
hdfs namenode -format
  • 5.1.5 启动
start-dfs.sh
start-yarn.sh
编写启停脚本

查看
http://hadoop102:50070
http://hadoop103:8088
  • 5.1.6 LZO压缩配置

hadoop本身并不支持lzo压缩,故需要使用twitter提供的hadoop-lzo开源组件。

  1. 环境准备
    maven
    gcc-c++
    zlib-devel
    autoconf
    automake
    libtool
    通过yum安装即可

  2. 下载、安装并编译LZO

wget http://www.oberhumer.com/opensource/lzo/download/lzo-2.10.tar.gz

tar -zxvf lzo-2.10.tar.gz

cd lzo-2.10

./configure -prefix=/usr/local/hadoop/lzo/

make

make install
  1. 编译hadoop-lzo源码
下载hadoop-lzo的源码,下载地址:
	https://github.com/twitter/hadoop-lzo/archive/master.zip

解压之后,修改pom.xml
	<hadoop.current.version>2.7.2</hadoop.current.version>
声明两个临时环境变量
     export C_INCLUDE_PATH=/usr/local/hadoop/lzo/include
     export LIBRARY_PATH=/usr/local/hadoop/lzo/lib 
编译
    进入hadoop-lzo-master,执行maven编译命令
    mvn package -Dmaven.test.skip=true
进入target,hadoop-lzo-0.4.21-SNAPSHOT.jar 即编译成功的hadoop-lzo组件
  1. 将编译好后的hadoop-lzo-0.4.20.jar 放入hadoop-2.7.2/share/hadoop/common/
[cluster@hadoop102 common]$ pwd
/opt/module/hadoop-2.7.2/share/hadoop/common

[cluster@hadoop102 common]$ ls
hadoop-lzo-0.4.20.jar
  1. 同步hadoop-lzo-0.4.20.jar到hadoop103、hadoop104
[cluster@hadoop102 common]$ xsync hadoop-lzo-0.4.20.jar
  1. core-site.xml配置支持LZO
<configuration>
<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>
</configuration>

  1. 同步core-site.xml到hadoop103、hadoop104
  2. 启动集群
[cluster@hadoop102 hadoop-2.7.2]$ sbin/start-dfs.sh
[cluster@hadoop103 hadoop-2.7.2]$ sbin/start-yarn.sh
  1. 测试
yarn jar share/hadoop/mapreduce/hadoop-mapreduce-examples-2.7.2.jar wordcount -Dmapreduce.output.fileoutputformat.compress=true -Dmapreduce.output.fileoutputformat.compress.codec=com.hadoop.compression.lzo.LzopCodec /input /output
  1. lzo文件创建索引
hadoop jar ./share/hadoop/common/hadoop-lzo-0.4.20.jar com.hadoop.compression.lzo.DistributedLzoIndexer /output
  • 5.1.7 参数调优
  1. 调优hdfs-site.xml
dfs.namenode.handler.count=
比如此次进群3台,参数设置为   20*log23=20
  1. 调优yarn-site.xml
(a)表示该节点上YARN可使用的物理内存总量
yarn.nodemanager.resource.memory-mb

(b)单个任务可申请的最多物理内存量
yarn.scheduler.maximum-allocation-mb

5.2 zookeeper安装

  • 5.2.1 安装ZK
  1. 正常安装即可
tar -zxvf  ...  -C ...
  1. 修改zoo.cfg文件
dataDir=/opt/module/zookeeper-3.4.10/datas
需要手动创建datas
  1. 创建一个myid的文件
cd /opt/module/zookeeper-3.4.10/datas
vim myid
103
  1. 分发ZK
  2. 修改每台机器的myid
  3. 配置ZOOKEEPER_HOME(bin)
  • 5.2.2 创建zk启停脚本
  1. 内容如下
#! /bin/bash

case $1 in
"start"){
    
    
	for i in hadoop102 hadoop103 hadoop104
	do
		ssh $i "/opt/module/zookeeper-3.4.10/bin/zkServer.sh start"
	done
};;
"stop"){
    
    
	for i in hadoop102 hadoop103 hadoop104
	do
		ssh $i "/opt/module/zookeeper-3.4.10/bin/zkServer.sh stop"
	done
};;
"status"){
    
    
	for i in hadoop102 hadoop103 hadoop104
	do
		ssh $i "/opt/module/zookeeper-3.4.10/bin/zkServer.sh status"
	done
};;
esac

  1. 增加脚本权限
[cluster@hadoop102 bin]$ chmod 777 zk.sh
  1. 启停脚本
zk.sh start
zk.sh stop

5.3 日志采集的flume安装

  • 5.3.1 规划
  1. 2个采集日志中的flume,1个采集kafka的flume
  2. hadoop102,hadoop103和hadoop104
  • 5.3.2 安装
tar -zxvf ... -C ...
  • 5.3.3 配置FLUME_HOME

5.4 kafka安装

  • 5.4.1 正常安装

  • 5.4.2 配置

配置kafka/config/server.properties

修改以下几点

broker.id=103
delete.topic.enable=true
log.dirs=/opt/module/kafka/datas
zookeeper.connect=hadoop102:2181,hadoop103:2181,hadoop104:2181
  • 5.4.3 配置KAFKA_HOME

  • 5.4.4 分发kafka

5.5 第一层采集通道编写

  • 5.5.1 选择source 和 channel
  1. source:TailDirSource 接近实时读取指定的文件!断点续传功能!
  2. channel:KafkaChannel 基于kafka,提高了可用性!
  • 5.5.2 编写自定义拦截器
public class MyInterceptor implements Interceptor{
    
    
	
	//创建一个放置复合要求数据的集合
	private List<Event> results=new ArrayList<>();
	
	private String startFlag="\"en\":\"start\"";

	@Override
	public void initialize() {
    
    
		
	}

	//核心方法
	@Override
	public Event intercept(Event event) {
    
    
		
		byte[] body = event.getBody();
		
		Map<String, String> headers = event.getHeaders();
		
		String bodyStr = new String(body, Charset.forName("utf-8"));
		
		boolean flag=true;

		if (bodyStr.contains(startFlag)) {
    
    
			
			headers.put("topic", "topic_start");
			
			flag=ETLUtil.validStartLog(bodyStr);
			
		}else {
    
    
			
			headers.put("topic", "topic_event");
			
			flag=ETLUtil.validEventLog(bodyStr);
			
		}

		if (!flag) {
    
    
			return null;
		}
		
		return event;
	}

	@Override
	public List<Event> intercept(List<Event> events) {
    
    
		
		results.clear();
		
		for (Event event : events) {
    
    
			
			Event result = intercept(event);
			
			if (result !=null) {
    
    
				
				//放入合法的数据集合中
				results.add(result);
				
			}
		
		}
		
		return results;
	}

	@Override
	public void close() {
    
    
		
	}
	
	 public static class Builder implements Interceptor.Builder{
    
    

		 //从flume的配置文件中读取参数
		@Override
		public void configure(Context context) {
    
    
			
			
		}

		//创建一个拦截器对象
		@Override
		public Interceptor build() {
    
    
			return new MyInterceptor();
		}
		 
		 
	 }

}
  • 5.5.3 编写flume执行conf

放到flume/myagents下

a1.sources = r1
a1.channels = c1 c2

a1.sources.r1.type=TAILDIR
a1.sources.r1.filegroups=f1
a1.sources.r1.batchSize=1000
a1.sources.r1.filegroups.f1=/tmp/logs/^app.+.log$
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


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

#连接组件
a1.sources.r1.channels=c1 c2


  • 5.5.4 测试
flume-ng agent -n a1 -f myagents/f1.conf -c conf/ -Dflume.root.logger=DEBUG,console
  • 5.5.5 第一层采集通道总结

从本机读取/ tmp/logs中的日志数据,通过flume, 传输到kafka中

1.保证/tmp/logs中有app-xxx. log

2.使用taildirsource,taildirsource会 讲上次读取数据的位置记录在json文件中可以查看json文件是否更新,判断是否新读取了数据

3.flume agent的工作原理 source ---->拦截器(ETL 1为header添加topic=topic_ start Itopic_ event)----> MuliplexingChannelSelector
(根据自己配置的映射信息,讲指定的event分配到channel)

5.6第二层采集通道编写

  • 5.6.1 选择source、channel、sink
  1. source

kafkasource
数据源在kafka,因此需要使用一个可以对接kafka的source

  1. channel

为了安全起见,选择filechannel

  1. sink

目的地在hdfs,使用hdfssink

  • 5.6.2 编写flume启动所需的conf
#配置文件编写
a1.sources = r1 r2
a1.sinks = k1 k2
a1.channels = c1 c2

#配置source
a1.sources.r1.type=org.apache.flume.source.kafka.KafkaSource
a1.sources.r1.kafka.bootstrap.servers=hadoop102:9092,hadoop103:9092,hadoop104:9092
a1.sources.r1.kafka.topics=topic_start
a1.sources.r1.kafka.consumer.auto.offset.reset=earliest
a1.sources.r1.kafka.consumer.group.id=CG_Start

a1.sources.r2.type=org.apache.flume.source.kafka.KafkaSource
a1.sources.r2.kafka.bootstrap.servers=hadoop102:9092,hadoop103:9092,hadoop104:9092
a1.sources.r2.kafka.topics=topic_event
a1.sources.r2.kafka.consumer.auto.offset.reset=earliest
a1.sources.r2.kafka.consumer.group.id=CG_Event


#配置channel
a1.channels.c1.type=file
a1.channels.c1.checkpointDir=/opt/module/flume/c1/checkpoint
a1.channels.c1.useDualCheckpoints=true
a1.channels.c1.backupCheckpointDir=/opt/module/flume/c1/backupcheckpoint
a1.channels.c1.dataDirs=/opt/module/flume/c1/datas


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
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
a1.sinks.k1.hdfs.rollInterval = 30
a1.sinks.k1.hdfs.rollSize = 134217700
a1.sinks.k1.hdfs.rollCount = 0
a1.sinks.k1.hdfs.fileType = CompressedStream 
a1.sinks.k1.hdfs.codeC = lzop



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.sources.r1.channels=c1
a1.sources.r2.channels=c2
a1.sinks.k1.channel=c1
a1.sinks.k2.channel=c2


  • 5.6.3 测试
flume-ng agent -n a1 -f myagents/f2.conf -c conf/ -Dflume.root.logger=DEBUG,console
  • 5.6.4 第二层采集通道总结

kafkaSource------>FileChannel------>HDFSSink

数据

验证kafkaSource------>FileChannel是否有问题 查看消费者组是否有lag。或运行test2.conf,使用loggersink看是否在控制台有数据的输出。验证时,需要注意,每次消费了数据后,当前消费者组都会提交offset!下次只会从之前的offset继续消费,因此,可以尝试重置offset
验证FileChannel------>HDFSSink是否有问题 遇到问题可以尝试讲日志级别设置 WARN,方便调试

5.7报错总结

  1. 导入pom.xml的maven-assembly-plugin报错

新建个class,打一次包试试
不行就加个依赖,在次打包

  1. 前面配置的lzo压缩,在运行f2.conf时报错,说不支持lzo压缩

使用lzo压缩要配置到core-site.xml中,不能配置到mapred-site.xml中,应为之前是MR运行可以读到lzo压缩,但是使用flume时,只能读到8个配置文件,读不到mapred-site.xml

第6章 用户行为数仓分层概念

请移步至基于Apache的电商数据仓库(三)

猜你喜欢

转载自blog.csdn.net/qq_43494678/article/details/114991772
今日推荐