在阿里云ECS服务器上搭建Hadoop集群
简介
Hadoop是一个开源的分布式计算的基础框架,其中最主要的组成部分则包括了hadoop分布式文件系统(hadoop distributed file system, 简称hdfs)以及mapreduce功能,而mapreduce在hadoop中则使用yarn调度组件完成。众所周知,google在分布式系统最有名的三个成果就是big table, google file system跟mapreduce,而hdfs则是对应的google file system的一个开源实现,而yarn则是mapreduce的一个开源实现。在下文中则将会介绍如何在数台阿里云的ecs服务器上搭建一个hadoop集群。为了方便下文中的配置,首先简要地介绍一下hdfs的架构,hdfs由一个namenode(用于存储文件系统的meta data),以及若干个datanode(存储文件数据)来组成,其中namenode负责对整个分布式文件系统进行管理,以及存储文件命名数据,因此也可以被称之为master node,而datanode有时候也被称为slavenode。(本篇教程主要参考自[1])
搭建Hadoop集群步骤
在阿里云上购买ECS服务器
首先需要完成的是在阿里云上购买运行hadoop的ecs服务器(注意所有服务器都需要在同一一个可用区中),由于我需要运行的应用需要较大的内存,因此我选择了购买ecs.r5.2xlarge实例,每台服务器具有64GB内存以及8个虚拟cpu核心,总共购买了9台云服务器实例。在购买的过程中可以选择服务器的hostname,为了方便起见,我将其中将作为hadoop namenode(master node)的服务器hostname改为hadoop-master,而剩下的作为datanode(slave node)的服务器分别命名为"hadoop-slave001"..."hadoop-slave008"。
配置集群内ssh无密码登陆
添加hadoop账户
首先需要在每台机器上都添加一个名为hadoop的账户,在这里为了方便起见,我将所有机器上的hadoop账户都添加了sudo权限,所需要的命令如下所示:(以下命令需要在root账户中执行)
useradd hadoop
passwd hadoop
usermod -aG wheel hadoop
在使用root账户添加完成hadoop账户之后,就退出root账户,登陆到hadoop账户中进行接下来的所有操作;
接下来配置所有机器上的/etc/hosts文件(需要sudo权限),在该文件中,添加整个集群的所有机器跟其内网ip地址(注意是内网ip而不是公网ip)的映射关系,修改完该文件之后的结果应当如下所示:
127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4
::1 localhost localhost.localdomain localhost6 localhost6.localdomain6
[hadoop-master的内网ip] hadoop-master hadoop-master
[hadoop-slave001的内网ip] hadoop-slave001 hadoop-slave001
[hadoop-slave002的内网ip] hadoop-slave002 hadoop-slave002
[hadoop-slave003的内网ip] hadoop-slave003 hadoop-slave003
[hadoop-slave004的内网ip] hadoop-slave004 hadoop-slave004
[hadoop-slave005的内网ip] hadoop-slave005 hadoop-slave005
[hadoop-slave006的内网ip] hadoop-slave006 hadoop-slave006
[hadoop-slave007的内网ip] hadoop-slave007 hadoop-slave007
[hadoop-slave008的内网ip] hadoop-slave008 hadoop-slave008
设置ssh密钥登陆
由于hadoop需要各个机器之间无密码ssh登陆来进行通信,因此下一步操作就是设置ssh密钥登陆了,首先在每台机器上生成本地的ssh密钥对:
ssh-keygen -b 4096
然后将公钥发送给其他所有机器:
ssh-copy-id hadoop@hadoop-master
ssh-copy-id hadoop@hadoop-slave001
ssh-copy-id hadoop@hadoop-slave002
ssh-copy-id hadoop@hadoop-slave003
ssh-copy-id hadoop@hadoop-slave004
ssh-copy-id hadoop@hadoop-slave005
ssh-copy-id hadoop@hadoop-slave006
ssh-copy-id hadoop@hadoop-slave007
ssh-copy-id hadoop@hadoop-slave008
安装Hadoop
安装jdk
由于hadoop是搭建在jvm之上的,因此需要安装java的开发工具即jdk,如以下命令所示:
sudo yum update
sudo yum install java-1.8.0-openjdk-devel
下载hadoop编译好的二进制文件
hadoop编译好的二进制文件可以在https://hadoop.apache.org/releases.html网站找到,由于本人需要跑的应用是在hadoop 2上开发的,因此下载了2.7.7版本,如果下载3版本的话,在后续的配置hadoop的部分会有稍微的不同(比如2.x版本的slaves配置文件在3.x版本中被命名为了workers文件,同时监视hdfs的端口也有所不同)。
下载与解压hadoop 2.7.7二进制文件的命令如下:
cd ~
wget https://www-us.apache.org/dist/hadoop/common/hadoop-2.7.7/hadoop-2.7.7.tar.gz
tar xvf hadoop-2.7.7.tar.gz
mv hadoop-2.7.7 hadoop
配置环境变量
接下来为了方便调用hdfs等命令,需要配置一下PATH环境变量:
vim ~/.bash_profile
然后在export PATH这一行前面添加
PATH=/home/hadoop/hadoop/bin:/home/hadoop/hadoop/sbin:$PATH
然后保存并退出该文件。
配置hadoop
首先为了让hadoop能够识别到jdk的安装位置,需要进行相应配置,首先使用以下命令:
update-alternatives --display java
可以看到如下的输出,其中的xxx/bin/java便是java的安装位置,而xxx便是jdk的目录,在此该目录被确定为"/usr/lib/jvm/java-1.8.0-openjdk-1.8.0.212.b04-0.el7_6.x86_64/jre"。
java - status is auto.
link currently points to /usr/lib/jvm/java-1.8.0-openjdk-1.8.0.212.b04-0.el7_6.x86_64/jre/bin/java
/usr/lib/jvm/java-1.8.0-openjdk-1.8.0.212.b04-0.el7_6.x86_64/jre/bin/java - family java-1.8.0-openjdk.x86_64 priority 1800212
slave jre: /usr/lib/jvm/java-1.8.0-openjdk-1.8.0.212.b04-0.el7_6.x86_64/jre
slave jre_exports: /usr/lib/jvm-exports/jre-1.8.0-openjdk-1.8.0.212.b04-0.el7_6.x86_64
slave jjs: /usr/lib/jvm/java-1.8.0-openjdk-1.8.0.212.b04-0.el7_6.x86_64/jre/bin/jjs
slave keytool: /usr/lib/jvm/java-1.8.0-openjdk-1.8.0.212.b04-0.el7_6.x86_64/jre/bin/keytool
slave orbd: /usr/lib/jvm/java-1.8.0-openjdk-1.8.0.212.b04-0.el7_6.x86_64/jre/bin/orbd
slave pack200: /usr/lib/jvm/java-1.8.0-openjdk-1.8.0.212.b04-0.el7_6.x86_64/jre/bin/pack200
slave rmid: /usr/lib/jvm/java-1.8.0-openjdk-1.8.0.212.b04-0.el7_6.x86_64/jre/bin/rmid
slave rmiregistry: /usr/lib/jvm/java-1.8.0-openjdk-1.8.0.212.b04-0.el7_6.x86_64/jre/bin/rmiregistry
slave servertool: /usr/lib/jvm/java-1.8.0-openjdk-1.8.0.212.b04-0.el7_6.x86_64/jre/bin/servertool
slave tnameserv: /usr/lib/jvm/java-1.8.0-openjdk-1.8.0.212.b04-0.el7_6.x86_64/jre/bin/tnameserv
slave policytool: /usr/lib/jvm/java-1.8.0-openjdk-1.8.0.212.b04-0.el7_6.x86_64/jre/bin/policytool
slave unpack200: /usr/lib/jvm/java-1.8.0-openjdk-1.8.0.212.b04-0.el7_6.x86_64/jre/bin/unpack200
slave java.1.gz: /usr/share/man/man1/java-java-1.8.0-openjdk-1.8.0.212.b04-0.el7_6.x86_64.1.gz
slave jjs.1.gz: /usr/share/man/man1/jjs-java-1.8.0-openjdk-1.8.0.212.b04-0.el7_6.x86_64.1.gz
slave keytool.1.gz: /usr/share/man/man1/keytool-java-1.8.0-openjdk-1.8.0.212.b04-0.el7_6.x86_64.1.gz
slave orbd.1.gz: /usr/share/man/man1/orbd-java-1.8.0-openjdk-1.8.0.212.b04-0.el7_6.x86_64.1.gz
slave pack200.1.gz: /usr/share/man/man1/pack200-java-1.8.0-openjdk-1.8.0.212.b04-0.el7_6.x86_64.1.gz
slave rmid.1.gz: /usr/share/man/man1/rmid-java-1.8.0-openjdk-1.8.0.212.b04-0.el7_6.x86_64.1.gz
slave rmiregistry.1.gz: /usr/share/man/man1/rmiregistry-java-1.8.0-openjdk-1.8.0.212.b04-0.el7_6.x86_64.1.gz
slave servertool.1.gz: /usr/share/man/man1/servertool-java-1.8.0-openjdk-1.8.0.212.b04-0.el7_6.x86_64.1.gz
slave tnameserv.1.gz: /usr/share/man/man1/tnameserv-java-1.8.0-openjdk-1.8.0.212.b04-0.el7_6.x86_64.1.gz
slave policytool.1.gz: /usr/share/man/man1/policytool-java-1.8.0-openjdk-1.8.0.212.b04-0.el7_6.x86_64.1.gz
slave unpack200.1.gz: /usr/share/man/man1/unpack200-java-1.8.0-openjdk-1.8.0.212.b04-0.el7_6.x86_64.1.gz
Current `best' version is /usr/lib/jvm/java-1.8.0-openjdk-1.8.0.212.b04-0.el7_6.x86_64/jre/bin/java.
接下来打开~/hadoop/etc/hadoop/hadoop-env.sh文件进行编辑,找到"export JAVA_HOME=${JAVA_HOME}"这一行,并且将其替换为“export JAVA_HOME={我们刚刚发现的jdk目录}”,这个目录在不同机器上可能不同,在本机器上修改为“export JAVA_HOME=/usr/lib/jvm/java-1.8.0-openjdk-1.8.0.212.b04-0.el7_6.x86_64/jre”。
接下来配置NameNode的位置(也就是文件系统hdfs的元数据),需要编辑文件"~/hadoop/etc/hadoop/core-site.xml",编辑完的结果如下所示:
fs.default.name
hdfs://hadoop-master:9000
接下来配置namenode和datanode在各自机器上的存放路径,编辑文件“~/hadoop/etc/hadoop/hdfs-site.xml”,编辑后的结果如下所示:
dfs.namenode.name.dir
/home/hadoop/data/nameNode
dfs.datanode.data.dir
/home/hadoop/data/dataNode
dfs.replication
1
接下来配置YARN,首先执行以下命令:
cd ~/hadoop/etc/hadoop
mv mapred-site.xml.template mapred-site.xml
然后编辑文件"~/hadoop/etc/hadoop/mapred-site.xml",编辑结果如下所示:
mapreduce.framework.name
yarn
mapreduce.jobtracker.address
yarn
编辑文件“~/hadoop/etc/hadoop/yarn-site.xml”,编辑结果如下所示:
yarn.acl.enable
0
yarn.resourcemanager.hostname
hadoop-master
yarn.nodemanager.aux-services
mapreduce_shuffle
接下来配置slave nodes的列表,打开文件"~/hadoop/etc/hadoop/slaves",编辑结果如下:
hadoop-slave001
hadoop-slave002
hadoop-slave003
hadoop-slave004
hadoop-slave005
hadoop-slave006
hadoop-slave007
hadoop-slave008
接下来将配置好的hadoop发送到各个slave机器上:
cd ~
scp -r hadoop hadoop-slave001:~
scp -r hadoop hadoop-slave002:~
scp -r hadoop hadoop-slave003:~
scp -r hadoop hadoop-slave004:~
scp -r hadoop hadoop-slave005:~
scp -r hadoop hadoop-slave006:~
scp -r hadoop hadoop-slave007:~
scp -r hadoop hadoop-slave008:~
接下来在master节点上格式化hdfs文件系统:
hdfs namenode -format
接下来就可以启动hdfs了:
start-dfs.sh
接下来可以使用jps命令查看hdfs是否正常运行,在hadoop-master上执行"jps"命令的结果应当如下所示:(进程号不一定一样)
hadoop@hadoop-master ~> jps
5536 SecondaryNameNode
5317 NameNode
5691 Jps
而在hadoop-slave上执行jps的结果应当如下:
[hadoop@hadoop-slave001 ~]$ jps
16753 Jps
16646 DataNode
如果需要关闭hdfs,则使用命令:
stop-dfs.sh
接下来启动yarn,执行命令:
start-yarn.sh
如果yarn正常启动,在执行"jps"命令的时候应该可以发现,在hadoop-master上多了一个名为“ResourceManager”的进程,而在hadoop-slave上多了一个名为“NodeManager”的进程;
如果需要关闭yarn,则:
stop-yarn.sh
测试Hadoop是否正确安装
接下来运行一些简单的样例(统计某几个文本文件中的单词总数)来判断hadoop是否能在集群上正常运行:
首先在hdfs上创建一个home目录:
hdfs dfs -mkdir /home
hdfs dfs -mkdir /home/hadoop
下载数据集并复制(put命令)到hdfs上:
hdfs dfs -mkdir /home/hadoop/books
cd ~
mkdir books
wget -O alice.txt https://www.gutenberg.org/files/11/11-0.txt
wget -O holmes.txt https://www.gutenberg.org/ebooks/1661.txt.utf-8
wget -O frankenstein.txt https://www.gutenberg.org/ebooks/84.txt.utf-8
hdfs dfs -put alice.txt holmes.txt frankenstein.txt /home/hadoop/books
查看hdfs上的数据集:
hdfs dfs -ls /home/hadoop/books
hdfs dfs -cat /home/hadoop/books/alice.txt
使用hadoop自带的单词数目统计样例来统计数据集中的所有单词的数目:
yarn jar ~/hadoop/share/hadoop/mapreduce/hadoop-mapreduce-examples-2.7.7.jar wordcount "/home/hadoop/books/*" /home/hadoop/output
顺利的话可以在hdfs的/home/hadoop/output/目录下看到输出文件:
hadoop@hadoop-master ~> hdfs dfs -ls /home/hadoop/output
Found 2 items
-rw-r--r-- 1 hadoop supergroup 0 2019-05-28 14:59 /home/hadoop/output/_SUCCESS
-rw-r--r-- 1 hadoop supergroup 789726 2019-05-28 14:59 /home/hadoop/output/part-r-00000
至此整个hadoop集群的环境就已经基本搭建完成了~
参考资料
[1] https://www.linode.com/docs/databases/hadoop/how-to-install-and-set-up-hadoop-cluster/
如果我的文章给您带来了帮助,并且您愿意给我一些小小的支持的话,以下这个是我的比特币地址~
My bitcoin address: 3KsqM8tef5XJ9jPvWGEVXyJNpvyLLsrPZj