写在前面的话
这篇学习笔记依托于尚硅谷课程资源,详细记录了尚硅谷离线数仓6.0从搭建、采集到数仓的整套流程,并且按照自己的理解调整了某些章节的顺序,尤其在数仓建模部分增添了个人认为极其必要的注解,以期行文更具有逻辑连贯性。
大数据组件之间配合紧密,在搭建的过程中踩坑之处一一列出,希望能对大家起到帮助。
本文涉及全套资料请猛戳↓↓↓
尚硅谷电商离线数仓6.0教程
B站直达:https://www.bilibili.com/video/BV1UN411j79o
百度网盘:https://pan.baidu.com/s/19RyMUMTp2A210aLIOyfYvw?pwd=yyds 提取码:yyds
阿里云盘:https://www.alipan.com/s/MfGKMkCeQxt(教程配套资料请从百度网盘下载)
参考书目:
《数仓建模工具箱》
《The Data Warehouse Toolkit, 3rd Edition The Definitive Guide to Dimensional Modeling (Ralph Kimball, Margy Ross).》
第一篇 阿里云集群部署
第一章 集群资源规划
1.1 集群资源规划
在本章,我们将租用五台阿里云服务器实现高可用状态下的集群实战。如果资源足够(最少要64GB内存),也可以部署本地虚拟机。下面是集群资源规划。
1.2 阿里云服务器准备
下图购买了三台服务器,但实际上我们需要购买五台。推荐购买按量计费模式最便宜,你将无条件持有实例一小时,在一小时之后若阿里云计算资源紧张,则持有的实例有可能会被阿里云释放(笔者就曾经被释放过两台)。配置好的集群一旦被释放重新配置组件将极为费力,因此采用按量计费模式对于本文请尽快食用。
1.2.1 注册阿里云账户
阿里云网址为:https://cn.aliyun.com/,注册账号并登录。
1.2.2 购买ECS云服务器
1) 进入控制台
2)打开侧边栏,点击云服务器ECS
3)侧边栏点击实例,然后点击创建实例
4)选择计费方式、服务器区域
5)选定服务器配置
离线数仓项目推荐配置4核8GB+,最好是16GB内存。
6)选定服务器系统
7)选定磁盘类型及大小
8)网络和安全组配置
9)系统配置
10)分组设置,默认即可
11)确认订单
1.2.3 ECS配置及安全组修改
1)升级hadoop102配置
(1)停止实例
(2)更改实例规格
2)修改安全组策略
需将以下端口开放:
1.2.4 连接阿里云服务器
可以使用xshell实现对云服务器的连接,注意如下图填写公网IP:
1.2.5 修改服务器hosts文件
[root@hadoop001 ~]# vim /etc/hosts
127.0.0.1 localhost localhost
::1 localhost localhost.localdomain localhost6 localhost6.localdomain6
172.17.138.24 hadoop001 hadoop1
172.17.138.25 hadoop002 hadoop2
172.17.138.23 hadoop003 hadoop3
注意:这里每个人不一样,ip填写的是五台云主机的私有ip,做完后ping一下。,一定要保证能够ping通。
1.3 连接云服务器并创建用户
首先,将控制台中的五台云主机的IP地址维护在一个文档中以备查(这里可以使用switchhosts以便一键切换host文件),在云主机启动的情况下,就可以使用Xshell连接这几个主机了。
进入系统可以发现用户是root,在实际生产环境中root权限是过于危险的,因此必须创建自定义用户。
1.4 配置跳板机
之所以一定要配置跳板机是为了避免我们的服务器被攻击。黑客攻击我们服务器的方法主要是通过各种端口,因此我们不应当开放过多的端口。但是我们想要访问阿里云上的hadoop集群,服务器上的9870端口就必须开放。我们要使用mysql呢?端口3306要开放。Yarn8088也要开放;hiveserver2的10000端口也要开放——我们开放的端口越多,被攻击的风险就越大。
为了避免这种情况发生,我们设置一个跳板机。跳板机通过ssh服务访问阿里云。而ssh服务所需的22端口在阿里云上是开放的。
那么,我们只要能通过这个22端口来代理别的端口,就可以实现跳板机访问阿里云的其他服务了。
1.4.1 安装Proxy SwitchyOmega
在浏览器安装Proxy SwitchyOmega插件,安装后点击“选项”,如下所示。
1.4.2 创建并配置代理服务器
如图所示,创建一个名为“proxy”的代理服务器。
接下来按照下图所示配置代理服务器。
之后,在自动切换页面(auto switch)做如下配置。
最后点击左下角的应用选项,就可以了。
同样,如果我们使用正常的方式连接mysql的3306端口,由于3306端口在阿里云上并未开放,所以一定是连接不上的。但是我们只要使用ssh隧道的方式就可以了,如Navicat所示。
然后,我们再在navicat的常规页面中将正常的端口号和连接配好,就可以了,如下所示。
包括配置datagrip也是一样的,首先在general界面正确配置主机名和用户密码,如下所示。
然后在ssh/ssl页面进行类似配置,如下所示。
1.4.3 解决22端口攻击风险
实际上,22端口也有被攻击的风险,为了彻底解决这个风险,我们可以采取下面两种办法之一。
注意,先根据1.15.3配置完机器之间的免密登陆,再继续解决端口问题!
1.4.3.1 修改系统ssh配置文件
首先,我们可以在下面的文件中修改端口号,如下所示。
sudo vim /etc/ssh/sshd_config
进入之后如下所示,我们可以直接把端口号改成55(这里改成你想要设置的值),使攻击者猜不到我们的端口号是多少。
这样一来,我们在上面的ssh配置中所有的端口号都要是55才行。同理,在脚本中的ssh命令的位置我们的都要事先重新指定端口,否则默认ssh走的仍然是22的设置。
如果你对这种方式并不满意,那么可以考虑使用下一小节的办法。
1.4.3.2 使用Xshell工具自动生成秘钥对
我们仍然使用22端口。仍然打开上面的文件,翻到最后一行。
这个设置表示采用密码的授权方式访问,我们可以将这个参数改成no。这样任何用户都无法用密码的方式来访问我们的主机。
注意,先根据1.15.3配置完机器之间的免密登陆,再继续解决端口问题!
在这里,我们先不要立马将这个选项设置为no,等到下面我们将多台主机的免密登陆设置完之后再将这个参数修改为no,并不影响免密登陆。如果此时先将此参数设置为no,则后面的免密登陆设置将会是不成功的,还要再返回修改此参数。
如果你在这里先打算着手端口问题,那么请删除.ssh文件,并且根据1.15.3节配置完各个机器的免密登陆功能之后再继续从这里向下阅读。
并且我们向上翻找文件,可以发现公钥私钥访问主机的方式是默认允许的,如下所示。
首先,我们要使用xshell来生成我们的公钥和私钥。如下所示:
点击“新建用户密钥生成向导”,密钥类型为RSA,长度则为2048,如下所示。
点击“下一步”,设置一个我们能够记得住的密码,此密码是对密钥管理的密码,如下所示。
点击“完成”,就生成了公钥,如下所示。
我们可以将此公钥保存为文件,选择保存位置后选择“完成”。在下面的页面导出私钥。
选择导出位置之后,我们可以看到下面的页面:
这个密码就是上面我们设置的管理私钥的密码,之后点击关闭就可以了。这样,我们就可以在我们选定的存储位置找到保存好的公钥和私钥。我们接下来就要将公钥授权到阿里云中,即将公钥中的内容配置到家目录的ssh文件夹中去,如下所示。
我们打开上面的文件,我们只要向其中追加刚才复制的公钥就可以了。
保存退出之后,我们要重新启动一下sshd的服务。
sudo systemctl restart sshd
配置完之后,我们就可以在xshell中选择公钥的方式连接我们的主机,如下所示。
而密钥的密码就输出我们上面设置的密钥管理密码。
同样,使用datagrip连接主机的时候也要采用上面类似的方法,如下所示:
通信短语也是我们设置的私钥管理密码。
1.5 设置隧道机
我们要在五台云服务器中选择一台作为隧道机,比如,我们选择hadoop100作为隧道机,那我们我们在Xshell的属性中选择“隧道”并选择“添加”,如下所示。
在转换规则中选择socks4/5,并做如下配置,如下图所示。
最后,不要忘记在windows的hosts文件上增加阿里云hadoop100隧道机的IP地址,如下所示。
这样,通过12345端口就可以找到阿里云hadoop100了。
1.6 阿里云服务器相关问题
我们在阿里云的管理台可以看到每台主机的IP地址,如下所示。
需要注意的是,每次主机启动之后公网IP都会发生变化,因此要么云主机就不关机,要么就直接使用ip地址。如果采用不关机的策略(这样会比较费钱),那么五台主机的ip地址最好维护在一个文档中备查(stitchhosts)。
1.7 安装必备插件
在root权限下安装一些必备插件。
(1)安装epel-release
Extra Packages for Enterprise Linux是为“红帽系”的操作系统提供额外的软件包,适用于RHEL、CentOS和Scientific Linux。相当于是一个软件仓库,大多数rpm包在官方 repository 中是找不到的。
sudo yum install -y epel-release
(2)安装net-tool工具包
net-tool工具包包含ifconfig等命令
sudo yum install -y net-tools
(3)安装vim编辑器
yum install -y vim
(4)安装一些其他工具
yum install -y net-tools vim psmisc nc rsync lrzsz ntp libzstd openssl-static tree iotop git
1.8 配置云主机映射文件
打开每台云主机的/etc/hosts文件,将每台云主机的私网ip和主机名配置进去。
1.9 修改云主机机器名
进入/etc/hostname修改每台云主机机器名。
1.10 在每台云主机上创建普通用户
在生产环境中大概率是不会使用root用户进行操作的,一般都是普通用户权限,因此这里要创建普通用户。
useradd atguigu
passwd atguigu
1.11 配置/etc/sudoers文件
使用atguigu账号登陆的时候,在某时候我们又想要去使用一下root权限,这时我们就要使用sudo命令暂时提升权限。在使用此命令前,我们必须修改/etc/sudoers中的配置才可以使用
atguigu ALL=(ALL) NOPASSWD:ALL
1.12 在/opt下创建module和software目录
创建这两个目录的目的是方便下一步向目录中传入和安装JDK,software用于存放安装包module用于存放安装文件。而之所以要在opt下创建正是因为opt文件就是专门用来加载其他内容的。
1.13修改文件所属用户和所属组
之所以要修改文件所有者是因为上面两个文件都是由root用户创建的,我们后续要使用atguigu来对这两个文件进行操作,因此要修改这两个文件的所属用户和所属组。
chown atguigu:atguigu module software
上面的命令即将module和software文件夹的所属用户和所属组改为atguigu。
1.14 使用atguigu账户登陆每台云主机
1.15 编写分发脚本
为了多多台机器安装组件方便,我们要编写一份分发脚本。
1.15.1 scp和rsync
用rsync做文件的复制要比scp的速度快,rsync只对差异文件做更新。scp是把所有文件都复制过去。
rsync只有发送和拉取功能,而不能同时操作两个远端(即不能站在第三者的角度对主机和被分发机进行操作,rsync没有这种操作)
rsync -av $pdir/$fname $user@$host:$pdir/$fname
命令 选项参数 要拷贝的文件路径/名称 目的地用户@主机:目的地路径/名称
1.15.2 检查环境变量
使用$PATH命令检查云主机的环境变量,我们的目的是将脚本存放在环境变量支持的目录中,这样就可以实现处处调用脚本了。
由于bin目录并不存在,因此我们只要在各个云主机上创建就好了。
1.15.3 配置云主机间的免密登录
如果不配置免密登录,那么使用分发脚本发送文件就要每次输入密码。在每台机器上都要如下操作。需要注意的是,如果我们要使用免密登陆就必须在上面的配置中将用户授权设置为yes。
注意,请一定要配置完免密登陆之后再解决端口安全问题!
(1)在虚拟机上使用ssh-keygen -t rsa命令生成密钥对
ssh-keygen -t rsa
在这个环节,执行完命令后别忘了敲四次回车。
生成了的私钥保存在了/home/atguigu/.ssh/id_rsa,公钥则保存在.ssh/id_rsa.pub。这两个文件是隐藏文件,可以使用ll -a来查看列表。
在列表中,我们可以看到名为know_hosts的文件,进入之后我们可以发现存在着几条记录。这几条记录记录了不同虚拟机之间的通信记录,如果这些通信记录存在,下次就不必再输入密码了。
(2)公钥授权
ssh-copy-id 虚拟机名
授权的时候别忘记要率先对当前虚拟机自我授权,其次对集群中的其他虚拟机也要进行授权。
注意:
以上操作都要在.ssh目录中进行
到这里为止,配置完成免密登陆之后就可以继续解决端口安全问题!
1.15.4 编写脚本
#参数判空
if [ $# -lt 1 ]
then
echo "要分发的文件目录不能为空!"
exit
fi
for host in hadoop101 hadoop102 hadoop103 hadoop104
do
for file in $@
do
if [ -e $file ]
then
pdir=$(cd -P $(dirname $file);pwd)
fname=$(basename $file)
sudo ssh $host "mkdir -p $pdir"
sudo rsync -av $pdir/$fname $host:$pdir
else
echo "要发送的文件目录不存在!"
exit
fi
done
done
第二章 阿里云集群组件安装与配置
2.1 使用Xtfp5向云主机上传安装包并安装
2.2 配置JDK的环境变量
(1)自定义脚本
在/etc/profile.d/下创建以.sh结尾的脚本
可以看到,因为使用用户是atguigu,而profile.d文件的所属用户和所属组都是root,因此我们要使用sudo指令来获得root权限。
(2)在这个profile.d/my_env.sh文件中设置JAVA_HOME,令其等于javajdk的家目录。
export JAVA_HOME=/opt/module/jdk1.8.0_212
(3)设置PATH变量
export PATH=$PATH:$JAVA_HOME/bin
(4)重新加载profile.d文件
以上配置完成后,需要重新加载profile.d文件方可生效,只要断开Xshell重新连接虚拟机就可以了。
JDK安装成功之后,调用下面的命令可以看到这样的信息。
2.3 hadoop环境配置
2.3.1 配置hadoop环境变量
(1) 确定hadoop的家目录
当然还是在Xshell中新开窗口后用pwd得到家目录
(2)配置/etc/profile.d/my_env.sh文件
我们不仅要配置bin目录,而且又要配置sbin目录,因为上面已经提及sbin目录下有很多我们要未来使用的.sh脚本。前后仍然使用:来连接。
export HADOOP_HOME=/opt/module/hadoop-3.1.3
export PATH=$PATH:$HADOOP_HOME/bin:$HADOOP_HOME/sbin
2.3.2配置HDFS高可用(HA)
根据上面的集群规划,我们要在hadoop100和hadoop101上配置namenode的高可用。
(1)core-site.xml
<configuration>
<!-- 把多个NameNode的地址组装成一个集群mycluster -->
<property>
<name>fs.defaultFS</name>
<value>hdfs://mycluster:8020</value>
</property>
<!-- 指定hadoop数据的存储目录 -->
<property>
<name>hadoop.tmp.dir</name>
<value>/opt/module/hadoop/data</value>
</property>
<!-- 配置HDFS网页登录使用的静态用户为atguigu -->
<property>
<name>hadoop.http.staticuser.user</name>
<value>atguigu</value>
</property>
<!-- 配置该atguigu(superUser)允许通过代理访问的主机节点 -->
<property>
<name>hadoop.proxyuser.atguigu.hosts</name>
<value>*</value>
</property>
<!-- 配置该atguigu(superUser)允许通过代理用户所属组 -->
<property>
<name>hadoop.proxyuser.atguigu.groups</name>
<value>*</value>
</property>
<!-- 配置该atguigu(superUser)允许通过代理的用户-->
<property>
<name>hadoop.proxyuser.atguigu.users</name>
<value>*</value>
</property>
<!-- 指定zkfc要连接的zkServer地址 -->
<property>
<name>ha.zookeeper.quorum</name>
<value>hadoop102:2181,hadoop103:2181,hadoop104:2181</value>
</property>
<!-- NN连接JN重试次数,默认是10次 -->
<property>
<name>ipc.client.connect.max.retries</name>
<value>2000</value>
</property>
<!-- 重试时间间隔,默认1s -->
<property>
<name>ipc.client.connect.retry.interval</name>
<value>50000</value>
</property>
</configuration>
(2)hdfs-site.xml
<configuration>
<!-- NameNode数据存储目录 -->
<property>
<name>dfs.namenode.name.dir</name>
<value>file://${hadoop.tmp.dir}/name</value>
</property>
<!-- DataNode数据存储目录 -->
<property>
<name>dfs.datanode.data.dir</name>
<value>file://${hadoop.tmp.dir}/data</value>
</property>
<!-- JournalNode数据存储目录 -->
<property>
<name>dfs.journalnode.edits.dir</name>
<value>${hadoop.tmp.dir}/jn</value>
</property>
<!-- 完全分布式集群名称 -->
<property>
<name>dfs.nameservices</name>
<value>mycluster</value>
</property>
<!-- 集群中NameNode节点都有哪些 -->
<property>
<name>dfs.ha.namenodes.mycluster</name>
<value>nn1,nn2</value>
</property>
<!-- NameNode的RPC通信地址 -->
<property>
<name>dfs.namenode.rpc-address.mycluster.nn1</name>
<value>hadoop100:9820</value>
</property>
<property>
<name>dfs.namenode.rpc-address.mycluster.nn2</name>
<value>hadoop101:9820</value>
</property>
<!-- NameNode的Web通信地址 -->
<property>
<name>dfs.namenode.http-address.mycluster.nn1</name>
<value>hadoop100:9870</value>
</property>
<property>
<name>dfs.namenode.http-address.mycluster.nn2</name>
<value>hadoop101:9870</value>
</property>
<!-- 指定NameNode元数据在JournalNode上的存放位置 -->
<property>
<name>dfs.namenode.shared.edits.dir</name>
<value>qjournal://hadoop102:8485;hadoop103:8485;hadoop104:8485/mycluster</value>
</property>
<!-- 访问代理类:client用于确定哪个NameNode为Active -->
<property>
<name>dfs.client.failover.proxy.provider.mycluster</name>
<value>org.apache.hadoop.hdfs.server.namenode.ha.ConfiguredFailoverProxyProvider</value>
</property>
<!-- 配置隔离机制,即同一时刻只能有一台服务器对外响应 -->
<property>
<name>dfs.ha.fencing.methods</name>
<value>sshfence</value>
</property>
<!-- 使用隔离机制时需要ssh秘钥登录-->
<property>
<name>dfs.ha.fencing.ssh.private-key-files</name>
<value>/home/atguigu/.ssh/id_rsa</value>
</property>
<!-- 启用nn故障自动转移 -->
<property>
<name>dfs.ha.automatic-failover.enabled</name>
<value>true</value>
</property>
</configuration>
2.3.3 启动JournalNode服务
根据集群配置,在hadoop102、hadoop103、hadoop104上输入以下命令,启动服务。
hdfs --daemon start journalnode
有时,我们启动JN服务的时候可能会遇到下面的错误。
ERROR: Cannot set priority of journalnode process 20798
使用cat命令打开hadoop下logs中的.out文件,可以看到下面的提示:
Error: Could not find or load main class org.apache.hadoop.hdfs.qjournal.server.JournalNode
首先检查环境变量是否正确,如果环境变量配置正确,那么很有可能是hadoop安装出现了问题(比如使用同步脚本发生丢包),重新安装即可。
注意,请在atguigu账户下执行JN服务。
2.3.4 格式化集群并同步集群信息
如果我们在两台namenode上分别格式化那么将产生两个不同的集群ID。为了避免这种情况的发生,我们可以挑选一台进行格式化,并且之后将集群信息同步到其他的NN上即可。
在hadoop100的nn1上对其格式化。
hdfs namenode -format
我们在执行上述格式化命令的时候可能会遇到下面这样的问题。
2023-XX-XX 20:16:33,469 INFO client.QuorumJournalManager: Waited 34018 ms (timeout=60000 ms) for a response for hasSomeData. No responses yet.
等待格式化结束,会出现下面的报错(若未出现请忽略)。
2023-xx-xx 23:30:20,464 ERROR namenode.NameNode: Failed to start namenode. java.io.IOException: Timed out waiting for response from loggers at org.apache.hadoop.hdfs.qjournal.client.QuorumJournalManager.hasSomeData(QuorumJournalManager.java:278) at org.apache.hadoop.hdfs.server.common.Storage.confirmFormat(Storage.java:1142) at org.apache.hadoop.hdfs.server.namenode.FSImage.confirmFormat(FSImage.java:209) at org.apache.hadoop.hdfs.server.namenode.NameNode.format(NameNode.java:1198) at org.apache.hadoop.hdfs.server.namenode.NameNode.createNameNode(NameNode.java:1645) at org.apache.hadoop.hdfs.server.namenode.NameNode.main(NameNode.java:1755) 2023-xx-xx 23:30:20,465 INFO util.ExitUtil: Exiting with status 1: java.io.IOException: Timed out waiting for response from loggers
经过检查可以发现,使用ping命令可以ping通百度,但是无法ping同其他主机,这说明是主机间通讯出现问题。
如果出现了上面的错误,请检查各机器/etc/hosts目录中存放的ip地址是否是私网ip。如果其中错放了公网ip,就会出现上述问题。
如果一切正常,那么nn应当能够正确格式化,如下所示。
之后,根据集群配置需求,我们在hadoop100上启动nn。
hdfs --daemon start namenode
然后,在hadoop101上同步元数据信息。
hdfs namenode -bootstrapStandby
如果同步成功,应当出现下面的页面:
紧接着,在hadoop101上启动namenode。
hdfs --daemon start namenode
2.3.5将nn1设置为active、启动DataNode并查看集群状态
将hadoop100上的nn1设置为active。
hdfs haadmin -transitionToActive nn1
如果没有启动zk和zkfc服务,那么将会出现下面的提示:
我们不尝试强制active nn1,而是在下面的小节中启动zk和zkfc服务,实现NN的自动故障转移。
根据上面的集群配置需求,在102、103、104三台机器上启动DN。
hdfs --daemon start datanode
如果一切正常,我们应当可以在web页面(hadoop100:9870和hadoop101:9870)查看到当前集群的状态。
目前两者都是standby。
2.3.6 Hadoop-HA的自动故障转移
自动故障转移为HDFS部署增加了两个新组件:ZooKeeper和ZKFailoverController(ZKFC)进程,如图所示。ZooKeeper是维护少量协调数据,通知客户端这些数据的改变和监视客户端故障的高可用服务。
根据集群规划,我们要在102、103、104三台机器上部署并且启动zookeeper。在此之前,我们要先关闭所有HDFS服务。
stop-dfs.sh
紧接着,使用自定义脚本启动zk集群(2.4.2节),注意启动之后观察zk是否正确启动。
然后,再初始化HA在zookeeper中的状态。
hdfs zkfc -formatZK
这步操作要在nn结点进行,如果一切正常,那么将会出现下面的界面。
之后,我们可以启动HDFS了。
start-dfs.sh
稍等片刻等待集群正确启动之后,我们可以看到本来都是standby的两个nn其中有一个自动变为了active。
2.3.7 配置YARN-HA集群
集群配置需求:
配置yarn-site.xml文件:
<configuration>
<property>
<name>yarn.nodemanager.aux-services</name>
<value>mapreduce_shuffle</value>
</property>
<!-- 启用resourcemanager ha -->
<property>
<name>yarn.resourcemanager.ha.enabled</name>
<value>true</value>
</property>
<!-- 声明两台resourcemanager的地址 -->
<property>
<name>yarn.resourcemanager.cluster-id</name>
<value>cluster-yarn1</value>
</property>
<!--指定resourcemanager的逻辑列表-->
<property>
<name>yarn.resourcemanager.ha.rm-ids</name>
<value>rm1,rm2</value>
</property>
<!-- ========== rm1的配置 ========== -->
<!-- 指定rm1的主机名 -->
<property>
<name>yarn.resourcemanager.hostname.rm1</name>
<value>hadoop100</value>
</property>
<!-- 指定rm1的web端地址 -->
<property>
<name>yarn.resourcemanager.webapp.address.rm1</name>
<value>hadoop100:8088</value>
</property>
<!-- 指定rm1的内部通信地址 -->
<property>
<name>yarn.resourcemanager.address.rm1</name>
<value>hadoop100:8032</value>
</property>
<!-- 指定AM向rm1申请资源的地址 -->
<property>
<name>yarn.resourcemanager.scheduler.address.rm1</name>
<value>hadoop100:8030</value>
</property>
<!-- 指定供NM连接的地址 -->
<property>
<name>yarn.resourcemanager.resource-tracker.address.rm1</name>
<value>hadoop100:8031</value>
</property>
<!-- ========== rm2的配置 ========== -->
<!-- 指定rm2的主机名 -->
<property>
<name>yarn.resourcemanager.hostname.rm2</name>
<value>hadoop101</value>
</property>
<property>
<name>yarn.resourcemanager.webapp.address.rm2</name>
<value>hadoop101:8088</value>
</property>
<property>
<name>yarn.resourcemanager.address.rm2</name>
<value>hadoop101:8032</value>
</property>
<property>
<name>yarn.resourcemanager.scheduler.address.rm2</name>
<value>hadoop101:8030</value>
</property>
<property>
<name>yarn.resourcemanager.resource-tracker.address.rm2</name>
<value>hadoop101:8031</value>
</property>
<!-- 指定zookeeper集群的地址 -->
<property>
<name>yarn.resourcemanager.zk-address</name>
<value>hadoop102:2181,hadoop103:2181,hadoop104:2181</value>
</property>
<!-- 启用自动恢复 -->
<property>
<name>yarn.resourcemanager.recovery.enabled</name>
<value>true</value>
</property>
<!-- 指定resourcemanager的状态信息存储在zookeeper集群 -->
<property>
<name>yarn.resourcemanager.store.class</name> <value>org.apache.hadoop.yarn.server.resourcemanager.recovery.ZKRMStateStore</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.log-aggregation-enable</name>
<value>true</value>
</property>
<!-- 设置日志聚集服务器地址 -->
<property>
<name>yarn.log.server.url</name>
<value>http://hadoop100:19888/jobhistory/logs</value>
</property>
<!-- 设置日志保留时间为7天 -->
<property>
<name>yarn.log-aggregation.retain-seconds</name>
<value>604800</value>
</property>
</configuration>
在要运行rm的结点上启动yarn集群,如下所示。
start-yarn.sh
查看服务状态
yarn rmadmin -getServiceState rm1
yarn rmadmin -getServiceState rm2
在hadoop100:8088页面查看yarn状态:
2.3.8 Hadoop框架如何知道哪些结点应当运行DN和NM
在hadoop-3.1.3/etc/hadoop目录下有一个名为“workers”的文件,里面指明的主机就运行DN和nodemanager。因此,如果不正确填写此文件,则集群将无法正常启动。并且查找logs文件看不出任何端倪。
2.3.9 Hadoop集群群启脚本
#!/bin/bash
if [ $# -lt 1 ]
then
echo "No Args Input..."
exit ;
fi
case $1 in
"start")
echo " =================== 启动 hadoop集群 ==================="
echo " --------------- 启动 hdfs ---------------"
ssh hadoop102 "/opt/module/hadoop-3.1.3/sbin/start-dfs.sh"
echo " --------------- 启动 yarn ---------------"
ssh hadoop100 "/opt/module/hadoop-3.1.3/sbin/start-yarn.sh"
echo " --------------- 启动 historyserver ---------------"
ssh hadoop102 "/opt/module/hadoop-3.1.3/bin/mapred --daemon start historyserver"
;;
"stop")
echo " =================== 关闭 hadoop集群 ==================="
echo " --------------- 关闭 historyserver ---------------"
ssh hadoop102 "/opt/module/hadoop-3.1.3/bin/mapred --daemon stop historyserver"
echo " --------------- 关闭 yarn ---------------"
ssh hadoop100 "/opt/module/hadoop-3.1.3/sbin/stop-yarn.sh"
echo " --------------- 关闭 hdfs ---------------"
ssh hadoop102 "/opt/module/hadoop-3.1.3/sbin/stop-dfs.sh"
;;
*)
echo "Input Args Error..."
;;
esac
2.4 zookeeper安装与配置
2.4.1 分布式安装部署
1)集群规划
在hadoop102、hadoop103和hadoop104三个节点上部署Zookeeper。
2)解压安装
(1)解压Zookeeper安装包到/opt/module/目录下
[atguigu@hadoop102 software]$ tar -zxvf apache-zookeeper-3.5.7-bin.tar.gz -C /opt/module/
(2)修改/opt/module/apache-zookeeper-3.5.7-bin名称为zookeeper-3.5.7
[atguigu@hadoop102 module]$ mv apache-zookeeper-3.5.7-bin/ zookeeper
3)配置服务器编号
(1)在/opt/module/zookeeper-3.5.7/这个目录下创建zkData
[atguigu@hadoop102 zookeeper]$ mkdir zkData
(2)在/opt/module/zookeeper-3.5.7/zkData目录下创建一个myid的文件
[atguigu@hadoop102 zkData]$ vim myid
添加myid文件,注意一定要在linux里面创建,在notepad++里面很可能乱码
在文件中添加与server对应的编号:
3
4)配置zoo.cfg文件
(1)重命名/opt/module/zookeeper-3.5.7/conf这个目录下的zoo_sample.cfg为zoo.cfg
[atguigu@hadoop102 conf]$ mv zoo_sample.cfg zoo.cfg
(2)打开zoo.cfg文件
[atguigu@hadoop102 conf]$ vim zoo.cfg
修改数据存储路径配置
dataDir=/opt/module/zookeeper/zkData
增加如下配置
#######################cluster##########################
server.3=hadoop102:2888:3888
server.4=hadoop103:2888:3888
server.5=hadoop104:2888:3888
(3)同步/opt/module/zookeeper-3.5.7目录内容到hadoop103、hadoop104
[atguigu@hadoop102 module]$ xsync zookeeper/
(4)分别修改hadoop103、hadoop104上的myid文件中内容为4、5
(5)zoo.cfg配置参数解读
server.A=B:C:D。
A是一个数字,表示这个是第几号服务器;
集群模式下配置一个文件myid,这个文件在dataDir目录下,这个文件里面有一个数据就是A的值,Zookeeper启动时读取此文件,拿到里面的数据与zoo.cfg里面的配置信息比较从而判断到底是哪个server。
B是这个服务器的地址;
C是这个服务器Follower与集群中的Leader服务器交换信息的端口;
D是万一集群中的Leader服务器挂了,需要一个端口来重新进行选举,选出一个新的Leader,而这个端口就是用来执行选举时服务器相互通信的端口。
5)集群操作
(1)分别启动Zookeeper
[atguigu@hadoop102 zookeeper]$ bin/zkServer.sh start
[atguigu@hadoop103 zookeeper]$ bin/zkServer.sh start
[atguigu@hadoop104 zookeeper]$ bin/zkServer.sh start
(2)查看状态
[atguigu@hadoop102 zookeeper]# bin/zkServer.sh status
JMX enabled by default
Using config: /opt/module/zookeeper/bin/../conf/zoo.cfg
Mode: follower
[atguigu@hadoop103 zookeeper]# bin/zkServer.sh status
JMX enabled by default
Using config: /opt/module/zookeeper/bin/../conf/zoo.cfg
Mode: leader
[atguigu@hadoop104 zookeeper]# bin/zkServer.sh status
JMX enabled by default
Using config: /opt/module/zookeeper/bin/../conf/zoo.cfg
Mode: follower
2.4.2 ZK集群启动停止脚本
(1)在hadoop100的/home/atguigu/bin目录下创建脚本
[atguigu@hadoop100 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/bin/zkServer.sh start"
done
};;
"stop"){
for i in hadoop102 hadoop103 hadoop104
do
echo ---------- zookeeper $i 停止 ------------
ssh $i "/opt/module/zookeeper/bin/zkServer.sh stop"
done
};;
"status"){
for i in hadoop102 hadoop103 hadoop104
do
echo ---------- zookeeper $i 状态 ------------
ssh $i "/opt/module/zookeeper/bin/zkServer.sh status"
done
};;
esac
(2)增加脚本执行权限
[atguigu@hadoop102 bin]$ chmod 777 zk.sh
(3)Zookeeper集群启动脚本
[atguigu@hadoop102 module]$ zk.sh start
(4)Zookeeper集群停止脚本
[atguigu@hadoop102 module]$ zk.sh stop
2.5 kafka集群配置
2.5.1 集群部署
1)解压安装包
[atguigu@hadoop102 software]$ tar -zx3vf kafka_2.12-3.0.0.tgz -C /opt/module/
2)修改解压后的文件名称
[atguigu@hadoop102 module]$ mv kafka_2.12-3.0.0/ kafka
3)进入到/opt/module/kafka目录,修改配置文件
[atguigu@hadoop102 kafka]$ cd config/
[atguigu@hadoop102 config]$ vim server.properties
输入以下内容:
#broker的全局唯一编号,不能重复,只能是数字。
broker.id=0
#处理网络请求的线程数量
num.network.threads=3
#用来处理磁盘IO的线程数量
num.io.threads=8
#发送套接字的缓冲区大小
socket.send.buffer.bytes=102400
#接收套接字的缓冲区大小
socket.receive.buffer.bytes=102400
#请求套接字的缓冲区大小
socket.request.max.bytes=104857600
#kafka运行日志(数据)存放的路径,路径不需要提前创建,kafka自动帮你创建,可以配置多个磁盘路径,路径与路径之间可以用","分隔
log.dirs=/opt/module/kafka/datas
#topic在当前broker上的分区个数
num.partitions=1
#用来恢复和清理data下数据的线程数量
num.recovery.threads.per.data.dir=1
# 每个topic创建时的副本数,默认时1个副本
offsets.topic.replication.factor=1
#segment文件保留的最长时间,超时将被删除
log.retention.hours=168
#每个segment文件的大小,默认最大1G
log.segment.bytes=1073741824
# 检查过期数据的时间,默认5分钟检查一次是否数据过期
log.retention.check.interval.ms=300000
#配置连接Zookeeper集群地址(在zk根目录下创建/kafka,方便管理)
zookeeper.connect=hadoop102:2181,hadoop103:2181,hadoop104:2181/kafka
4)分发安装包
[atguigu@hadoop102 module]$ xsync kafka/
5)分别在hadoop103和hadoop104上修改配置文件/opt/module/kafka/config/server.properties中的broker.id=1、broker.id=2
注:broker.id不得重复,整个集群中唯一。
[atguigu@hadoop103 module]$ vim kafka/config/server.properties
修改:
# The id of the broker. This must be set to a unique integer for each broker.
broker.id=1
[atguigu@hadoop104 module]$ vim kafka/config/server.properties
修改:
# The id of the broker. This must be set to a unique integer for each broker.
broker.id=2
6)配置环境变量
(1)在/etc/profile.d/my_env.sh文件中增加kafka环境变量配置
[atguigu@hadoop102 module]$ sudo vim /etc/profile.d/my_env.sh
增加如下内容:
#KAFKA_HOME
export KAFKA_HOME=/opt/module/kafka
export PATH=$PATH:$KAFKA_HOME/bin
(2)刷新一下环境变量。
[atguigu@hadoop102 module]$ source /etc/profile
(3)分发环境变量文件到其他节点,并source。
[atguigu@hadoop102 module]$ sudo /home/atguigu/bin/xsync /etc/profile.d/my_env.sh
[atguigu@hadoop103 module]$ source /etc/profile
[atguigu@hadoop104 module]$ source /etc/profile
7)启动集群
(1)先启动Zookeeper集群,然后启动Kafka。
[atguigu@hadoop102 kafka]$ zk.sh start
(2)依次在hadoop102、hadoop103、hadoop104节点上启动Kafka。
[atguigu@hadoop102 kafka]$ bin/kafka-server-start.sh -daemon config/server.properties
[atguigu@hadoop103 kafka]$ bin/kafka-server-start.sh -daemon config/server.properties
[atguigu@hadoop104 kafka]$ bin/kafka-server-start.sh -daemon config/server.properties
注意:配置文件的路径要能够到server.properties。
8)关闭集群
[atguigu@hadoop102 kafka]$ bin/kafka-server-stop.sh
[atguigu@hadoop103 kafka]$ bin/kafka-server-stop.sh
[atguigu@hadoop104 kafka]$ bin/kafka-server-stop.sh
2.5.2 集群启停脚本
1)在/home/atguigu/bin目录下创建文件kf.sh脚本文件
[atguigu@hadoop100 bin]$ vim kf.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 "
done
};;
esac
2)添加执行权限
[atguigu@hadoop102 bin]$ chmod +x kf.sh
3)启动集群命令
[atguigu@hadoop102 ~]$ kf.sh start
4)停止集群命令
[atguigu@hadoop102 ~]$ kf.sh stop
注意:停止Kafka集群时,一定要等Kafka所有节点进程全部停止后再停止Zookeeper集群。因为Zookeeper集群当中记录着Kafka集群相关信息,Zookeeper集群一旦先停止,Kafka集群就没有办法再获取停止进程的信息,只能手动杀死Kafka进程了。
2.5 flume安装
按照采集通道规划,需在hadoop100,hadoop101、hadoop104三台节点分别部署一个Flume。可参照以下步骤先在hadoop100安装,然后再进行分发。
1)安装
(1)将apache-flume-1.9.0-bin.tar.gz上传到linux的/opt/software目录下
(2)解压apache-flume-1.9.0-bin.tar.gz到/opt/module/目录下
[atguigu@hadoop100 software]$ tar -zxf /opt/software/apache-flume-1.9.0-bin.tar.gz -C /opt/module/
(3)修改apache-flume-1.9.0-bin的名称为flume
[atguigu@hadoop100 module]$ mv /opt/module/apache-flume-1.9.0-bin /opt/module/flume
(4)将lib文件夹下的guava-11.0.2.jar删除以兼容Hadoop 3.1.3
[atguigu@hadoop100 module]$ rm /opt/module/flume/lib/guava-11.0.2.jar
注意:删除guava-11.0.2.jar的服务器节点,一定要配置hadoop环境变量。否则会报如下异常。
Caused by: java.lang.ClassNotFoundException: com.google.common.collect.Lists
at java.net.URLClassLoader.findClass(URLClassLoader.java:382)
at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:349)
at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
... 1 more
(5)修改conf目录下的log4j.properties配置文件,配置日志文件路径
[atguigu@hadoop100 conf]$ vim log4j.properties
flume.log.dir=/opt/module/flume/logs
2)分发Flume
[atguigu@hadoop102 ~]$ xsync /opt/module/flume/
第一篇完