项目:数仓采集(一)配置集群JDK+hadoop+zookeeper+kafka+Flume

准备服务器

设置host

如果本地集群 16G 8、3、3 其他随意 8、4、4

以下为阿里云为主 本地需要设置本机host、防火墙和网络

我选的3台 阿里云服务器 每台2核8G 带宽100M拉满 按量计费便宜

屏幕快照 2020-05-15 下午9.18.22

配置host 需要用私网

shell远程登入用公网 密码为复杂密码

机器名称设置为正则表达式 hadoop[102,3]

不需要关闭防火墙 、网络

以下配置三台都要做!!!建个用户 赋予权限 免密登入

[root@hadoop103 ~]# vim /etc/hosts
172.24.143.121	hadoop102	hadoop102
172.24.143.122	hadoop103
172.24.143.120	hadoop104
sudo权限
[root@hadoop104 ~]# sudo useradd vanas
[root@hadoop104 ~]# sudo passwd vanas
更改用户 vanas 的密码 。
新的 密码:
重新输入新的 密码:
passwd:所有的身份验证令牌已经成功更新

[root@hadoop102 ~]# sudo vim /etc/sudoers
vanas	ALL=(ALL)     ALL
#注意放置位置 以及大小写
[root@hadoop104 ~]# cd /opt/
[root@hadoop104 opt]# mkdir software module
[root@hadoop104 opt]# chown vanas:vanas software/ module/
[root@hadoop104 opt]# ll
总用量 8
drwxr-xr-x 2 vanas vanas 4096 5月  14 15:26 module
drwxr-xr-x 2 vanas vanas 4096 5月  14 15:26 software
编写群发脚本xsync
[vanas@hadoop102 ~]$ mkdir bin
[vanas@hadoop102 ~]$ cd bin
[vanas@hadoop102 bin]$ vim xsync
#!/bin/bash
#1. 判断参数个数
if [ $# -lt 1 ]
then
  echo Not Enough Arguement!
  exit;
fi
#2. 遍历集群所有机器
for host in hadoop102 hadoop103 hadoop104
do
  echo ====================  $host  ====================
  #3. 遍历所有目录,挨个发送
  for file in $@
  do
    #4 判断文件是否存在
    if [ -e $file ]
    then
      #5. 获取父目录
      pdir=$(cd -P $(dirname $file); pwd)
      #6. 获取当前文件的名称
      fname=$(basename $file)
      ssh $host "mkdir -p $pdir"
      rsync -av $pdir/$fname $host:$pdir
    else
      echo $file does not exists!
    fi
  done
done
[vanas@hadoop102 bin]$ chmod +x xsync 
远程访问免密

3台

[vanas@hadoop102 bin]$ ssh-keygen -t rsa
[vanas@hadoop102 bin]$ ssh-copy-id hadoop102
[vanas@hadoop102 bin]$ ssh-copy-id hadoop103
[vanas@hadoop102 bin]$ ssh-copy-id hadoop104

JDK

环境变量设置和分发

[vanas@hadoop102 software]$ tar -zxvf jdk-8u212-linux-x64.tar.gz -C /opt/module/
[vanas@hadoop102 software]$ sudo vim /etc/profile.d/my_env.sh
#JAVA_HOME
export JAVA_HOME=/opt/module/jdk1.8.0_212
export PATH=$PATH:$JAVA_HOME/bin

[vanas@hadoop102 ~]$ java -version
java version "1.8.0_212"
Java(TM) SE Runtime Environment (build 1.8.0_212-b10)
Java HotSpot(TM) 64-Bit Server VM (build 25.212-b10, mixed mode)

[vanas@hadoop102 ~]$ xsync /opt/module/jdk1.8.0_212/
[vanas@hadoop102 ~]$ sudo /home/vanas/bin/xsync /etc/profile.d/my_env.sh

source /etc/profile.d/my_env.sh 或重新开始窗口

关于profile.d

/etc/profile.d 登入时加载 ssh Hadoop102 jps 非登入模式

.bachrc

/etc/profile.d/my_env.sh 所以最好用这个方式配

采集日志

mkdir applog

102上传日志文件 并发送给103

[vanas@hadoop103 applog]$ scp hadoop102:/opt/module/applog/gmall2020-mock-log-2020-04-01.jar ./
[vanas@hadoop103 applog]$ scp hadoop102:/opt/module/applog/application.properties ./
[vanas@hadoop103 applog]$ scp hadoop102:/opt/module/applog/path2.json ./

log为后生成的日志

屏幕快照 2020-05-14 下午5.36.52

编写脚本(为了方便)

要写绝对路径

[vanas@hadoop102 bin]$ vim log.sh
#!/bin/bash
for i in hadoop102 hadoop103; do
    echo "========== $i =========="
    ssh $i "cd /opt/module/applog/; java -jar gmall2020-mock-log-2020-04-01.jar >/dev/null 2>&1 &"
done 
[vanas@hadoop102 bin]$chmod 777 log.sh

集群所有进程查看脚本

[vanas@hadoop102 bin]$ vim xcall.sh
#! /bin/bash

for i in hadoop102 hadoop103 hadoop104
do
    echo --------- $i ----------
    ssh $i "$*"
done
[vanas@hadoop102 bin]$ chmod 777 xcall.sh 

$* 所有参数看成一个整体

“A1,a2,a3,a4”

@*

“a1” “a2” “a3” “a4”

Hadoop

ssh免密 、jdk已完成

生产环境再配置HA

集群基础配置(重要)

集群规划

服务器hadoop102服务器hadoop103服务器hadoop104
HDFSNameNodeDataNodeDataNodeDataNodeSecondaryNameNode
YarnNodeManagerResourcemanagerNodeManagerNodeManager

解压与安装

[vanas@hadoop102 software]$ tar -zxvf hadoop-3.1.3.tar.gz -C /opt/module/

[vanas@hadoop102 module]$ sudo vim /etc/profile.d/my_env.sh
#在文件末尾 添加(**shift+g**)
##HADOOP_HOME
export HADOOP_HOME=/opt/module/hadoop-3.1.3
export PATH=$PATH:$HADOOP_HOME/bin
export PATH=$PATH:$HADOOP_HOME/sbin
[vanas@hadoop102 module]$ source /etc/profile.d/my_env.sh

ect/hadoop/ 下有许多配置文件 其中workers 是在hadoop3中 其他版本可能是slaves

[vanas@hadoop102 hadoop]$ vim workers 
hadoop102
hadoop103
hadoop104
core-site.xml

3.1多 又改回了8020 3刚开始的时候9820

proxyuser代理用户是hive中beline

a代理b hosts是代理启动 超级用户 可以代理所有用户

group 代理所有组

http hadoop3 可以在web界面 进行目录增删

[vanas@hadoop102 hadoop-3.1.3]$ cd etc/hadoop/
[vanas@hadoop102 hadoop]$ vim core-site.xml 
<configuration>
    <property>
        <name>fs.defaultFS</name>
        <value>hdfs://hadoop102:8020</value>
    </property>
    <property>
        <name>hadoop.tmp.dir</name>
        <value>/opt/module/hadoop-3.1.3/data</value>
    </property>
    <property>
        <name>hadoop.proxyuser.vanas.hosts</name>
        <value>*</value>
    </property>
    <property>
        <name>hadoop.proxyuser.vanas.groups</name>
        <value>*</value>
    </property>
    <property>
        <name>hadoop.http.staticuser.user</name>
        <value>vanas</value>
    </property>
</configuration>

配置项的解读:

dir缓存:

官网说明:

hadoop.tmp.dir  /tmp/hadoop-${user.name}  A base for other temporary directories.

该地址会被别的配置项所引用如dfs.datanode.data.dir
是一个中间变量 ,间接指定了namenode和datanode的存放位置

proxyuser代理说明:

情景:以编写HQL 通过HiveServer2 进而提交给hadoop集群MapReduce为说明:

情况1:

hiveserver2提交任务给到yarn的用户

hiveServer2 :a

beeline用户;a

提交到yarn的用户:a

==============================

情况2:

hiveServer2 :a

beeline用户;b

提交到yarn的用户:a

b的权限低,但提交的权限升高了,可能会造成影响

解决办法:实现代理
hiveServer2 :a

beeline用户;b

提交Yarn时 :是a(代理),但是实际执行的Hql是b(代理)

======================================

adoop.proxyuser.atguigu.hosts 和 hadoop.proxyuser.atguigu.groups 指的是

用户可以代理所有用户和所有组

Web用户权限

hadoop.http.staticuser.user 指定Web访问的用户 避免Web用户使用了不同权限用户

补充:对于一个服务来说,谁启动服务,则谁就是这个服务的超级用户,与Linux系统的root无关联

hdfs-site.xml

[vanas@hadoop102 hadoop]$ vim hdfs-site.xml

datenode和namenode都有默认值

    <property>
        <name>dfs.namenode.secondary.http-address</name>
        <value>hadoop104:9868</value>
    </property>
yarn-site.xml

[vanas@hadoop102 hadoop]$ vim yarn-site.xml

yarn.nodemanager.resource.memory-mb nm交给rm最大资源默认8G

在公司生产环境时服务器一般服务器内存都为128G,需要修改到100G,否则执行缓慢

前两个配置 一个container最多和最少能获得大资源

yarn.scheduler.minimum-allocation-mb
yarn.scheduler.maximum-allocation-mb

    <property>
        <name>yarn.nodemanager.aux-services</name>
        <value>mapreduce_shuffle</value>
    </property>
    <property>
        <name>yarn.resourcemanager.hostname</name>
        <value>hadoop103</value>
</property>
<property>
        <name>yarn.nodemanager.env-whitelist</name>						<value>JAVA_HOME,HADOOP_COMMON_HOME,HADOOP_HDFS_HOME,HADOOP_CONF_DIR,CLASSPATH_PREPEND_DISTCACHE,HADOOP_YARN_HOME,HADOOP_MAPRED_HOME</value>
    </property>
    <property>
        <name>yarn.scheduler.minimum-allocation-mb</name>
        <value>512</value>
    </property>
    <property>
        <name>yarn.scheduler.maximum-allocation-mb</name>
        <value>4096</value>
    </property>
    <property>
        <name>yarn.nodemanager.resource.memory-mb</name>
        <value>4096</value>
    </property>
    <property>
        <name>yarn.nodemanager.vmem-check-enabled</name>
        <value>false</value>
    </property>

https://hadoop.apache.org/docs/stable/hadoop-yarn/hadoop-yarn-common/yarn-default.xml

mapred.site.xml
<configuration>
    <property>
        <name>mapreduce.framework.name</name>
        <value>yarn</value>
    </property>
</configuration>
workers/slaves配置
#配置workers
[vanas@hadoop102 hadoop]$ vim /opt/module/hadoop-3.1.3/etc/hadoop/workers
#在该文件中增加如下内容:
hadoop102
hadoop103
hadoop104
配置历史服务器

配置在哪台在哪台起

[vanas@hadoop102 hadoop]$ vim 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>

启动指令

[vanas@hadoop102 hadoop]$ maperd —daemon start historyserver
日志聚集功能

把nodemanager的日志放到hdfs上这样web端就可以查看了

注意:开启日志聚集功能,需要重新启动

[vanas@hadoop102 hadoop]$ vim yarn-site.xml

保留日志时间 7天

历史服务器地址

    <property>
        <name>yarn.log-aggregation-enable</name>
        <value>true</value>
    </property>
    <property>  
        <name>yarn.log.server.url</name>  
        <value>http://hadoop102:19888/jobhistory/logs</value>  
    </property> 
    <property>
        <name>yarn.log-aggregation.retain-seconds</name>
        <value>604800</value>
		</property>

启动测试是否可以跑通

#分发
[vanas@hadoop102 module]$ xsync hadoop-3.1.3/ 
[vanas@hadoop102 module]$ sudo /home/vanas/bin/xsync /etc/profile.d/my_env.sh

[vanas@hadoop102 hadoop-3.1.3]$ hdfs namenode -format

[vanas@hadoop102 ~]$ hadoop jar /opt/module/hadoop-3.1.3/share/hadoop/mapreduce/hadoop-mapreduce-examples-3.1.3.jar pi 1 1
关于集群时间同步

时间同步的方式:找一个机器,作为时间服务器,所有的机器与这台集群时间进行定时的同步,比如,每隔十分钟,同步一次时间。

云服务器不用配

物理机 需要配

关于2nn页面不显示问题

查看dfs-dust.js的第61行

'date_tostring' : function (v) {
  return moment(Number(v)).format('ddd MMM DD HH:mm:ss ZZ YYYY');
},

找不到moment函数。在此打断点,并修改函数返回值为:

'date_tostring' : function (v) {
  return new Date(Number(v)).toLocaleString();
},
阿里云安全组

9868、8088、19888、9870 web端访问

屏幕快照 2020-05-15 下午10.12.11

Hadoop项目经验

HDFS存储多目录

屏幕快照 2020-05-15 下午9.52.48

概述:一般生产服务器的磁盘都不止一块,如果要让hdfs的datanode存储在不止一块磁盘,需要配置多目录,同时注意新挂载磁盘的访问权限问题

HDFS的DataNode节点保存数据的路径由dfs.datanode.data.dir参数决定,其默认值为file://${hadoop.tmp.dir}/dfs/data,若服务器有多个磁盘,必须对该参数进行修改。如服务器磁盘如上图所示,则该参数应修改为如下的值

<property>
    <name>dfs.datanode.data.dir</name>
<value>file:///dfs/data1,file:///hd2/dfs/data2,file:///hd3/dfs/data3,file:///hd4/dfs/data4</value>
</property>

注意: file:// 充当协议,表示本地文件 /dfs 表示根目录下的dfs

集群数据均衡

节点间的数据均衡

#开启数据均衡命令:
start-balancer.sh –threshold 10
#对于参数10,代表的是集群中各个节点的磁盘空间利用率相差不超过10%,可根据实际情况进行调整。
#停止数据均衡命令:
stop-balancer.sh

磁盘间的数据均衡

(Hadoop3引入的新特性)

针对有多个挂在磁盘

#生成均衡计划
hdfs diskbalancer -plan hadoop102
#执行均衡计划
hdfs diskbalancer -execute hadoop102.plan.json
#查看当前均衡任务的执行情况
hdfs diskbalancer -query hadoop102
#取消均衡任务
hdfs diskbalancer -cancel hadoop102.plan.json

Q:停止时是否对数据有影响
已经完成的 不会变,不会回退
未完成的就不执行

Q加了新磁盘后挂载后 , data.dir 多目录 配置时没有配置这个新的磁盘怎么办
必须配置,否则无法使用

LZO配置

因为hadoop自带不具备Lzo压缩类型

优点 可切片

[vanas@hadoop102 software]$ cp hadoop-lzo-0.4.20.jar /opt/module/hadoop-3.1.3/share/hadoop/common/
[vanas@hadoop102 software]$ cd /opt/module/hadoop-3.1.3/share/hadoop/common/
[vanas@hadoop102 common]$ xsync hadoop-lzo-0.4.20.jar 

core-site.xml增加配置支持LZO压缩

[vanas@hadoop102 common]$ cd /opt/module/hadoop-3.1.3/etc/hadoop/
[vanas@hadoop102 hadoop]$ vim 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>
[vanas@hadoop102 hadoop]$ xsync core-site.xml 

Hadoop能使用的压缩解压缩格式:
io.compression.codecs

测试lzo

[vanas@hadoop102 hadoop]$ hadoop fs -mkdir /input
[vanas@hadoop102 hadoop]$ hadoop fs -put works /input/
[vanas@hadoop102 hadoop]$ hadoop jar /opt/module/hadoop-3.1.3/share/hadoop/mapreduce/hadoop-mapreduce-examples-3.1.3.jar wordcount -Dmapreduce.output.fileoutputformat.compress=true -Dmapreduce.output.fileoutputformat.compress.codec=com.hadoop.compression.lzo.LzopCodec  /input /output

屏幕快照 2020-05-14 下午7.33.11

lzo需要建立索引才可以切片 不建索引依然是一片

建索引

hadoop jar /opt/module/hadoop-3.1.3/share/hadoop/common/hadoop-lzo-0.4.20.jar  com.hadoop.compression.lzo.DistributedLzoIndexer /input/bigtable.lzo

com.hadoop.compression.lzo.DistributedLzoIndexer 为Lzo官方指定的索引类名

基准测试

集群核心数的确认

开启Hadoop集群后从Yarn上可以观察到集群的核心数量

如果是线上环境,有几核最多就有几个,如图是24个,那么公式为24-1 ,最多可以跑23个maptask 需要预留1个跑appmaster

虚拟机情况下取决于 主机的个数 我的是8核心 既选7个

测试HDFS的读写性能

#写测试,向HDFS集群写10个128M的文件
hadoop jar /opt/module/hadoop-3.1.3/share/hadoop/mapreduce/hadoop-mapreduce-client-jobclient-3.1.3-tests.jar TestDFSIO -write -nrFiles 10 -fileSize 128MB

#读测试,向HDFS集群读10个128M的文件
hadoop jar /opt/module/hadoop-3.1.3/share/hadoop/mapreduce/hadoop-mapreduce-client-jobclient-3.1.3-tests.jar TestDFSIO -read -nrFiles 10 -fileSize 128MB

这里以写数据性能分析为例,读性能测试不在缀述

 Number of files(集群同时能运行的最多maptask个数): 7
Total MBytes processed(总吞吐量): 896
Throughput mb/sec(): 0.85   单个maptask的吞吐量  

计算逻辑:896/(Tm1+Tm2+Tm3+...)

 Average IO rate mb/sec: 0.92 单台maptask的吞吐量

计算逻辑:[(m1/Tm1)+(m2/Tm2)+...]/7

IO rate std deviation: 0.21   方差,值越小 maptask之间的差值越小,集群越稳定
Test exec time sec: 308.89  :总用时

MapReduce性能测试
因虚拟机或学习用阿里云无法提供足够的资源,
真实的10台物理机128G内存 的测试参数为 50s

记!!! 不要测试map

Hadoop参数调优

HDFS参数调优hdfs-site.xml

The number of Namenode RPC server threads that listen to requests from clients. If dfs.namenode.servicerpc-address is not configured then Namenode RPC server threads listen to requests from all nodes.
NameNode有一个工作线程池,用来处理不同DataNode的并发心跳以及客户端并发的元数据操作。
对于大集群或者有大量客户端的集群来说,通常需要增大参数dfs.namenode.handler.count的默认值10。
<property>
    <name>dfs.namenode.handler.count</name>
    <value>10</value>
</property>

YARN参数调优yarn-site.xml

(1)情景描述:总共7台机器,每天几亿条数据,数据源->Flume->Kafka->HDFS->Hive

面临问题:数据统计主要用HiveSQL,没有数据倾斜,小文件已经做了合并处理,开启的JVM重用,而且IO没有阻塞,内存用了不到50%。但是还是跑的非常慢,而且数据量洪峰过来时,整个集群都会宕掉。基于这种情况有没有优化方案。

(2)解决办法:

内存利用率不够。这个一般是Yarn的2个配置造成的,单个任务可以申请的最大内存大小,和Hadoop单个节点可用内存大小。调节这两个参数能提高系统内存的利用率。

(a)yarn.nodemanager.resource.memory-mb

表示该节点上YARN可使用的物理内存总量,默认是8192(MB),注意,如果你的节点内存资源不够8GB,则需要调减小这个值,而YARN不会智能的探测节点的物理内存总量。

(b)yarn.scheduler.maximum-allocation-mb

单个任务可申请的最多物理内存量,默认是8192(MB)。

Zookeeper

集群规划:

服务器hadoop102服务器hadoop103服务器hadoop104
ZookeeperZookeeperZookeeperZookeeper

安装与初始化配置

[vanas@hadoop102 module]$ tar -zxvf apache-zookeeper-3.5.7-bin.tar.gz -C /opt/module/
[vanas@hadoop102 module]$ mv apache-zookeeper-3.5.7-bin/ zookeeper-3.5.7
[vanas@hadoop102 zookeeper-3.5.7]$ mkdir zkData
[vanas@hadoop102 zookeeper-3.5.7]$ cd zkData/
[vanas@hadoop102 zkData]$ vim myid
2
#myid三台分别改
[vanas@hadoop102 zookeeper-3.5.7]$ cd conf/
[vanas@hadoop102 conf]$ mv zoo_sample.cfg zoo.cfg
[vanas@hadoop102 conf]$ vim zoo.cfg 
dataDir=/opt/module/zookeeper-3.5.7/zkData
#######################cluster##########################
server.2=hadoop102:2888:3888
server.3=hadoop103:2888:3888
server.4=hadoop104:2888:3888
[vanas@hadoop102 module]$ xsync zookeeper-3.5.7/

**配置参数解读:**server.A=B:C:D

A是一个数字,表示这个是第几号服务器;

集群模式下配置一个文件myid,这个文件在dataDir目录下,这个文件里面有一个数据就是A的值,Zookeeper启动时读取此文件,拿到里面的数据与zoo.cfg里面的配置信息比较从而判断到底是哪个server。

B是这个服务器的地址;

C是这个服务器Follower与集群中的Leader服务器交换信息的端口;

D是万一集群中的Leader服务器挂了,需要一个端口来重新进行选举,选出一个新的Leader,而这个端口就是用来执行选举时服务器相互通信的端口。

群起脚本

[vanas@hadoop102 bin]$ vim zk.sh
#! /bin/bash

case $1 in
"start"){
	for i in hadoop102 hadoop103 hadoop104
	do
        echo ---------- zookeeper $i 启动 ------------
		ssh $i "/opt/module/zookeeper-3.5.7/bin/zkServer.sh start"
	done
};;
"stop"){
	for i in hadoop102 hadoop103 hadoop104
	do
        echo ---------- zookeeper $i 停止 ------------    
		ssh $i "/opt/module/zookeeper-3.5.7/bin/zkServer.sh stop"
	done
};;
"status"){
	for i in hadoop102 hadoop103 hadoop104
	do
        echo ---------- zookeeper $i 状态 ------------    
		ssh $i "/opt/module/zookeeper-3.5.7/bin/zkServer.sh status"
	done
};;
esac

[vanas@hadoop102 bin]$ chmod 777 zk.sh 

Kafka

屏幕快照 2020-05-15 下午10.34.00

集群规划:

服务器hadoop102服务器hadoop103服务器hadoop104
KafkaKafkaKafkaKafka

安装与初始化配置

不光是运行日志 还有kafka生产者的topic

/kafka 是放在zookeeper的/kafka路径下

[vanas@hadoop102 software]$ tar -zxvf kafka_2.11-2.4.1.tgz -C /opt/module/
[vanas@hadoop102 module]$ mv kafka_2.11-2.4.1/ kafka
[vanas@hadoop102 kafka_2.11-2.4.1]$ mkdir logs
[vanas@hadoop102 kafka_2.11-2.4.1]$ cd config/
[vanas@hadoop102 config]$ vim server.properties
修改或者增加以下内容:
#broker的全局唯一编号,不能重复 103 104也改
broker.id=0
#删除topic功能使能
delete.topic.enable=true
#kafka运行日志存放的路径
log.dirs=/opt/module/kafka/logs
#配置连接Zookeeper集群地址
zookeeper.connect=hadoop102:2181,hadoop103:2181,hadoop104:2181/kafka

其他默认配置详情(无需要不需改动)

#处理网络请求的线程数量
num.network.threads=3
#用来处理磁盘IO的现成数量
num.io.threads=8
#发送套接字的缓冲区大小
socket.send.buffer.bytes=102400
#接收套接字的缓冲区大小
socket.receive.buffer.bytes=102400
#请求套接字的缓冲区大小
socket.request.max.bytes=104857600
#topic在当前broker上的分区个数
num.partitions=1
#用来恢复和清理data下数据的线程数量
num.recovery.threads.per.data.dir=1
#segment文件保留的最长时间,超时将被删除
log.retention.hours=168

配置环境变量(可以不配)

[vanas@hadoop102 config]$ sudo vi /etc/profile.d/my_env.sh
#KAFKA_HOME
export KAFKA_HOME=/opt/module/kafka
export PATH=$PATH:$KAFKA_HOME/bin
[vanas@hadoop102 config]$ source /etc/profile.d/my_env.sh

群起脚本

[vanas@hadoop102 bin]$ vim kafka.sh
#! /bin/bash

case $1 in
"start"){
    for i in hadoop102 hadoop103 hadoop104
    do
        echo " --------启动 $i Kafka-------"
        ssh $i "/opt/module/kafka/bin/kafka-server-start.sh -daemon /opt/module/kafka/config/server.properties "
    done
};;
"stop"){
    for i in hadoop102 hadoop103 hadoop104
    do
        echo " --------停止 $i Kafka-------"
        ssh $i "/opt/module/kafka/bin/kafka-server-stop.sh stop"
    done
};;
esac
[vanas@hadoop102 bin]$ chmod 777 kafka.sh 

测试

#创建topic
[vanas@hadoop102 ~]$ kafka-topics.sh --zookeeper hadoop102:2181/kafka --create --topic test --partitions 1 --replication-factor 1
Created topic test.

[vanas@hadoop102 ~]$ kafka-console-producer.sh --broker-list hadoop102:9092 --topic first

[vanas@hadoop103 kafka]$ bin/kafka-console-consumer.sh --bootstrap-server hadoop102:9092 --topic first  
[vanas@hadoop102 kafka]$ kafka-topics.sh --list --bootstrap-server hadoop102:9092
__consumer_offsets
first
test

Kafka项目经验

压力测试

用Kafka官方自带的脚本,对Kafka进行压测。Kafka压测时,可以查看到哪个地方出现了瓶颈(CPU,内存,网络IO)。一般都是网络IO达到瓶颈。

kafka-consumer-perf-test.sh

kafka-producer-perf-test.sh

#生产者
[vanas@hadoop102 kafka]$ bin/kafka-producer-perf-test.sh  --topic test --record-size 100 --num-records 100000 --throughput -1 --producer-props bootstrap.servers=hadoop102:9092,hadoop103:9092,hadoop104:9092

100000 records sent, 50735.667174 records/sec (4.84 MB/sec), 863.43 ms avg latency, 1184.00 ms max latency, 890 ms 50th, 1160 ms 95th, 1176 ms 99th, 1184 ms 99.9th.


说明:

record-size是一条信息有多大,单位是字节。

num-records是总共发送多少条信息。

throughput 是每秒多少条信息,设成-1,表示不限流,可测出生产者最大吞吐量。

参数解析:本例中一共写入10w条消息,吞吐量为4.84MB/sec,每次写入的平均延迟为863.43毫秒,最大的延迟为1184.00毫秒。

890 ms 50th, 1160 ms 95th, 1176 ms 99th, 1184 ms 99.9th :描绘了延迟的走势图

横轴是所有数据,纵轴为延迟,表征50%的message在863.43s以下,以此类推

#消费者
[vanas@hadoop102 kafka]$ bin/kafka-consumer-perf-test.sh --broker-list hadoop102:9092,hadoop103:9092,hadoop104:9092 --topic test --fetch-size 10000 --messages 10000000 --threads 1

start.time, end.time, data.consumed.in.MB, MB.sec, data.consumed.in.nMsg, nMsg.sec, rebalance.time.ms, fetch.time.ms, fetch.MB.sec, fetch.nMsg.sec
WARNING: Exiting before consuming the expected number of messages: timeout (10000 ms) exceeded. You can use the --timeout option to increase the timeout.
2020-05-14 21:19:58:116, 2020-05-14 21:20:09:654, 9.5367, 0.8266, 100000, 8667.0133, 1589462398473, -1589462386935, -0.0000, -0.0001

参数说明:

–zookeeper 指定zookeeper的链接信息

–topic 指定topic的名称

–fetch-size 指定每次fetch的数据的大小

–messages 总共要消费的消息个数

测试结果说明:

start.time, end.time, data.consumed.in.MB, MB/sec, data.consumed.in.nMsg**, nMsg.sec**

2020-05-14 21:19:58:116, 2020-05-14 21:20:09:654, 9.5367, 0.8266, 100000, 8667.0133, 1589462398473, -1589462386935, -0.0000, -0.0001

开始测试时间,测试结束数据,共消费数据9.5368MB,吞吐量0.8266MB/s,共消费100000条,平均每秒消费8667.0133条

机器数量计算

Kafka机器数量(经验公式)=2*(峰值生产速度 * 副本数/100)+1
先拿到峰值生产速度,再根据设定的副本数,就能预估出需要部署Kafka的数量。
比如我们的峰值生产速度是50M/s。副本数为2。
Kafka机器数量=2*(50* *2/100)+ 1=3台

峰值生产速度:M/S

kafka分区数量计算(重点)

1)创建一个只有1个分区的topic
2)测试这个topic的producer吞吐量和consumer吞吐量。
3)假设他们的值分别是Tp和Tc,单位可以是MB/s。
4)然后假设总的目标吞吐量是Tt,那么分区数=Tt / min(Tp,Tc)
例如:producer吞吐量=20m/s;consumer吞吐量=50m/s,期望吞吐量100m/s;
分区数=100 / 20 =5分区

分区数一般设置为:3-10个

Flume

屏幕快照 2020-05-15 下午10.33.25

服务器hadoop102服务器hadoop103服务器hadoop104
Flume(采集日志)生产 Flume生产 Flume消费Flume

安装与初始化配置

[vanas@hadoop102 ~]$ cd /opt/software/
[vanas@hadoop102 software]$ tar -zxf /opt/software/apache-flume-1.9.0-bin.tar.gz -C /opt/module/
[vanas@hadoop102 software]$ cd ../module/
[vanas@hadoop102 module]$ mv /opt/module/apache-flume-1.9.0-bin /opt/module/flume
[vanas@hadoop102 lib]$ rm guava-11.0.2.jar 

[vanas@hadoop102 conf]$ mv flume-env.sh.template flume-env.sh
[vanas@hadoop102 conf]$ vi flume-env.sh
export JAVA_HOME=/opt/module/jdk1.8.0_212
拦截器

上传自定义拦截器jar包 到flum/lib

日志采集flume配置

正则 .*(0-所有) .+(1-所有)
parseAsFlumeEvent 把head去掉

a1.sinks.k1.channel agent 是扇形结构
bootstrap.servers作用 2 个是为了容错

[vanas@hadoop102 flume]$ mkdir jobs
[vanas@hadoop102 jobs]$ vim taildir_kafka.conf
#为各组件命名
a1.sources = r1
a1.channels = c1

#描述source
a1.sources.r1.type = TAILDIR
a1.sources.r1.filegroups = f1
a1.sources.r1.filegroups.f1 = /opt/module/applog/log/app.*
a1.sources.r1.batchSize=500 
a1.sources.r1.positionFile = /opt/module/flume/taildir_position.json
a1.sources.r1.interceptors = i1
a1.sources.r1.interceptors.i1.type = com.orange.lin.interceptor.ETLInterceptor$Builder
    
#描述channel
a1.channels.c1.type = org.apache.flume.channel.kafka.KafkaChannel
a1.channels.c1.kafka.bootstrap.servers = hadoop102:9092,hadoop103:9092
a1.channels.c1.kafka.topic = topic_log 
a1.channels.c1.parseAsFlumeEvent = false
    
#绑定source和channel以及sink和channel的关系
a1.sources.r1.channels = c1

nohup 免挂断

&退到后台

[vanas@hadoop102 flume]$ bin/flume-ng agent -n a1 -c conf/ -f jobs/taildir_kafka.conf -Dflume.root.logger=info,console
[vanas@hadoop103 kafka]$ bin/kafka-console-consumer.sh --bootstrap-server hadoop102:9092 --topic topic_log

xsync flume

群起脚本

[vanas@hadoop103 kafka]$ nohup /opt/module/flume/bin/flume-ng agent -n a1 -c /opt/module/flume/conf/ -f /opt/module/flume/jobs/taildir_kafka.conf -Dflume.root.logger=info,console >/opt/module/flume/log.txt 2>&1 &

[vanas@hadoop102 bin]$ vim f1.sh
#! /bin/bash

case $1 in
"start"){
        for i in hadoop102 hadoop103
        do
                echo " --------启动 $i 采集flume-------"
                ssh $i "nohup /opt/module/flume/bin/flume-ng agent -n a1 -c /opt/module/flume/conf/ -f /opt/module/flume/jobs/taildir_kafka.conf -Dflume.root.logger=info,console >/opt/module/flume/log.txt 2>&1 &"
        done
};;	
"stop"){
        for i in hadoop102 hadoop103
        do
                echo " --------停止 $i 采集flume-------"
                ssh $i "ps -ef | grep taildir_kafka.conf | grep -v grep |awk  '{print \$2}' | xargs -n1 kill -9 "
        done

};;
esac

[vanas@hadoop102 bin]$ chmod 777 f1.sh 
日志消费Flume配置
[vanas@hadoop104 jobs]$ vim kafka_hdfs.conf
## 组件
a1.sources=r1
a1.channels=c1
a1.sinks=k1

## source1
a1.sources.r1.type = org.apache.flume.source.kafka.KafkaSource
a1.sources.r1.batchSize = 5000
a1.sources.r1.batchDurationMillis = 2000
a1.sources.r1.kafka.bootstrap.servers = hadoop102:9092,hadoop103:9092,hadoop104:9092
a1.sources.r1.kafka.topics=topic_log


## channel1
a1.channels.c1.type = file
a1.channels.c1.checkpointDir = /opt/module/flume/checkpoint/behavior1
a1.channels.c1.dataDirs = /opt/module/flume/data/behavior1/
a1.channels.c1.maxFileSize = 2146435071
a1.channels.c1.capacity = 1000000
a1.channels.c1.keep-alive = 6


## sink1
a1.sinks.k1.type = hdfs
a1.sinks.k1.hdfs.path = /origin_data/gmall/log/topic_log/%Y-%m-%d
a1.sinks.k1.hdfs.filePrefix = log-
a1.sinks.k1.hdfs.round = false


a1.sinks.k1.hdfs.rollInterval = 10
a1.sinks.k1.hdfs.rollSize = 134217728
a1.sinks.k1.hdfs.rollCount = 0

## 控制输出文件是原生文件。
a1.sinks.k1.hdfs.fileType = CompressedStream
a1.sinks.k1.hdfs.codeC = lzop

## 拼装
a1.sources.r1.channels = c1
a1.sinks.k1.channel= c1

启动脚本

[vanas@hadoop102 bin]$ vim f2.sh

#! /bin/bash

case $1 in
"start"){
        for i in hadoop104
        do
                echo " --------启动 $i 采集flume-------"
                ssh $i "nohup /opt/module/flume/bin/flume-ng agent -n a1 -c /opt/module/flume/conf/ -f /opt/module/flume/jobs/kafka_hdfs.conf -Dflume.root.logger=info,console >/opt/module/flume/log.txt 2>&1 &"
        done
};;	
"stop"){
        for i in hadoop104
        do
                echo " --------停止 $i 采集flume-------"
                ssh $i "ps -ef | grep kafka_hdfs.conf | grep -v grep |awk  '{print \$2}' | xargs -n1 kill -9 "
        done

};;
esac


[vanas@hadoop102 bin]$ chmod 777 f2.sh 

启动时候注意

先把通道打通 再生成数据

f1.sh start
f2.sh start
log.sh

Flume项目经验

Flume组件-Source选型

(1)Taildir Source相比Exec Source、Spooling Directory Source的优势

TailDir Source:断点续传、多目录。Flume1.6以前需要自己自定义Source记录每次读取文件位置,实现断点续传。

Exec Source可以实时搜集数据,但是在Flume不运行或者Shell命令出错的情况下,数据将会丢失。

Spooling Directory Source监控目录,支持断点续传。但是不适合对实时追加日志的文件进行监听并同步

(2)batchSize大小如何设置?

答:Event 1K左右时,500-1000合适(默认为100)

Flume组件Channel选型
Kafka Channel

采用Kafka Channel,省去了Sink,提高了效率。KafkaChannel数据存储在Kafka里面,所以数据是存储在磁盘中。

注意在Flume1.7以前,Kafka Channel很少有人使用,因为发现parseAsFlumeEvent这个配置起不了作用。也就是无论parseAsFlumeEvent配置为true还是false,都会转为Flume Event。这样的话,造成的结果是,会始终都把Flume的headers中的信息混合着内容一起写入Kafka的消息中,这显然不是我所需要的,我只是需要把内容写入即可。

FileChannel和MemoryChannel区别

MemoryChannel传输数据速度更快,但因为数据保存在JVM的堆内存中,Agent进程挂掉会导致数据丢失,适用于对数据质量要求不高的需求。

FileChannel传输速度相对于Memory慢,但数据安全保障高,Agent进程挂掉也可以从失败中恢复数据。

选型:

金融类公司、对钱要求非常准确的公司通常会选择FileChannel

传输的是普通日志信息(京东内部一天丢100万-200万条,这是非常正常的),通常选择

MemoryChannel。

FileChannel的优化

通过配置dataDirs指向多个路径,每个路径对应不同的硬盘,增大Flume吞吐量。

官方说明如下:

Comma separated list of directories for storing log files. Using multiple directories on separate disks can improve file channel peformance

checkpointDir和backupCheckpointDir也尽量配置在不同硬盘对应的目录中,保证checkpoint坏掉后,可以快速使用backupCheckpointDir恢复数据

Flume组件Sink选型

Sink:HDFS Sink

(1)HDFS存入大量小文件,有什么影响?

**元数据层面:**每个小文件都有一份元数据,其中包括文件路径,文件名,所有者,所属组,权限,创建时间等,这些信息都保存在Namenode内存中。所以小文件过多,会占用Namenode服务器大量内存,影响Namenode性能和使用寿命

**计算层面:**默认情况下MR会对每个小文件启用一个Map任务计算,非常影响计算性能。同时也影响磁盘寻址时间。

(2)HDFS小文件处理

官方默认的这三个参数配置写入HDFS后会产生小文件,hdfs.rollInterval、hdfs.rollSize、hdfs.rollCount

基于以上hdfs.rollInterval=3600,hdfs.rollSize=134217728,hdfs.rollCount =0几个参数综合作用,效果如下:

(1)文件在达到128M时会滚动生成新文件

(2)文件创建超3600秒时会滚动生成新文件

Flume内存优化

问题描述:如果启动消费Flume抛出如下异常

ERROR hdfs.HDFSEventSink: process failed

java.lang.OutOfMemoryError: GC overhead limit exceeded

解决方案步骤:

(1)在hadoop102服务器的/opt/module/flume/conf/flume-env.sh文件中增加如下配置

export JAVA_OPTS="-Xms100m -Xmx2000m -Dcom.sun.management.jmxremote"

(2)同步配置到hadoop103、hadoop104服务器

[atguigu@hadoop102 conf]$ xsync flume-env.sh

3)Flume内存参数设置及优化

JVM heap一般设置为4G或更高

-Xmx与-Xms最好设置一致,减少内存抖动带来的性能影响,如果设置不一致容易导致频繁fullgc。

-Xms表示JVM Heap(堆内存)最小尺寸,初始分配;-Xmx 表示JVM Heap(堆内存)最大允许的尺寸,按需分配。如果不设置一致,容易在初始化时,由于内存不够,频繁触发fullgc。fullgc会暂停虚拟机的其他线程,等GC后开启,

其他小问题总结

时间脚本

-t 非root用户 强制生成终端

ntpd 自动同步网上时间 阿里云默认开启

​ disable 也关掉

kafka时间索引有存储

时间只能往后改不能往前改

zookeeper启动完再启动kafka

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值