Hadoop框架配置

HDFS 负责分布式存储,Yarn 负责集群资源调度,Hive 基于两者之上提供 SQL 查询接口。

前置准备

以下步骤需在三台节点上全部执行

配置主机名与节点映射

1
2
3
4
5
6
7
8
# 各节点分别设置主机名
hostnamectl set-hostname node1 # node2、node3 同理

# 三台节点均追加以下内容到 /etc/hosts
vim /etc/hosts
192.168.x.x node1
192.168.x.x node2
192.168.x.x node3

创建 hadoop 用户

1
2
3
# 三台节点均执行
useradd hadoop
passwd hadoop

配置 SSH 免密登录

1
2
3
4
5
6
7
# 在 node1 上生成密钥,一路回车
ssh-keygen -t rsa

# 将公钥分发到三台节点(含自身),执行后输入对应节点密码
ssh-copy-id hadoop@node1
ssh-copy-id hadoop@node2
ssh-copy-id hadoop@node3

HDFS

  • 镜像:centos_7_9_x64_20G_alibase
  • Java:JDK 1.8.0_361
  • Hadoop:Apache Hadoop 3.3.5
  • node1: NameNode, DataNode, SecondaryNameNode
  • node2,node3: DataNode

SecondaryNameNode 不是 NameNode 的热备,它的作用是定期合并 fsimage 与 edits 日志,减轻 NameNode 的内存压力;NameNode 宕机后它无法自动接管。

HDFS部署

配置HDFS集群,主要涉及以下文件(存于$HADOOP_HOME/etc/hadoop):

  • workers: 配置DataNode
  • hadoop-env.sh: 配置hadoop的相关环境变量
  • core-site.xml: Hadoop核心配置文件
  • hdfs-site.xml: HDFS核心配置文件

配置workers

1
2
3
4
5
6
7
# 进入目录
cd etc/hadoop
vim workers
# 填入
node1
node2
node3

配置hadoop-env.sh

1
2
3
4
5
vim hadoop-env.sh
export JAVA_HOME=/export/server/jdk
export HADOOP_HOME=/export/server/hadoop
export HADOOP_CONF_DIR=$HADOOP_HOME/etc/hadoop # hadoop配置文件目录
export HADOOP_LOG_DIR=$HADOOP_HOME/logs # hadoop运行日志

配置core-site.xml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<configuration>
<property>
<name>fs.defaultFS</name>
<!-- HDFS文件系统的网络通讯路径 -->
<value>hdfs://node1:8020</value>
<!-- 配置了node1为namenode,并且协议为hdfs://,端口为8020 -->
</property>

<property>
<name>io.file.buffer.size</name>
<!-- io操作文件缓冲区大小,单位:字节(131072字节=128KB) -->
<value>131072</value>
</property>
</configuration>

配置hdfs-site.xml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
<configuration>
<property>
<name>dfs.datanode.data.dir.perm</name>
<!-- hdfs默认创建的文件权限设置 -->
<value>700</value>
</property>
<property>
<name>dfs.namenode.name.dir</name>
<!-- NameNode元数据的存储路径 -->
<value>/data/nn</value>
</property>
<property>
<name>dfs.namenode.hosts</name>
<!-- hdfs白名单,允许哪些节点可以作为DataNode加入集群 -->
<value>node1,node2,node3</value>
</property>
<property>
<name>dfs.blocksize</name>
<!-- HDFS文件块大小,256MB -->
<value>268435456</value>
</property>
<property>
<name>dfs.namenode.handler.count</name>
<!-- NameNode处理的并发线程数 -->
<value>100</value>
</property>
<property>
<name>dfs.datanode.data.dir</name>
<!-- DataNode的数据存储目录 -->
<value>/data/dn</value>
</property>
</configuration>

创建数据存放目录

1
2
3
4
5
6
# node1
mkdir -p /data/nn
mkdir /data/dn

#node2, node3
mkdir -p /data/dn

分发Hadoop文件夹

1
2
3
4
5
6
7
# 在node1当中执行
cd /export/server
scp -r hadoop-3.3.5 node2:`pwd`/
scp -r hadoop-3.3.5 node3:`pwd`/

# 在node2,node3执行,为hadoop配置软连接
ln -s /export/server/hadoop-3.3.5 /export/server/hadoop

配置环境变量

1
2
3
4
5
6
7
vim /etc/profile

# 追加
export HADOOP_HOME=/export/server/hadoop
export PATH=$PATH:$HADOOP_HOME/bin:$HADOOP_HOME/sbin

source /etc/profile

授权为hadoop用户

1
2
3
# 以root的身份,在三台服务器上均执行
chown -R hadoop:hadoop /data
chown -R hadoop:hadoop /export

格式化整个文件系统

1
2
3
4
5
6
7
8
# 切换为hadoop
su - hadoop
hdfs namenode -format

# 启动hdfs集群,启动后可用公网ip:9870打开namenode的web界面
start-dfs.sh
# 关闭hdfs集群
stop-dfs.sh

HDFS的shell操作

进程启停管理

1
2
# 单独控制当前机器的进程启停(Hadoop 3.x 推荐)
hdfs --daemon (start|stop) (namenode|secondarynamenode|datanode)

文件系统操作命令

1
2
3
4
5
6
7
8
9
hdfs dfs -mkdir [-p] <path> ... #-p表示可以沿父目录创建
hdfs dfs -ls [-h] [-R] <path> #-h表示显示size,-R表示递归查看
hdfs dfs -put [-f] [-p] <localsrc> <dst> #-f强制覆盖,-p表示保留访问和修改时间,localsrc表示linux路径,dst为hdfs路径
hdfs dfs -cat <src> | more #文件过大可以用管道符配合more实现翻页
hdfs dfs -get [-f] [-p] <src> <localdst> #从hdfs下载到本地
hdfs dfs -cp [-f] <src> <dst> #都在hdfs下
hdfs dfs -appendToFile <localsrc> <dst> #本地内容向hdfs追加
hdfs dfs -mv <src> <dst> #移动和重命名
hdfs dfs -rm -r [-skipTrash]

Yarn

Yarn架构

类似于HDFS中NameNode和DataNode的主从架构,Yarn中为ResourceManager和NodeManager。ResourceManager 负责全局资源调度与分配,NodeManager 负责管理单节点资源,按 ResourceManager 的指令启动和监控 Container(Container 是资源的抽象单元,封装了 CPU/内存分配)。

除此之外还有两个辅助角色,为ProxyServer和JobHistoryServer。

ProxyServer用于保障对于Yarn的WebUI访问是安全的;

JobHistoryServer用于记录历史运行的程序信息以及日志,可以将不同容器的日志统一搜集。

Yarn部署

  • node1: ResourceManager,NodeManager,ProxyServer,JobHistoryServer
  • node2,node3: NodeManager
1
2
3
4
5
6
7
8
cd /export/server/hadoop/etc/hadoop/
vim mapred-env.sh
#JDK路径
export JAVA_HOME=/export/server/jdk
#设置进程内存1G
export HADOOP_JOB_HISTORYSERVER_HEAPSIZE=1000
#设置日志级别INFO
export HADOOP_MAPRED_ROOT_LOGGER=INFO,RFA
1
2
cd /export/server/hadoop/etc/hadoop/
vim mapred-site.xml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
<configuration>

<!-- MapReduce运行在YARN上 -->
<property>
<name>mapreduce.framework.name</name>
<value>yarn</value>
<description>MapReduce的运行框架设置为YARN</description>
</property>

<!-- JobHistory Server 通信地址 -->
<property>
<name>mapreduce.jobhistory.address</name>
<value>node1:10020</value>
<description>历史服务器通讯端口为 node1:10020</description>
</property>

<!-- JobHistory Server Web UI -->
<property>
<name>mapreduce.jobhistory.webapp.address</name>
<value>node1:19888</value>
<description>历史服务器web端口为 node1:19888</description>
</property>

<!-- 历史记录临时目录 -->
<property>
<name>mapreduce.jobhistory.intermediate-done-dir</name>
<value>/data/mr-history/tmp</value>
<description>历史信息在HDFS的记录临时路径</description>
</property>

<!-- 历史记录完成目录 -->
<property>
<name>mapreduce.jobhistory.done-dir</name>
<value>/data/mr-history/done</value>
<description>历史信息在HDFS的记录路径</description>
</property>

<!-- 环境变量配置 -->
<property>
<name>yarn.app.mapreduce.am.env</name>
<value>HADOOP_MAPRED_HOME=$HADOOP_HOME</value>
<description>MapReduce HOME 设置为 HADOOP_HOME</description>
</property>

<property>
<name>mapreduce.map.env</name>
<value>HADOOP_MAPRED_HOME=$HADOOP_HOME</value>
<description>MapReduce HOME 设置为 HADOOP_HOME</description>
</property>

<property>
<name>mapreduce.reduce.env</name>
<value>HADOOP_MAPRED_HOME=$HADOOP_HOME</value>
<description>MapReduce HOME 设置为 HADOOP_HOME</description>
</property>

</configuration>
1
2
3
4
5
6
7
8
9
10
11
12
vim yarn-env.sh
# 设置JDK路径的环境变量
export JAVA_HOME=/export/server/jdk

# 设置HADOOP_HOME的环境变量
export HADOOP_HOME=/export/server/hadoop

# 设置配置文件路径的环境变量
export HADOOP_CONF_DIR=$HADOOP_HOME/etc/hadoop

# 设置日志文件路径的环境变量
export HADOOP_LOG_DIR=$HADOOP_HOME/logs
1
vim yarn-site.xml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
<configuration>

<!-- ResourceManager所在节点 -->
<property>
<name>yarn.resourcemanager.hostname</name>
<value>node1</value>
<description>ResourceManager设置在node1节点</description>
</property>

<!-- NodeManager本地数据存储路径 -->
<property>
<name>yarn.nodemanager.local-dirs</name>
<value>/data/nm-local</value>
<description>NodeManager中间数据本地存储路径</description>
</property>

<!-- NodeManager日志本地存储路径 -->
<property>
<name>yarn.nodemanager.log-dirs</name>
<value>/data/nm-log</value>
<description>NodeManager数据日志本地存储路径</description>
</property>

<!-- 开启shuffle服务 -->
<property>
<name>yarn.nodemanager.aux-services</name>
<value>mapreduce_shuffle</value>
<description>为MapReduce程序开启Shuffle服务</description>
</property>

<!-- 日志服务器URL -->
<property>
<name>yarn.log.server.url</name>
<value>http://node1:19888/jobhistory/logs</value>
<description>历史服务器URL</description>
</property>

<!-- Web代理 -->
<property>
<name>yarn.web-proxy.address</name>
<value>node1:8089</value>
<description>代理服务器主机和端口</description>
</property>

<!-- 开启日志聚合 -->
<property>
<name>yarn.log-aggregation-enable</name>
<value>true</value>
<description>开启日志聚合</description>
</property>

<!-- 程序日志在HDFS的存储路径 -->
<property>
<name>yarn.nodemanager.remote-app-log-dir</name>
<value>/tmp/logs</value>
<description>程序日志HDFS的存储路径</description>
</property>

<!-- 调度器 -->
<property>
<name>yarn.resourcemanager.scheduler.class</name>
<value>org.apache.hadoop.yarn.server.resourcemanager.scheduler.fair.FairScheduler</value>
<description>选择公平调度器</description>
</property>

</configuration>
1
2
3
#分发到另外服务器
scp mapred-env.sh mapred-site.xml yarn-env.sh yarn-site.xml node2:$PWD
scp mapred-env.sh mapred-site.xml yarn-env.sh yarn-site.xml node3:$PWD

Yarn启停命令

1
2
3
4
5
6
7
8
9
# 一键启动Yarn集群,启动后可用公网ip:8088打开ResourceManager的web界面
start-yarn.sh
# 一键停止Yarn集群
stop-yarn.sh

# 启动JobHistoryServer,可用公网ip:19888访问历史日志
mapred --daemon start historyserver
# 停止JobHistoryServer
mapred --daemon stop historyserver
1
2
3
# 单独控制当前机器的进程启停
yarn --daemon (start|status|stop) (resourcemanager|nodemanager|proxyserver)
mapred --daemon (start|status|stop) historyserver

Hive

Hive架构

Hive的核心架构包括元数据管理(Metastore)、SQL驱动层(Driver,负责解析/编译/优化/执行)和用户接口(CLI/HiveServer2)。

Hive配置

只需要在node1当中部署Hive即可。元数据服务所需的关系型数据库可以在node1上部署MySQL或者云服务器上购买数据库服务。

配置完MySQL之后,需要进行Hadoop的代理用户配置:把下面的配置加到 core-site.xml 的 标签内
用 scp 把文件分发到集群其他节点,随后重启 HDFS 集群。

1
2
3
4
5
6
7
8
<property>
<name>hadoop.proxyuser.hadoop.hosts</name>
<value>*</value>
</property>
<property>
<name>hadoop.proxyuser.hadoop.groups</name>
<value>*</value>
</property>

配置完成后,则可以下载解压Hive以及配置MySQL驱动:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# 1. 切换到 hadoop 用户
su - hadoop

# 2. 下载 Hive 安装包(进入存放目录后执行)
wget http://archive.apache.org/dist/hive/hive-3.1.3/apache-hive-3.1.3-bin.tar.gz

# 3. 解压到 /export/server/
tar -zxvf apache-hive-3.1.3-bin.tar.gz -C /export/server/

# 4. 设置软连接
ln -s /export/server/apache-hive-3.1.3-bin /export/server/hive

# 5. 下载 MySQL 驱动包(5.1.x 对应 MySQL 5.x;若用 MySQL 8.x 需换 8.x 驱动,驱动类名也不同)
wget https://repo1.maven.org/maven2/mysql/mysql-connector-java/5.1.34/mysql-connector-java-5.1.34.jar

# 6. 将驱动包移入 Hive 的 lib 目录
mv mysql-connector-java-5.1.34.jar /export/server/hive/lib/

随后进行Hive的配置:

1
2
3
4
5
6
7
8
# 从模板复制(安装包已附带模板)
cp /export/server/hive/conf/hive-env.sh.template /export/server/hive/conf/hive-env.sh
vim /export/server/hive/conf/hive-env.sh

# 填入以下内容:
export HADOOP_HOME=/export/server/hadoop
export HIVE_CONF_DIR=/export/server/hive/conf
export HIVE_AUX_JARS_PATH=/export/server/hive/lib

配置 Metastore(hive-site.xml):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
<!-- 新建 /export/server/hive/conf/hive-site.xml,填入以下内容 -->
<configuration>
<!-- MySQL 连接地址 -->
<property>
<name>javax.jdo.option.ConnectionURL</name>
<value>jdbc:mysql://node1:3306/hive?createDatabaseIfNotExist=true&amp;useSSL=false&amp;useUnicode=true&amp;characterEncoding=UTF-8</value>
</property>

<!-- MySQL 驱动类 -->
<property>
<name>javax.jdo.option.ConnectionDriverName</name>
<value>com.mysql.jdbc.Driver</value>
</property>

<!-- MySQL 用户名 -->
<property>
<name>javax.jdo.option.ConnectionUserName</name>
<value>root</value>
</property>

<!-- MySQL 密码 -->
<property>
<name>javax.jdo.option.ConnectionPassword</name>
<value>123456</value>
</property>

<!-- HiveServer2 绑定的主机 -->
<property>
<name>hive.server2.thrift.bind.host</name>
<value>node1</value>
</property>

<!-- Metastore 服务地址 -->
<property>
<name>hive.metastore.uris</name>
<value>thrift://node1:9083</value>
</property>

<!-- 关闭 Metastore 事件通知鉴权 -->
<property>
<name>hive.metastore.event.db.notification.api.auth</name>
<value>false</value>
</property>
</configuration>

初始化元数据库:

1
2
-- 1. 登录 MySQL,新建 hive 数据库
CREATE DATABASE hive CHARSET UTF8;
1
2
3
4
# 2. 执行 Hive 元数据库初始化
cd /export/server/hive
bin/schematool -initSchema -dbType mysql -verbose
# 初始化成功后,会在 MySQL 的 hive 库中自动创建 74 张元数据管理表

启动Hive:

1
2
3
4
5
6
7
8
9
10
# 确保目录归属 hadoop 用户
mkdir /export/server/hive/logs

# 启动 Metastore(必须先启动!)
# 后台启动(推荐):
nohup bin/hive --service metastore >> logs/metastore.log 2>&1 &

# 启动客户端,二选一:
bin/hive # Hive Shell(可直接写SQL,学习用)
bin/hive --service hiveserver2 # ThriftServer(供外部客户端连接)

连接DataGrip

1
2
3
4
5
start-dfs.sh
start-yarn.sh
cd /export/server/hive
nohup bin/hive --service metastore >> logs/metastore.log 2>&1 &
nohup bin/hive --service hiveserver2 >> logs/hiveserver2.log 2>&1 &

启动完毕后,在DataGrip中连接Hive,端口默认为10000。

封面

封面