在阿里云ECS服务器上搭建Hadoop集群

在阿里云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"。

image.png

配置集群内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",编辑完的结果如下所示:

<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="configuration.xsl"?>
<!--
  Licensed under the Apache License, Version 2.0 (the "License");
  you may not use this file except in compliance with the License.
  You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

  Unless required by applicable law or agreed to in writing, software
  distributed under the License is distributed on an "AS IS" BASIS,
  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  See the License for the specific language governing permissions and
  limitations under the License. See accompanying LICENSE file.
-->

<!-- Put site-specific property overrides in this file. -->

<configuration>
    <property>
            <name>fs.default.name</name>
            <value>hdfs://hadoop-master:9000</value>
        </property>
</configuration>

接下来配置namenode和datanode在各自机器上的存放路径,编辑文件“~/hadoop/etc/hadoop/hdfs-site.xml”,编辑后的结果如下所示:

<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="configuration.xsl"?>
<!--
  Licensed under the Apache License, Version 2.0 (the "License");
  you may not use this file except in compliance with the License.
  You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

  Unless required by applicable law or agreed to in writing, software
  distributed under the License is distributed on an "AS IS" BASIS,
  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  See the License for the specific language governing permissions and
  limitations under the License. See accompanying LICENSE file.
-->

<!-- Put site-specific property overrides in this file. -->

<configuration>

    <property>
            <name>dfs.namenode.name.dir</name>
            <value>/home/hadoop/data/nameNode</value>
    </property>

    <property>
            <name>dfs.datanode.data.dir</name>
            <value>/home/hadoop/data/dataNode</value>
    </property>

    <property>
            <name>dfs.replication</name>
            <value>1</value>
    </property>

</configuration>

接下来配置YARN,首先执行以下命令:

cd ~/hadoop/etc/hadoop
mv mapred-site.xml.template mapred-site.xml

然后编辑文件"~/hadoop/etc/hadoop/mapred-site.xml",编辑结果如下所示:

<?xml version="1.0"?>
<?xml-stylesheet type="text/xsl" href="configuration.xsl"?>
<!--
  Licensed under the Apache License, Version 2.0 (the "License");
  you may not use this file except in compliance with the License.
  You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

  Unless required by applicable law or agreed to in writing, software
  distributed under the License is distributed on an "AS IS" BASIS,
  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  See the License for the specific language governing permissions and
  limitations under the License. See accompanying LICENSE file.
-->

<!-- Put site-specific property overrides in this file. -->

<configuration>

    <property>
        <name>mapreduce.framework.name</name>
        <value>yarn</value>
    </property>
    <property>
        <name>mapreduce.jobtracker.address</name>
        <value>yarn</value>
    </property>

</configuration>

编辑文件“~/hadoop/etc/hadoop/yarn-site.xml”,编辑结果如下所示:

<?xml version="1.0"?>
<!--
  Licensed under the Apache License, Version 2.0 (the "License");
  you may not use this file except in compliance with the License.
  You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

  Unless required by applicable law or agreed to in writing, software
  distributed under the License is distributed on an "AS IS" BASIS,
  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  See the License for the specific language governing permissions and
  limitations under the License. See accompanying LICENSE file.
-->
<configuration>

<!-- Site specific YARN configuration properties -->

    <property>
            <name>yarn.acl.enable</name>
            <value>0</value>
    </property>

    <property>
            <name>yarn.resourcemanager.hostname</name>
            <value>hadoop-master</value>
    </property>

    <property>
            <name>yarn.nodemanager.aux-services</name>
            <value>mapreduce_shuffle</value>
    </property>

</configuration>

接下来配置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

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 143,736评论 1 303
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 61,631评论 1 258
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 95,145评论 0 213
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 41,213评论 0 181
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 49,025评论 1 259
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 38,893评论 1 178
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 30,497评论 2 273
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 29,240评论 0 167
  • 想象着我的养父在大火中拼命挣扎,窒息,最后皮肤化为焦炭。我心中就已经是抑制不住地欢快,这就叫做以其人之道,还治其人...
    爱写小说的胖达阅读 29,114评论 6 235
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 32,596评论 0 213
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 29,363评论 2 215
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 30,717评论 1 232
  • 白月光回国,霸总把我这个替身辞退。还一脸阴沉的警告我。[不要出现在思思面前, 不然我有一百种方法让你生不如死。]我...
    爱写小说的胖达阅读 24,279评论 0 32
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 27,183评论 2 214
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 31,629评论 3 209
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 25,647评论 0 9
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,047评论 0 167
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 33,625评论 2 232
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 33,734评论 2 236

推荐阅读更多精彩内容