Hadoop集群安装 3.2.3

1.前提准备

  • 安装前确保集群已经完成基础环境配置
  • 集群已经正常安装并运行ZooKeeper服务
  • 本次安装的Hadoop版本为:3.2.3,为了便于安装对安装文件做了部分修改,因此和官网直接下载的会存在不同。

2.集群规划

待安装Hadoop服务的集群有3个节点,分别为:ecs21,ecs22,ecs23,规划待安装的角色如下:

节点 角色
ecs21 NameNode,JournalNode,DFSZKFailoverController,DataNode,ResourceManager,NodeManager,JobHistoryServer
ecs22 NameNode,JournalNode,DFSZKFailoverController,DataNode,ResourceManager,NodeManager
ecs23 NameNode,JournalNode,DFSZKFailoverController,DataNode,ResourceManager,NodeManager

由于当前配置仅有三台服务器组成Hadoop高可用集群,因此是一个比较紧凑的集群,每个节点上都存在所有的角色,实际生产环境中管理节点和工作节点角色应尽量分离,管理节点在小型集群(几十台以内)中有3台即可, 大型集群配置5台管理节点。

上面这些角色中,属于管理或协调的角色有:NameNodeResourceManagerJournalNodeDFSZKFailoverController,属于具体执行的工作节点有:DataNodeNodeManager,另外JobHistoryServer用于收集日志使用。

通常情况下,若集群规模大于3台,则管理或协调的角色只需要配置3台即可,而工作节点的可以往后配置,这个时候其余的工作节点就只需要启动上面的两个角色即可。

3.安装配置

3.1.所有配置项梳理

为了方便后续的配置先提前整理全局用到的变量,后面直接使用即可,变量名和变量值按照:分割为yml格式:

# 变量名: 变量值
# 当前java安装目录 请按照基础环境中配置的方法确定OpenJDK所在的路径
java_home: /usr/lib/jvm/java-8-openjdk-amd64/
# 当前Hadoop环境的安装目录
hadoop_home: /opt/hadoop-3.2.3
# 全局数据目录, 数据目录下面会包含不同角色的子目录(datanode的数据目录可以配置多个, 使用逗号分割)
hadoop_data_dir: /data/hadoop
# 当前3个节点均已经安装ZooKeeper服务, 列表如下
zookeeper_hosts: ecs21:2181,ecs22:2181,ecs23:2181

然后NameNode的故障转移是基于角色JournalNode实现的,所以整个HDFS高可用集群会包含多个控制节点,通常会写作nn1,nn2,nn3这样的代号,每个节点其实是对应了多个主机,所以我们这里定义对应的主机如下:

nn1_host: ecs21
nn2_host: ecs22
nn3_host: ecs23

JournalNode的配置如下:

# journal node的端口默认为8485, 当前JournalNode节点列表为
journalnode_hosts: ecs21:8485;ecs22:8485;ecs23:8485

NameNode高可用的配置一样,YARN的资源管理角色ResourceManager同样需要配置高可用,集群会包括像rm1,rm2,rm3这样的代号,每个节点同样也是对应多个主机,所以对应的主机关系如下:

rm1_host: ecs21
rm2_host: ecs22
rm3_host: ecs23

最后我们还要启动JobHistoryServer,目前设置为ecs21:

history_server: ecs21

上面这些是我们提前准备好的配置,并不是真实的配置文件,接下来我们只需要将配置替换到配置文件中即可。

Hadoop集群的部署过程较为复杂,其实必须要修改的配置项并不多,所以还请配置时务必细心检查,以保证整个过程顺利无误。为便于表示变量全都写成{{ 变量名 }}的形式,替换时也请替换掉变量包裹的{{ }}符号。

3.2.解压安装包

我们首先在其中1个机器完成配置,等配置完成后再发送到其他的机器即可,当前选择在ecs21节点上配置,首先解压到指定安装目录:

# ecs21节点上执行
# 解压之后 安装目录为/opt/hadoop-3.2.3
tar zxf hadoop-3.2.3.tar.gz -C /opt/
# 进入配置文件所在目录
cd /opt/hadoop-3.2.3/etc/hadoop

接下来在配置文件目录下进行配置。

3.3.配置hadoop-env.sh

编辑hadoop-env.sh 配置文件,例如:vim hadoop-env.sh,修改替换下面的变量:

export JAVA_HOME={{ java_home }}
export HADOOP_HOME={{ hadoop_home }}

当前替换完成之后结果如下:

export JAVA_HOME=/usr/lib/jvm/java-8-openjdk-amd64/
export HADOOP_HOME=/opt/hadoop-3.2.3

然后其他的配置项保持默认即可。

3.4.配置core-site.xml

编辑core-site.xml配置文件,模板主要内容如下:

<configuration>
    <property>
        <name>fs.defaultFS</name>
        <value>hdfs://hdfscluster</value>
    </property>
    <property>
        <name>io.file.buffer.size</name>
        <value>131072</value>
    </property>
    <property>
        <name>hadoop.proxyuser.root.hosts</name>
        <value>*</value>
    </property>
    <property>
        <name>hadoop.proxyuser.root.groups</name>
        <value>*</value>
    </property>
    <!-- 替换zookeeper_hosts配置 -->
    <property>
        <name>ha.zookeeper.quorum</name>
        <value>{{ zookeeper_hosts }}</value>
    </property>
    <!-- 替换hadoop_data_dir配置 -->
    <property>
        <name>hadoop.tmp.dir</name>
        <value>{{ hadoop_data_dir }}/tmp</value>
    </property>
</configuration>

替换其中的ZooKeeper集群和数据目录,如下:

<configuration>
    <property>
        <name>fs.defaultFS</name>
        <value>hdfs://hdfscluster</value>
    </property>
    <property>
        <name>io.file.buffer.size</name>
        <value>131072</value>
    </property>
    <property>
        <name>hadoop.proxyuser.root.hosts</name>
        <value>*</value>
    </property>
    <property>
        <name>hadoop.proxyuser.root.groups</name>
        <value>*</value>
    </property>
    <!-- 替换zookeeper_hosts配置 -->
    <property>
        <name>ha.zookeeper.quorum</name>
        <value>ecs21:2181,ecs22:2181,ecs23:2181</value>
    </property>
    <!-- 替换hadoop_data_dir配置 -->
    <property>
        <name>hadoop.tmp.dir</name>
        <value>/data/hadoop/tmp</value>
    </property>
</configuration>

3.5.hdfs-site.xml

编辑hdfs-site.xml配置文件,模板内容如下:

<configuration>
    <property>
        <name>dfs.nameservices</name>
        <value>hdfscluster</value>
    </property>
    <!-- 高可用配置: nn1,nn2,nn3名字不需要修改 -->
    <property>
        <name>dfs.ha.namenodes.hdfscluster</name>
        <value>nn1,nn2,nn3</value>
    </property>
    <!-- 分别替换变量修改为对应的主机名 -->
    <property>
        <name>dfs.namenode.rpc-address.hdfscluster.nn1</name>
        <value>{{ nn1_host }}:8020</value>
    </property>
    <property>
        <name>dfs.namenode.rpc-address.hdfscluster.nn2</name>
        <value>{{ nn2_host }}:8020</value>
    </property>
    <property>
        <name>dfs.namenode.rpc-address.hdfscluster.nn3</name>
        <value>{{ nn3_host }}:8020</value>
    </property>
    <property>
        <name>dfs.namenode.http-address.hdfscluster.nn1</name>
        <value>{{ nn1_host }}:9870</value>
    </property>
    <property>
        <name>dfs.namenode.http-address.hdfscluster.nn2</name>
        <value>{{ nn2_host }}:9870</value>
    </property>
    <property>
        <name>dfs.namenode.http-address.hdfscluster.nn3</name>
        <value>{{ nn3_host }}:9870</value>
    </property>
    <!-- journalnode列表,以分号分隔,例如: ecs21:8485;ecs22:8485;ecs23:8485 -->
    <property>
        <name>dfs.namenode.shared.edits.dir</name>
        <value>qjournal://{{ journalnode_hosts }}/hdfscluster</value>
    </property>
    <property>
        <name>dfs.client.failover.proxy.provider.hdfscluster</name>
        <value>org.apache.hadoop.hdfs.server.namenode.ha.ConfiguredFailoverProxyProvider</value>
    </property>
    <property>
        <name>dfs.ha.fencing.methods</name>
        <value>shell(/bin/true)</value>
    </property>
    <!-- 替换hadoop_data_dir为实际的数据目录, 例如: /data/hadoop 注意原样替换 -->
    <property>
        <name>dfs.journalnode.edits.dir</name>
        <value>{{ hadoop_data_dir }}/dfs/journalnode</value>
    </property>
    <property>
        <name>dfs.namenode.name.dir</name>
        <value>file://{{ hadoop_data_dir }}/dfs/name</value>
    </property>
    <property>
        <name>dfs.datanode.data.dir</name>
        <value>file://{{ hadoop_data_dir }}/dfs/data</value>
    </property>
    <property>
        <name>dfs.blocksize</name>
        <value>268435456</value>
    </property>
    <property>
        <name>dfs.namenode.handler.count</name>
        <value>128</value>
    </property>
    <property>
        <name>dfs.datanode.handler.count</name>
        <value>128</value>
    </property>
    <property>
        <name>dfs.replication</name>
        <value>2</value>
    </property>
    <property>
        <name>dfs.ha.automatic-failover.enabled</name>
        <value>true</value>
    </property>
</configuration>

然后按照既定的变量替换配置,其余的保持默认即可,如下:

<configuration>
    <property>
        <name>dfs.nameservices</name>
        <value>hdfscluster</value>
    </property>
    <!-- 高可用配置: nn1,nn2,nn3名字不需要修改 -->
    <property>
        <name>dfs.ha.namenodes.hdfscluster</name>
        <value>nn1,nn2,nn3</value>
    </property>
    <!-- 分别替换变量修改为对应的主机名 -->
    <property>
        <name>dfs.namenode.rpc-address.hdfscluster.nn1</name>
        <value>ecs21:8020</value>
    </property>
    <property>
        <name>dfs.namenode.rpc-address.hdfscluster.nn2</name>
        <value>ecs22:8020</value>
    </property>
    <property>
        <name>dfs.namenode.rpc-address.hdfscluster.nn3</name>
        <value>ecs23:8020</value>
    </property>
    <property>
        <name>dfs.namenode.http-address.hdfscluster.nn1</name>
        <value>ecs21:9870</value>
    </property>
    <property>
        <name>dfs.namenode.http-address.hdfscluster.nn2</name>
        <value>ecs22:9870</value>
    </property>
    <property>
        <name>dfs.namenode.http-address.hdfscluster.nn3</name>
        <value>ecs23:9870</value>
    </property>
    <!-- journalnode列表,以分号分隔,例如: ecs21:8485;ecs22:8485;ecs23:8485 -->
    <property>
        <name>dfs.namenode.shared.edits.dir</name>
        <value>qjournal://ecs21:8485;ecs22:8485;ecs23:8485/hdfscluster</value>
    </property>
    <property>
        <name>dfs.client.failover.proxy.provider.hdfscluster</name>
        <value>org.apache.hadoop.hdfs.server.namenode.ha.ConfiguredFailoverProxyProvider</value>
    </property>
    <property>
        <name>dfs.ha.fencing.methods</name>
        <value>shell(/bin/true)</value>
    </property>
    <!-- 替换hadoop_data_dir为实际的数据目录, 例如: /data/hadoop 注意原样替换 -->
    <property>
        <name>dfs.journalnode.edits.dir</name>
        <value>/data/hadoop/dfs/journalnode</value>
    </property>
    <property>
        <name>dfs.namenode.name.dir</name>
        <value>file:///data/hadoop/dfs/name</value>
    </property>
    <property>
        <name>dfs.datanode.data.dir</name>
        <value>file:///data/hadoop/dfs/data</value>
    </property>
    <property>
        <name>dfs.blocksize</name>
        <value>268435456</value>
    </property>
    <property>
        <name>dfs.namenode.handler.count</name>
        <value>128</value>
    </property>
    <property>
        <name>dfs.datanode.handler.count</name>
        <value>128</value>
    </property>
    <property>
        <name>dfs.replication</name>
        <value>2</value>
    </property>
    <property>
        <name>dfs.ha.automatic-failover.enabled</name>
        <value>true</value>
    </property>
</configuration>

注意上面数据目录的配置中file://前缀不要去掉。

3.6.yarn-site.xml

编辑yarn-site.xml配置文件,模板内容如下:

<configuration>
    <property>
        <name>yarn.resourcemanager.ha.enabled</name>
        <value>true</value>
    </property>
    <property>
        <name>yarn.resourcemanager.cluster-id</name>
        <value>yarncluster</value>
    </property>
    <!-- 高可用配置: rm1,rm2,rm3名字不需要修改 -->
    <property>
        <name>yarn.resourcemanager.ha.rm-ids</name>
        <value>rm1,rm2,rm3</value>
    </property>
    <!-- 分别替换变量修改为对应的主机名 -->
    <property>
        <name>yarn.resourcemanager.hostname.rm1</name>
        <value>{{ rm1_host }}</value>
    </property>
    <property>
        <name>yarn.resourcemanager.hostname.rm2</name>
        <value>{{ rm2_host }}</value>
    </property>
    <property>
        <name>yarn.resourcemanager.hostname.rm3</name>
        <value>{{ rm3_host }}</value>
    </property>
    <property>
        <name>yarn.resourcemanager.address.rm1</name>
        <value>{{ rm1_host }}:8032</value>
    </property>
    <property>
        <name>yarn.resourcemanager.address.rm2</name>
        <value>{{ rm2_host }}:8032</value>
    </property>
    <property>
        <name>yarn.resourcemanager.address.rm3</name>
        <value>{{ rm3_host }}:8032</value>
    </property>
    <property>
        <name>yarn.resourcemanager.webapp.address.rm1</name>
        <value>{{ rm1_host }}:8088</value>
    </property>
    <property>
        <name>yarn.resourcemanager.webapp.address.rm2</name>
        <value>{{ rm2_host }}:8088</value>
    </property>
    <property>
        <name>yarn.resourcemanager.webapp.address.rm3</name>
        <value>{{ rm3_host }}:8088</value>
    </property>
    <property>
        <name>yarn.resourcemanager.recovery.enabled</name>
        <value>true</value>
    </property>
    <property>
        <name>yarn.resourcemanager.store.class</name>
        <value>org.apache.hadoop.yarn.server.resourcemanager.recovery.ZKRMStateStore</value>
    </property>
    <!-- 替换zookeeper_hosts为实际的ZooKeeper集群 -->
    <property>
        <name>hadoop.zk.address</name>
        <value>{{ zookeeper_hosts }}</value>
    </property>
    <property>
        <name>yarn.log-aggregation-enable</name>
        <value>true</value>
    </property>
    <property>
        <name>yarn.log-aggregation.retain-seconds</name>
        <value>2592000</value>
    </property>
    <property>
        <name>yarn.log-aggregation.retain-check-interval-seconds</name>
        <value>86400</value>
    </property>
    <property>
        <name>yarn.nodemanager.remote-app-log-dir</name>
        <value>/tmp/logs</value>
    </property>
    <!-- 替换history_server为实际的主机名 -->
    <property>
        <name>yarn.log.server.url</name>
        <value>http://{{ history_server }}:19888/jobhistory/logs</value>
    </property>
    <property>
        <name>yarn.nodemanager.aux-services</name>
        <value>mapreduce_shuffle</value>
    </property>
    <property>
        <name>yarn.nodemanager.aux-services.mapreduce_shuffle.class</name>
        <value>org.apache.hadoop.mapred.ShuffleHandler</value>
    </property>
    <property>
        <name>yarn.nodemanager.vmem-check-enabled</name>
        <value>false</value>
    </property>
    <property>
        <name>yarn.nodemanager.resource.memory-mb</name>
        <value>100000</value>
    </property>
    <property>
        <name>yarn.nodemanager.resource.cpu-vcores</name>
        <value>64</value>
    </property>
    <property>
        <name>yarn.scheduler.minimum-allocation-mb</name>
        <value>4096</value>
    </property>
    <property>
        <name>yarn.scheduler.maximum-allocation-mb</name>
        <value>32000</value>
    </property>
    <property>
        <name>yarn.scheduler.minimum-allocation-vcores</name>
        <value>1</value>
    </property>
    <property>
        <name>yarn.scheduler.maximum-allocation-vcores</name>
        <value>32</value>
    </property>
</configuration>

替换其中的变量,其余的保持默认即可,按照当前的变量替换完成如下:

<configuration>
    <property>
        <name>yarn.resourcemanager.ha.enabled</name>
        <value>true</value>
    </property>
    <property>
        <name>yarn.resourcemanager.cluster-id</name>
        <value>yarncluster</value>
    </property>
    <!-- 高可用配置: rm1,rm2,rm3名字不需要修改 -->
    <property>
        <name>yarn.resourcemanager.ha.rm-ids</name>
        <value>rm1,rm2,rm3</value>
    </property>
    <!-- 分别替换变量修改为对应的主机名 -->
    <property>
        <name>yarn.resourcemanager.hostname.rm1</name>
        <value>ecs21</value>
    </property>
    <property>
        <name>yarn.resourcemanager.hostname.rm2</name>
        <value>ecs22</value>
    </property>
    <property>
        <name>yarn.resourcemanager.hostname.rm3</name>
        <value>ecs23</value>
    </property>
    <property>
        <name>yarn.resourcemanager.address.rm1</name>
        <value>ecs21:8032</value>
    </property>
    <property>
        <name>yarn.resourcemanager.address.rm2</name>
        <value>ecs22:8032</value>
    </property>
    <property>
        <name>yarn.resourcemanager.address.rm3</name>
        <value>ecs23:8032</value>
    </property>
    <property>
        <name>yarn.resourcemanager.webapp.address.rm1</name>
        <value>ecs21:8088</value>
    </property>
    <property>
        <name>yarn.resourcemanager.webapp.address.rm2</name>
        <value>ecs22:8088</value>
    </property>
    <property>
        <name>yarn.resourcemanager.webapp.address.rm3</name>
        <value>ecs23:8088</value>
    </property>
    <property>
        <name>yarn.resourcemanager.recovery.enabled</name>
        <value>true</value>
    </property>
    <property>
        <name>yarn.resourcemanager.store.class</name>
        <value>org.apache.hadoop.yarn.server.resourcemanager.recovery.ZKRMStateStore</value>
    </property>
    <!-- 替换zookeeper_hosts为实际的ZooKeeper集群 -->
    <property>
        <name>hadoop.zk.address</name>
        <value>ecs21:2181,ecs22:2181,ecs23:2181</value>
    </property>
    <property>
        <name>yarn.log-aggregation-enable</name>
        <value>true</value>
    </property>
    <property>
        <name>yarn.log-aggregation.retain-seconds</name>
        <value>2592000</value>
    </property>
    <property>
        <name>yarn.log-aggregation.retain-check-interval-seconds</name>
        <value>86400</value>
    </property>
    <property>
        <name>yarn.nodemanager.remote-app-log-dir</name>
        <value>/tmp/logs</value>
    </property>
    <!-- 替换history_server为实际的主机名 -->
    <property>
        <name>yarn.log.server.url</name>
        <value>http://ecs21:19888/jobhistory/logs</value>
    </property>
    <property>
        <name>yarn.nodemanager.aux-services</name>
        <value>mapreduce_shuffle</value>
    </property>
    <property>
        <name>yarn.nodemanager.aux-services.mapreduce_shuffle.class</name>
        <value>org.apache.hadoop.mapred.ShuffleHandler</value>
    </property>
    <property>
        <name>yarn.nodemanager.vmem-check-enabled</name>
        <value>false</value>
    </property>
    <property>
        <name>yarn.nodemanager.resource.memory-mb</name>
        <value>100000</value>
    </property>
    <property>
        <name>yarn.nodemanager.resource.cpu-vcores</name>
        <value>64</value>
    </property>
    <property>
        <name>yarn.scheduler.minimum-allocation-mb</name>
        <value>4096</value>
    </property>
    <property>
        <name>yarn.scheduler.maximum-allocation-mb</name>
        <value>32000</value>
    </property>
    <property>
        <name>yarn.scheduler.minimum-allocation-vcores</name>
        <value>1</value>
    </property>
    <property>
        <name>yarn.scheduler.maximum-allocation-vcores</name>
        <value>32</value>
    </property>
</configuration>

上面需要替换的变量其实就那么几个,其余保持默认,保存并退出。

3.7.mapred-site.xml

编辑配置文件mapred-site.xml,模板内容如下:

<configuration>
    <!-- 替换history_server变量 -->
    <property>
        <name>mapreduce.jobhistory.address</name>
        <value>{{ history_server }}:10020</value>
    </property>
    <property>
        <name>mapreduce.jobhistory.webapp.address</name>
        <value>{{ history_server }}:19888</value>
    </property>
    <property>
        <name>mapreduce.framework.name</name>
        <value>yarn</value>
    </property>
    <property>
        <name>mapreduce.map.memory.mb</name>
        <value>8192</value>
    </property>
    <property>
        <name>mapreduce.reduce.memory.mb</name>
        <value>8192</value>
    </property>
    <property>
        <name>mapreduce.task.io.sort.mb</name>
        <value>1024</value>
    </property>
</configuration>

这里仅替换history_server变量即可,当前值是ecs21

<configuration>
    <!-- 替换history_server变量 -->
    <property>
        <name>mapreduce.jobhistory.address</name>
        <value>ecs21:10020</value>
    </property>
    <property>
        <name>mapreduce.jobhistory.webapp.address</name>
        <value>ecs21:19888</value>
    </property>
    <property>
        <name>mapreduce.framework.name</name>
        <value>yarn</value>
    </property>
    <property>
        <name>mapreduce.map.memory.mb</name>
        <value>8192</value>
    </property>
    <property>
        <name>mapreduce.reduce.memory.mb</name>
        <value>8192</value>
    </property>
    <property>
        <name>mapreduce.task.io.sort.mb</name>
        <value>1024</value>
    </property>
</configuration>

3.8.workers

Hadoop集群所有的节点需要保存到workers文件中,这样可以方便脚本启动,所以编辑workers配置文件,填入当前集群的主机列表,目前为:

ecs21
ecs22
ecs23

3.9.systemd服务文件

为了方便使用systemd服务管理Hadoop集群的进程,程序包提供了3个服务文件,分别是hdfs@.serviceyarn@.servicemapred-historyserver.service,模板分别如下:

  1. hdfs@.service
[Unit]
Description=hdfs
After=network.target

[Service]
User=root
Group=root
Type=forking
ExecStartPre=echo $PATH
ExecStart={{ hadoop_home }}/bin/hdfs --daemon start %i
ExecStop={{ hadoop_home }}/bin/hdfs --daemon stop %i
TimeoutSec=90s
RestartSec=10s
Restart=always
SuccessExitStatus=143
LimitNOFILE=infinity
LimitNPROC=infinity
LimitCORE=infinity

[Install]
WantedBy=multi-user.target
  1. yarn@.service
[Unit]
Description=yarn
After=network.target

[Service]
User=root
Group=root
Type=forking
ExecStartPre=echo $PATH
ExecStart={{ hadoop_home }}/bin/yarn --daemon start %i
ExecStop={{ hadoop_home }}/bin/yarn --daemon stop %i
TimeoutSec=90s
RestartSec=10s
Restart=always
SuccessExitStatus=143
LimitNOFILE=infinity
LimitNPROC=infinity
LimitCORE=infinity

[Install]
WantedBy=multi-user.target
  1. mapred-historyserver.service
[Unit]
Description=mapred history server
After=network.target

[Service]
User=root
Group=root
Type=forking
ExecStartPre=echo $PATH
ExecStart={{ hadoop_home }}/bin/mapred --daemon start historyserver
ExecStop={{ hadoop_home }}/bin/mapred --daemon stop historyserver
TimeoutSec=90s
RestartSec=10s
Restart=always
SuccessExitStatus=143
LimitNOFILE=infinity
LimitNPROC=infinity
LimitCORE=infinity

[Install]
WantedBy=multi-user.target

这些模板仅需要替换其中的hadoop_home为实际的安装目录即可,替换后的service文件如下:

  1. hdfs@.service
[Unit]
Description=hdfs
After=network.target

[Service]
User=root
Group=root
Type=forking
ExecStartPre=echo $PATH
ExecStart=/opt/hadoop-3.2.3/bin/hdfs --daemon start %i
ExecStop=/opt/hadoop-3.2.3/bin/hdfs --daemon stop %i
TimeoutSec=90s
RestartSec=10s
Restart=always
SuccessExitStatus=143
LimitNOFILE=infinity
LimitNPROC=infinity
LimitCORE=infinity

[Install]
WantedBy=multi-user.target
  1. yarn@.service
[Unit]
Description=yarn
After=network.target

[Service]
User=root
Group=root
Type=forking
ExecStartPre=echo $PATH
ExecStart=/opt/hadoop-3.2.3/bin/yarn --daemon start %i
ExecStop=/opt/hadoop-3.2.3/bin/yarn --daemon stop %i
TimeoutSec=90s
RestartSec=10s
Restart=always
SuccessExitStatus=143
LimitNOFILE=infinity
LimitNPROC=infinity
LimitCORE=infinity

[Install]
WantedBy=multi-user.target
  1. mapred-historyserver.service
[Unit]
Description=mapred history server
After=network.target

[Service]
User=root
Group=root
Type=forking
ExecStartPre=echo $PATH
ExecStart=/opt/hadoop-3.2.3/bin/mapred --daemon start historyserver
ExecStop=/opt/hadoop-3.2.3/bin/mapred --daemon stop historyserver
TimeoutSec=90s
RestartSec=10s
Restart=always
SuccessExitStatus=143
LimitNOFILE=infinity
LimitNPROC=infinity
LimitCORE=infinity

[Install]
WantedBy=multi-user.target

配置无误保存服务文件,其中hdfs@.service支持启动的角色是NameNodeDataNodeJournalNodeZKFCyarn@.service支持启动的角色有ResourceManagerNodeManagermapred-historyserver.service用来启动JobHistoryServer

4.分发安装文件到其他节点

当前已经在ecs21节点上完成了配置,需要分发安装文件到其他两个节点上,即ecs22ecs23,这里使用rsync工具进行分发,要注意前面的路径后切勿包含/,命令如下:

# 在ecs21节点上执行, 路径后切勿包含斜杠'/'
rsync -av /opt/hadoop-3.2.3 ecs22:/opt
rsync -av /opt/hadoop-3.2.3 ecs23:/opt

5.启动服务

5.1.配置环境变量

为了方便执行命令,所有节点均应该添加环境变量,编辑环境变量配置 /etc/profile,写入内容如下:

# HADOOP PATH
export HADOOP_HOME=/opt/hadoop-3.2.3
export PATH=$PATH:$HADOOP_HOME/bin
export PATH=$PATH:$HADOOP_HOME/sbin

上面的环境变量所有节点都需要配置,配置后加载生效:

source /etc/profile

5.2.NameNode和高可用集群初始化

所有管理节点先启动JournalNode服务,也就是nn1,nn2,nn3对应的节点:

# ecs21,ecs22,ecs23均需要执行一次
hdfs --daemon start journalnode
# 确认JournalNode进程是否存在
jps

确认没问题后,在1个管理节点上执行操作,当前在ecs21上执行如下操作:

# 仅在ecs21上执行命令
# 初始化ZooKeeper故障转移目录
hdfs zkfc -formatZK
# 初始化NameNode
hdfs namenode -format
# 启动namenode服务
hdfs --daemon start namenode

启动完成之后,在ecs21上执行jps确认NameNode进程正常存在。

然后其余控制节点也就是另外两台ecs22,ecs23需要分别执行下面的命令同步NameNode元数据:

# ecs22,ecs23 依次执行1次
hdfs namenode -bootstrapStandby

上面的几步至关重要,请严格按照说明执行。

5.3.启动集群

在任意1个节点执行命令启动集群:

start-all.sh
# 在ecs21单独启动history server
mapred --daemon start historyserver

等待集群启动完成之后,可以在每个机器依次执行jps查看进程状态,当前的状态依次如下:

ecs21:

image-20220727153026517

ecs22:

image-20220727153055637

ecs23:

image-20220727153114074

然后通过任意一个节点可以查看NameNode的运行状态:

hdfs haadmin -getAllServiceState

image-20220727153253441

可以看到此时ecs21是active状态,其余的都是standby状态。

查看YARN高可用集群ResourceManager的状态:

yarn rmadmin -getAllServiceState

image-20220727154340846

同样也可以看到此时ecs21是active状态,其余的都是standby的状态。

如果停止整个集群可以执行stop-all.sh

5.4.页面访问验证

可以访问http://ecs21:9870http://ecs22:9870http://ecs23:9870, 来查看HDFS的状态:

如果本地没有配置hosts也可以直接使用IP地址访问,和上面的命令结果一样,需保证有1个节点处在active状态, 其他管理节点均处在standby状态即可

image-20220727153804684

查看YARN的页面可以访问http://ecs21:8088查看yarn状态,注意这里只能访问active状态的页面:

image-20220727154454694

可以看到当前集群总的内存和虚拟CPU资源,取决于具体yarn-site.xml中的配置。

5.5.使用systemd接管角色

为了保证服务的稳定性,实现开机自启动以及进程挂掉自动重启的功能,可以使用systemd的方式接管Hadoop集群的角色,由于我们上面都完成了具体service文件的修改,只需要将service服务文件安装到系统即可,所有节点执行命令如下:

# ecs21,ecs22,ecs23分别安装服务
# 进入配置文件所在目录 
cd /opt/hadoop-3.2.3/etc/hadoop
# 安装service服务
cp *.service /usr/lib/systemd/system

然后停止掉原来启动的集群,在任意一个管理节点执行:

# ecs21上停止集群
stop-all.sh

然后停止掉JobHistoryServer进程,当前在ecs21节点上:

mapred --daemon stop historyserver

然后在所有节点上启动对应角色的服务,由于当前ecs21,ecs22,ecs23除了JobHistoryServer外角色都一样,那么就都执行一样的命令启动全部角色即可:

# ecs21,ecs22,ecs23均执行下面的命令
# 启动NameNode
systemctl start hdfs@namenode
# 启动DataNode
systemctl start hdfs@datanode
# 启动DFSZKFailoverController
systemctl start hdfs@zkfc
# 启动JournalNode
systemctl start hdfs@journalnode

# 启动YARN ResourceManager
systemctl start yarn@resourcemanager
# 启动YARN NodeManager
systemctl start yarn@nodemanager

然后查看服务状态:

# 查看NameNode状态
systemctl status hdfs@namenode
# 查看DataNode启动状态
systemctl status hdfs@datanode
# 查看DFSZKFailoverController
systemctl status hdfs@zkfc
# 查看JournalNode
systemctl status hdfs@journalnode

# 查看YARN ResourceManager
systemctl status yarn@resourcemanager
# 查看YARN NodeManager
systemctl status yarn@nodemanager

在实际的集群中,可能是分管理节点和工作节点的,那么就只需要启动当前节点所需的角色即可。

然后在ecs21上面启动JobHistoryServer

systemctl start mapred-historyserver.service
# 查看运行状态
systemctl status mapred-historyserver.service

然后为服务设置开机自动启动,当前在ecs21,ecs22,ecs23上分别设置如下:

# ecs21,ecs22,ecs23都需要执行一遍
systemctl enable hdfs@namenode
systemctl enable hdfs@datanode
systemctl enable hdfs@zkfc
systemctl enable hdfs@journalnode

systemctl enable yarn@resourcemanager
systemctl enable yarn@nodemanager

然后在ecs21上开启JobHistoryServer自动启动:

systemctl enable mapred-historyserver.service

这样Hadoop集群中的角色服务就能随服务器的开机实现自动启动了。