完全分布式就是把Hadoop核心组件分开部署到不同的服务器节点上运行。
通常,建议HDFS和YARN以单独的用户身份运行。在大多数安装中,HDFS进程以“hdfs”执行。YARN通常使用“yarn”帐户。
hadoopHA集群的工作机制如下图:
Hadoop HA集群总体上可以分为三部分:NameNode集群、JournalNode集群和Zookeeper集群。NameNode在某一时刻只有一个处于活跃状态,其他的都处于standby状态;JournalNode负责把edits文件传到standby的NameNode上;Zookeeper负责监控NameNode宕机情况,ZKFC(ZookeeperFailoverController)是专门监控NameNode健康的。
为了同步NameNode的元数据一致,有专门的JournalNode来同步元数据文件,活跃的NameNode的edits文件会写入journalnode集群,其他standby的结点会去读取journalnode上的edits文件,以此来同步自身的元数据。
详细过程如下:
1、ZKFC的HealthyMonitor是监控NameNode的进程,是专门监控NameNode将康情况的进程。
2、HealthyMonitor会定时向ZKFC进程报告NameNode情况。
3、当HealthyMonitor出现汇报了NameNode,ZKFC就会向AcitveStandbyEloctor报告。
4、AcitveStandbyEloctor接到NameNode宕机报告就会通知zk集群选举出新的NameNode。
5、zk集群经过内部选举,返回一个standby的NameNode给AcitveStandbyEloctor。
6、AcitveStandbyEloctor想ZKFC报告选举结果。
7、ZKFC为了防止是网络原因导致NameNode假死,就会结束NameNode进程。
8、zk集群就会通知另一个ZKFC要求它修改它监控的NameNode的进程为活跃节点。
在Hadoop 1.x的时候,NameNode存在单点故障问题。如果NameNode进程或者所在的机器有故障,会导致整个集群不可用,直到NameNode进程重启或者所在的机器恢复。在hadoop 2.x之后,增加了NameNode的HA机制。即在一个HDFS集群中运行两个NameNode节点,一个是Active状态的,一个是Standby状态的。当Active状态的NameNode挂掉后,Standby状态的NameNode会切换成Active状态。
NameNode的HA架构如上图
涉及到几个主要角色如下:
Active NameNode: 与Standby NameNode形成互备,只有处于Active状态的NameNode节点才能对外提供读写服务。
Standby NameNode: 承接原来SecondaryNameNode的checkpoint功能。Standby NameNode从JN拉取edit log,合并到自己的fsimage上。在Active NameNode故障时,Standby会切换成Active状态。
JournalNode: 必须奇数个节点(3,5,7…),至少3个节点。当有N个JN时,可以允许(N-1)/2个NameNode发生故障。Active NameNode发送edit log到JN的绝大部分节点上。
ZKFailoverController: ZKFC作为独立的进程运行,对NameNode的主备切换进行总体控制。每个运行NameNode的机器上,都需要同时运行一个ZKFC。ZKFC定期监测它本机的NameNode的健康状态,会与Zookeeper之间维护一个session,当本机的NameNode是Active状态时,会把某个znode“加锁”(创建znode)。如果session过期,这个znode会被删除。当其他ZKFC看到这个znode不存在,会去请求“加锁”(创建znode),如果成功“加锁”,也就是所谓的赢得了选举(won the election),它所在机器上的NameNode成为了Active状态。当然,NameNode也支持不依赖Zookeeper的手动主备切换。
DataNode: 同时向Active NameNode和Standby NameNode上报数据块位置信息和心跳包。
Zookeeper: ZKFC和Zookeeper之间维护了一个session,如果NameNode挂掉了,会使session失效,进而导致Zookeeper上保存的lock znode被删除,而ZKFC就是通过这个znode来进行Active NameNode选举。
图中涉及到的角色介绍
搭建分为四个阶段,每一个是环境准备,第二个是Zookeeper集群的搭建,第三是Hadoop集群的搭建,第四是Spark集群的搭建。
软件包下载:
链接: https://pan.baidu.com/s/1WS10UlQ6sN_W5ZX5k1cYMA 提取码: 854q
这里将使用六台服务器进行搭建。分别命名spark01、spark02、spark03、spark04、spark05、spark06。
机器数为6台,但因为分布式算法的需要,集群通常部署在奇数台服务器上,所有主机共用上述6台机器,如下角色划分
1、Zookeeper集群分配三台。
2、Hadoop分配需要分开说:
2.1、HDFS:两个主节点,三个从节点,5台。
2.2、JN集群:三台
2.3、Yarn集群:两个主节点,三个从节点,5台。
3、Spark集群分配三台。
将以上各个集群的节点合并,具体分配如下:
机器名 | IP | 节点应用 |
---|---|---|
spark01 | 192.168.234.21 | Zookeeper、NameNode(active)、ResourceManager(active) |
spark02 | 192.168.234.22 | Zookeeper、NameNode(standby) |
spark03 | 192.168.234.23 | Zookeeper、ResourceManager(standby) |
spark04 | 192.168.234.24 | JournalNode、DataNode、NodeManager、Spark |
spark05 | 192.168.234.25 | JournalNode、DataNode、NodeManager、Spark |
spark06 | 192.168.234.26 | JournalNode、DataNode、NodeManager、Spark |
服务器设置
每台服务器都要进行如下的配置。
1、关闭防火墙与selinux
systemctl stop firewalld
systemctl disable firewalld
sed -i '/SELINUX/s/enforcing/disabled/' /etc/selinux/config
setenforce 0
2、配置主机名
hostnamectl set-hostname xxx
配置hosts
vim /etc/hosts # 填入以下内容
127.0.0.1 localhost
::1 localhost
192.168.234.21 spark01
192.168.234.22 spark02
192.168.234.23 spark03
192.168.234.24 spark04
192.168.234.25 spark05
192.168.234.26 spark06
配置好此文件之后可以通过远程命令将配置好的hosts文件scp到其他5台节点上,执行命令如下:
scp /etc/hosts spark02: /etc/hosts
scp /etc/hosts spark03: /etc/hosts
scp /etc/hosts spark04: /etc/hosts
scp /etc/hosts spark05: /etc/hosts
scp /etc/hosts spark06: /etc/hosts
配置免密登录
集群中所有主机都要互相进行免密登录,包括自己和自己。
生成密钥:
ssh-keygen
发送公钥:
ssh-copy-id root@spark01
此时在远程主机的/root/.ssh/authorized_keys文件中保存了公钥,在known_hosts中保存了已知主机信息,当再次访问的时候就不需要输入密码了。
通过以下命令远程连接,检验是否可以不需密码连接:
ssh spark01
记得免密登录一定要给本机发送。
此次集群数量,互相发送免密登录的次数为36次。
注意注意注意:做完密钥登陆后,一定要每台主机ssh root@来登陆一遍,把该输入的yes都输入完毕,保证ssh可以直接连接上,不在需要交互,否则后续hadoop脚本启服务时会出现问
1、将jdk安装包上传、解压安装包,并更名,命令如下:
tar -zxvf jdk-8u65-linux-x64.tar.gz
mv jdk1.8.0_65 jdk1.8
2、修改/etc/profile, 在文件行尾加入以下内容后保存退出。
JAVA_HOME=/home/software/jdk1.8/
PATH=$PATH:$JAVA_HOME/bin
export JAVA_HOME PATH
1、上传解压scala-2.11.0.tgz,并更名,命令如下:
tar -zxvf scala-2.11.0.tgz
mv scala-2.11.0 scala2.11
2、修改/etc/profile,配置如下:
注:上图将Hadoop的环境变量也一起配置了,下面也有Hadoop的环境变量配置。
3、重新加载profile使配置生效:
source /etc/profile
ps:java、python、scala介绍
下面只是说说spark研发团队为什么选择scala,不是对比语言好坏。
第一:java与scala
1、当涉及到大数据Spark项目场景时,Java就不太适合,与Python和Scala相比,Java太冗长了,一行scala可能需要10行java代码。
2、当大数据项目,Scala支持Scala-shell,这样可以更容易地进行原型设计,并帮助初学者轻松学习Spark,而无需全面的开发周期。但是Java不支持交互式的shell功能。
第二:Python与Scala
虽然两者都具有简洁的语法,两者都是面向对象加功能,两者都有活跃的社区。
1、Python通常比Scala慢,Scala会提供更好的性能。
2、Scala是static typed. 错误在编译阶段就抛出,它使在大型项目中开发过程更容易。
3、Scala基于JVM,因为Spark是基于Hadoop的文件系统HDFS的。 Python与Hadoop服务交互非常糟糕,因此开发人员必须使用第三方库(如hadoopy)。 Scala通过Java中的Hadoop API来与Hadoop进行交互。 这就是为什么在Scala中编写本机Hadoop应用程序非常简单。
总之:选择哪种语言,要看作者的个人想法着重点,当然想“玩”spark,python也是非常好的。
Spark专注于数据的"transformation"和"mapping"的概念,这非常适合于完美支持像scala这样的概念的功能编程语言。 另外scala在JVM上运行,这使得更容易集成hadoop、YARN等框架。
View Code
可以通过ZooKKeeper完成Hadoop NameNode的监控,发生故障时做到自动切换,从而达到高可用
参见:Zookeeper集群的搭建
部署在spark01、spark02、spark03上即可
此示例以spark01节点服务器为示例。
直接解压Hadoop压缩包即可。
以下配置文件均在hadoop-2.7.1/etc/hadoop目录下。
hadoop-env.sh
编辑hadoop-env.sh文件,命令如下:
cd hadoop-2.10.1/
vim etc/hadoop/hadoop-env.sh
此文件配置两项:jdk安装所在目录、hadoop配置文件所在目录。
直接编辑core-site.xml文件,命令如下:
vim etc/hadoop/core-site.xml
此文件配置项内容如下:
直接编辑hdfs-site.xml文件,命令如下:
vim etc/hadoop/hdfs-site.xml
配置内容如下:
需要复制mapred-site.xml.template更名为mapred-site.xml然后配置,命令如下:
cp etc/hadoop/mapred-site.xml.template etc/hadoop/mapred-site.xml
vim etc/hadoop/mapred-site.xml
配置内容如下:
直接编辑yarn-site.xml文件,命令如下:
vim etc/hadoop/yarn-site.xml
配置内容如下:
补充:
1、yarn监控nodemanager的运行状况
Hadoop提供了一种机制,管理员可以通过该机制定期运行管理员提供的脚本以确定节点是否健康。
管理员可以通过在脚本中执行对其选择的任何检查来确定节点是否处于正常状态。如果脚本检测到节点处于不健康状态,则必须以字符串ERROR开头的标准输出行。NodeManager定期生成脚本并检查其输出。如果脚本的输出包含字符串ERROR,如上所述,节点的状态将报告为运行状况不佳并且ResourceManager将节点列入黑名单。不会为此节点分配其他任务。但是,NodeManager继续运行脚本,因此如果节点再次变得健康,它将自动从ResourceManager上的黑名单节点中删除。如果节点不健康,则可以在ResourceManager Web界面中为管理员提供节点的运行状况以及脚本的输出。自节点健康以来的时间也显示在Web界面上。
以下参数在yarn.site.xml配置
参数 值 说明
yarn.nodemanager.health-checker.script.path 节点健康脚本 用于检查节点健康状况的脚本。
yarn.nodemanager.health-checker.script.opts 节点健康脚本选项 用于检查节点健康状态的脚本选项。
yarn.nodemanager.health-checker.interval-ms 节点健康脚本间隔 运行健康脚本的时间间隔。
yarn.nodemanager.health-checker.script.timeout-ms 节点运行状况超时间隔 健康脚本执行超时。
如果只有部分本地磁盘变坏,则运行状况检查程序脚本不应该给出错误。NodeManager能够定期检查本地磁盘的运行状况(具体检查nodemanager-local-dirs和nodemanager-log-dirs),并在达到配置属性yarn.nodemanager.disk-health-checker.min-healthy-disks设置的错误目录数阈值,整个节点被标记为运行状况不佳,此信息也会发送给资源管理器。引导磁盘被突袭或健康检查程序脚本识别引导磁盘中的故障。
更多请参考yarn-site.xml配置详解
slaves文件是指定HDFS上有哪些DataNode节点。
直接编辑slaves文件,命令如下:
vim etc/hadoop/slaves
配置内容如下:
spark04
spark05
spark06
如果在上面已经配置过了,此步骤可以忽略。
配置hadoop的环境变量,命令如下:
vim /etc/profile
内容如下:
JAVA_HOME=/home/software/jdk1.8
HADOOP_HOME=/home/software/hadoop-2.7.3
PATH=$JAVA_HOME/bin:$HADOOP_HOME/bin:$HADOOP_HOME/sbin:$PATH
export JAVA_HOME PATH HADOOP_HOME
重新加载:
source /etc/profile
根据配置文件,创建相关的文件夹,用来存放对应数据。
在hadoop-2.7.1目录下创建:
命令如下:
#当前所在Hadoop根目录
mkdir journal
mkdir tmp
cd tmp/
mkdir namenode
mkdir datanode
通过scp 命令,将hadoop安装目录远程copy到其他5台机器上。
比如向spark02节点传输:
scp -r hadoop-2.10.1 root@spark02:/home/software/hadoop-2.10.1
远程拷贝之前要先在其他服务器上创建对应的目录(当前主机一样的目录结构,因为配置文件中写死了),否则拷贝失败。
!!!拷贝完毕后要记得在目标主机设置环境变量
在目标主机配置hadoop的环境变量,命令如下:
vim /etc/profile
内容如下:
JAVA_HOME=/home/software/jdk1.8
HADOOP_HOME=/home/software/hadoop-2.7.3
PATH=$JAVA_HOME/bin:$HADOOP_HOME/bin:$HADOOP_HOME/sbin:$PATH
export JAVA_HOME PATH HADOOP_HOME
重新加载:
source /etc/profile
在Zookeeper安装目录的bin目录下执行:
zkServer.sh start
此命令需要在所有的Zookeeper节点服务器上执行,执行完成可以使用以下命令查看启动状态:
zkServer.sh status
以下是查看进程命令:
jps
zkfc用来做两个namenode的状态切换管理或者失败切换管理。
在运行namenode的zk的节点服务器上,Hadoop的bin目录中执行如下命令:
sh hdfs zkfc -formatZK
如果配置了Hadoop的环境变量,那么在此节点的任何目录下都可以执行,这个指令的作用是在zookeeper集群上生成ha节点(ns节点)。
vim /data/aicu-tob/software/zookeeper-3.4.10/conf/zoo.cfg # 添加
zookeeper.sasl.client=false
若报错:using SASL (unknown error)
格式化以后会在Zookeeper写一些东西,现在可以看一下去(master节点):
为hadoop提供元数据管理(edits)。在04、05、06任意一个节点服务器上,即分配了journalnode角色的节点服务器上,切换到hadoop安装目录的sbin目录下,执行如下命令:
hadoop-daemons.sh start journalnode
注意:1、第一次需要手动起,以后就不需要手动启动了,就包含在了start-dfs.sh脚本里面了;
2、此命令执行一次就可以启动所有journalnode节点。如下图,命令使用的是hadoop-daemons.sh,是有s的,启动的时候一定要注意,不要用错了命令。
然后执行jps命令查看,如果此项启动不成功尝试重启,如果报ssh连接的问题Host key verification failed则手动检查每台主机的ssh密钥链接。这项启动不成功会影响下一步的格式化。
在spark01服务器上格式化namenode,执行如下命令:
hadoop namenode -format
spark01服务器
在spark01节点上执行如下命令,启动NameNode节点:
hadoop-daemon.sh start namenode
可以用下述命令查看服务是否拉起,若正常拉起会显示服务名
jps
spark02服务器
首先把spark02服务器的 namenode节点变为standby namenode节点,执行命令如下:
hdfs namenode -bootstrapStandby
启动spark02服务器的namenode节点,执行命令如下:
hadoop-daemon.sh start namenode
在spark04、spark05、spark06服务器上分别启动datanode节点,在这三台服务器上分别执行如下命令:
hadoop-daemon.sh start datanode
FalioverControllerActive是失败恢复线程。这个线程需要在NameNode节点所在的服务器上启动,在spark01、spark02服务器上执行如下命令:
hadoop-daemon.sh start zkfc
spark01服务器
在spark01服务器上启动主Resourcemanager节点,执行如下命令:
start-yarn.sh
启动成功后,spark04、spark05、spark06服务器上的nodemanager 也会跟随启动。
spark03服务器
在spark03服务器上启动副 Resoucemanager节点,执行如下命令:
yarn-daemon.sh start resourcemanager
访问主namenode,在浏览器中输入地址:http://192.168.234.21:50070,查看namenode的信息,是active状态的。此ip地址是我在配置的时候使用的ip地址,请不要照搬,要写自己使用的ip地址。
如果无法访问,请检查防火墙,或者端口是否方向or冲突,可以修改监听端口
查看yarn的管理地址:
http://192.168.234.21:8088(spark01的8088端口)
目前Apache Spark支持一种单机模式、三种分布式部署方式,分别是standalone、spark on mesos和 spark on YARN,详情参考。
Spark单机运行,一般用于开发测试。
构建一个由Master+Slave构成的Spark集群,Spark运行在集群中。
Spark客户端直接连接Yarn。不需要额外构建Spark集群。
Spark客户端直接连接Mesos。不需要额外构建Spark集群。
本文采用的是spark on YARM:原理见:https://www.cnblogs.com/linhaifeng/p/15919143.html#_label8
了解Spark standalone模式分布式部署:原理见:https://www.cnblogs.com/linhaifeng/p/15919143.html#_label5
在spark04、spark05、spark06节点上安装配置spark。此处以spark04服务器为例。
直接解压压缩包即可。
进入Spark安装目录的conf目录,配置以下文件。
spark-env.sh
conf目录下没有此文件,需要复制模版文件spark-env.sh.template更名,命令如下:
cp spark-env.sh.template spark-env.sh
vim spark-env.sh
直接在文件末尾添加,内容示例如下:
export JAVA_HOME=/home/software/jdk1.8
export SCALA_HOME=/home/software/scala2.11 # 如果不依赖scala语言,则忽略
export HADOOP_HOME=/data/aicu-tob/software/hadoop-2.10.1
export HADOOP_CONF_DIR=/data/aicu-tob/software/hadoop-2.10.1/etc/hadoop #让spark知道hadoop配置文件的路径,完成spark整合hadoop
export LANG="en_US.UTF-8"
spark-defaults.conf
此文件在目录下也没有,也需要复制模版文件,更名然后编辑,命令如下:
cp spark-defaults.conf.template spark-defaults.conf
vim spark-defaults.conf
直接在文件末尾添加内容,配置示例如下:
spark.ui.port 8040 # 选配,不配置则端口默认
slaves
此文件在conf目录下也没有,同样需要赋值模版文件,更名然后编辑,命令如下:
cp slaves.template slaves
vim slaves
同样在文件末尾直接添加配置内容即可,配置示例如下:
spark04
spark05
spark06
yarn-site.xml
如果是用虚拟机搭建,可能会由于虚拟机内存过小而导致启动失败,比如内存资源过小,yarn会直接kill掉进程导致rpc连接失败。
所以,我们还需要配置Hadoop的yarn-site.xml文件,加入如下两项配置:
至此spark on yarn就配置完毕。
强调!!!!
现在越来越多的场景,都是Spark跑在Hadoop集群中,所以为了做到资源能够均衡调度,会使用YARN来做为Spark的Cluster Manager,来为Spark的应用程序分配资源。
在执行Spark应用程序前,要启动Hadoop的各种服务。由于已经有了资源管理器,所以不需要启动Spark的Master、Worker守护进程。
怕你没看见,再强调一遍:在spark-Yarn模式下,Spark自身的Master结点和Worker结点不需要启动(只有集群的Standalone方式时,才需要这两个角色),但是Spark的部署包必须是基于对应的Yarn版本正确编译后的,否则会出现Spark和Yarn的兼容性问题
https://spark-reference-doc-cn.readthedocs.io/zh_CN/latest/deploy-guide/running-on-yarn.html
所以我们在部署完spark on yarn之后不需要启动spark,只需要用spark的工具提交任务即可,在提交之前,先把相关服务重启一下
往往在测试的时候,需要重新启动集群服务,在重新启动的时候,就不需要第一次配置时那么麻烦,可以按照如下步骤进行重启集群服务。
在Zookeeper安装目录的bin目录下执行:
sh zkServer.sh stop/start
此命令同样需要在所有的Zookeeper节点服务器上执行。
重启HDFS
进入hadoop安装目录的sbin目录,执行如下命令,此命令会将HDFS相关的所有节点都启动,不需要切换服务器来进行单独启动HDFS相关的节点进程。
stop-dfs.sh
start-dfs.sh
重启Yarn
spark01服务器
在spark01服务器上启动主Resourcemanager节点,执行如下命令:
stop-yarn.sh
start-yarn.sh
启动成功后,spark04、spark05、spark06服务器上的nodemanager 也会跟随启动。
spark03服务器
在spark03服务器上启动副 Resoucemanager节点,执行如下命令:
yarn-daemon.sh stop resourcemanager
yarn-daemon.sh start resourcemanager
可以通过spark shell启动任务,进入Spark安装目录的bin目录,执行如下命令,下述采用的是yarn-cient,生产环境应该采用yarn-cluster,点击查看二者区别
spark-shell --master yarn-client
可以通过yarn控制台来验证,会发现新增一个应用正在运行,ctrl+c掉spark-shell后任务结束
如果启动spark shell时报错
spark用yarn提交任务会报
ERROR cluster.YarnClientSchedulerBackend: YARN
application has exited unexpectedly with state UNDEFINED! Check the YARN
application logs for more details.
ERROR cluster.YarnClientSchedulerBackend: Diagnostics message: Shutdown hook called before final status was reported.
只需要将hadoop集群的yarn-site.xml配置中加入如下两行即可解决:
如果你用的java8,则多会报此错误。
如果报警告: WARN yarn.Client: Neither spark.yarn.jars nor spark.yarn.archive is set, falling back to uploading libraries under SPARK_HOME
解决方案有两种
1、方案一:
1、上传jar包
在HDFS上,创建一个目录,用来存放spark的依赖jar包。此目录是spark-defaults.conf目录中配置的目录名称,命令如下:
hadoop fs -mkdir /spark_jars
进入spark安装目录的jars目录,执行下述命令上传spark的jars
hadoop fs -put ./* /spark_jars
2、修改spark配置文件:spark-defaults.conf
末尾增加
spark.yarn.jars=hdfs://spark01:9000/spark_jars/* # 可以将spark运行时需要的jar包缓存在HDFS上,无需每次运行任务的时候都进行分发。
注:此处hdfs的地址需要是active状态的节点,注意访问的是hdfs,可以通过3.7小节所示的页面查看谁是active状态。
# 推荐阅读
关于Spark on Yarn运行时加载的jar包,详见https://www.yixuebiancheng.com/article/61045.html
https://www.cnblogs.com/zlslch/p/7612684.html
上传jar包并修改配置
2、方案二:
说白了,就是spark2.1.0或spark2.2.0以上的版本的命令有所变化。所以压根可以需改动解决办法1所示的配置,直接用官网这样的命令来操作就可以了。
http://spark.apache.org/docs/latest/running-on-yarn.html
从图中得知提交任务的另外一种方式
cd /data/aicu-tob/software/spark-2.4.8-bin-hadoop2.7 # 切换到spark的安装目录下执行,因为命令引用的spark-examples_2.11-2.4.8.jar采用的相对路径,当然用绝对路径也是可以的
./bin/spark-submit --master yarn --deploy-mode cluster --class org.apache.spark.examples.JavaSparkPi ./examples/jars/spark-examples_2.11-2.4.8.jar 80
可以通过yarn控制台来验证
可以点击ID进去查看详情
配置 yarn-site.xml 开启日志聚合
日志聚集是YARN提供的日志中央化管理功能,它能将运行完成的Container/任务日志上传到HDFS上,从而减轻NodeManager负载,且提供一个中央化存储和分析机制。默认情况下,Container/任务日志存在在各个NodeManager上
配置 mapred-site.xml
重启yarn
stop-yarn.sh
start-yarn.sh
开启日志监控服务进程
在nodenode机器上执行 sbin/mr-jobhistory-daemon.sh start historyserver
命令,执行完成后使用jps命令查看是否启动成功,若启动成功则会显示出JobHistoryServer服务
最好将yarn-site.xml 的 yarn.log.server.url
也配置上
不然的话这个链接跳转不到
引用:
http://www.51niux.com/?id=180
https://www.cnblogs.com/52mm/p/p13.html
https://www.daimajiaoliu.com/daima/48605606a900402
https://www.kancloud.cn/willseecloud/bigdata/2324801
hadoop原理剖析:https://www.saoniuhuo.com/article/detail-1124.html
Hadoop、Spark——完全分布式HA集群搭建
https://www.cnblogs.com/caoweixiong/p/13451038.html
Spark2.3 HA集群的分布式安装
Hadoop集群的四个配置文件的常用属性解析
面试题:https://www.1024sou.com/article/751466.html