本节所讲的hadoop基本安装配置主要包含三部分内容:
单机
伪分布
全分布
本次实验环境所用的操作系统为centos7,在进行安装之前,我们首先要做以下准备工作:
1.创建hadoop用户
为方便操作我们创建一个名为hadoop的用户来运行程序,这样可以使得不同用户之间有明确的权限区别,同时针对hadoop的配置操作也可以不影响其它用户的使用。对于一些大的软件比如MySql,在企业中也常常为它单独创建一个用户。
创建用户的命令是useradd,设置密码为passwd,此外可能部分系统还需要为用户创建文件夹,在这里我们就不详细说明了。
2.java安装
由于hadoop本身是由java编写,因此对于hadoop开发和运行都需要java的支持,对于版本上的要求为java 6或者更新的版本。对于centos7本身,系统上可能已经预装了java7,它的jdk版本应该为openjdk,路径为/usr/lib/jvm/java-1.7.0-openjdk,此即为后文中需要配置的JAVA_HOME环境。
对于hadoop而言,使用oracle公司更为广泛应用的java版本在功能上可能会更稳定一些,因此用户也可以根据自己的爱好安装oracle版本的java,在安装过程中请记录jdk的路径,即JAVA_HOME的位置,这个路径的设置将在后文hadoop的配置文件中,目的是让hadoop程序可以找到依赖的java工具。
3.ssh登陆权限
对于hadoop的伪分布和全分布而言,hadoop主控机namenode需要启动集群中所有主机的hadoop守护进程,而这个过程是通过ssh登陆实现的。hadoop并没有提供ssh输入密码登陆的形式,因此为了能够顺利登陆每台机器,需要将所有机器配置为主控机namenode可以无密码登陆。
ssh无密码登陆的方式是指namenode生成自己的ssh key:
ssh-keygen -t rsa -P '' //在后面选择存放位置时按照默认位置,会存放在用户目录的.ssh/路径下。
生成自己的key之后,将它的public key发送给集群中其它的主机。我们将id_dsa.pub中的内容添加到要匿名登陆的节点的.ssh/authorized_key下,然后在理论上就可以无密码登陆了。对于无密码登陆本机而言,代码可以为:
cat ~/.ssh/id_dsa.pub >> ~/.ssh/authorized_keys
这时大家可以通过ssh localhost 检测一下是否需要输入密码。对于ubuntu而言,到这里ssh就配置好了,但是由于centos7更为严格的安全措施,还需要修改两个地方:
1.修改/etc/ssh/sshd_config文件,将其中以下几行的注释去掉
RSAAuthentication yes
PubkeyAuthentication yes
AuthorizedKeysFile .ssh/authorized_keys
2.确认~/.ssh/authorized_keys的权限为600
这样配置之后,ssh的配置就完成了
4.安装单机hadoop
本文中使用的hadoop版本为1.2.1,虽然hadoop目前最新版本已经为2.6.0,但由于新的功能在本文中并不会用到,因此我们选择1.2.1版本,下载链接为http://mirrors.hust.edu.cn/apache/hadoop/common/hadoop-1.2.1/,在目录中选择hadoop-1.2.1.tar.gz
将该文件夹解压后,放置到自己喜欢的位置,如/usr/lcoal/hadoop文件夹下,注意文件夹的用户和组保证为hadoop:hadoop。
在hadoop的文件夹中,conf/下面放置了配置文件,对于单机安装,我们首先需要更改hadoop-env.sh文件,以配置hadoop运行的环境变量,这里只需要将JAVA_HOME环境变量指定到本机的jdk目录就可以了,如:
export JAVA_HOME=/usr/lib/jvm/java-1.7.0-openjdk
完成之后,我们试着查看hadoop版,运行/usr/local/hadoop/bin/hadoop version
此时应该得到这样的提示
Hadoop 1.2.1
........
This command was run using /usr/local/hadoop/hadoop-core-1.2.1.jar
hadoop文档中还附带了一些例子来供我们测试,我们可以运行WordCount的例子检测一下安装是否成功。
我们将conf文件夹下的配置文件拷贝到当前目录新建的input文件夹中,作为输入数据,然后在当前目录创建output文件夹,执行如下代码:
./bin/hadoop jar hadoop-examples-2.4.1.jar grep input output 'dfs[a-z.]+'
执行之后,我们
cat ./output/*
会得到
1 dfsadmin
这意味着在所有的配置文件中只有一个符合正则表达式的单词,结果正确。
5 hadoop伪分布式安装
伪分布式安装是指在一台机器上模拟一个小的集群。当hadoop应用于集群时,不论是伪分布式还是真正的分布式运行,都需要通过配置文件对各组件的协同工作进行设置,最重要的几个配置文件见下表:
对于伪分布式配置我们需要修改core-site-xml、hdfs-site-xml和mapred-site-xml三个文件
core-site-xml:
<configuration>
<property>
<name>fs.default.name</name>
<value>hdfs://localhost:9000</value>
</property>
</configuration>
配置文件的格式十分简单,<name>标签代表了配置项的名字,<value>项设置的是配置的值,对于core-site-xml文件我们只需要在其中指定文件系统的默认名字,并设置了通信端口号,这里我们按照官方文档设置为9000。
hdfs-site-xml:
<configuration>
<property>
<name>dfs.replication</name>
<value>1</value>
</property>
</configuration>
对于hdfs-site-xml文件,我们设置replication值为1,这也是hadoop运行的默认最小值,它限制了hdfs文件系统的备份方案,详细内容可以参照文档。
mapred-site-xml:
<configuration>
<property>
<name>mapred.job.tracker</name>
<value>localhost:9001</value>
</property>
</configuration>
对于mapred-site-xml文件,我们在其中设置jobtracker的端口信息。
对于本文中的实验,我们这样配置后就已经满足运行要求了,我们还会给出一个官方文档的详细地址,感兴趣的读者可以查看文档配置其它项目http://hadoop.apache.org/docs/r1.2.1/api/index.html
在配置完成后,我们首先初始化文件系统,由于hadoop的很多工作是在自带的HDFS文件系统上完成的,因此需要将文件系统初始化之后才能进一步执行计算任务,命令如下
[hadoop@localhost hadoop]$ ./bin/hadoop namenode -format
15/01/14 18:04:15 INFO namenode.NameNode: STARTUP_MSG:
/************************************************************
STARTUP_MSG: Starting NameNode
STARTUP_MSG: host = localhost.localdomain/127.0.0.1
STARTUP_MSG: args = [-format]
STARTUP_MSG: version = 1.2.1
STARTUP_MSG: build = https://svn.apache.org/repos/asf/hadoop/common/branches/branch-1.2 -r 1503152; compiled by 'mattf' on Mon Jul 22 15:23:09 PDT 2013
STARTUP_MSG: java = 1.7.0_71
************************************************************/
15/01/14 18:04:15 INFO util.GSet: Computing capacity for map BlocksMap
15/01/14 18:04:15 INFO util.GSet: VM type = 64-bit
15/01/14 18:04:15 INFO util.GSet: 2.0% max memory = 932184064
15/01/14 18:04:15 INFO util.GSet: capacity = 2^21 = 2097152 entries
........
15/01/14 18:04:16 INFO common.Storage: Storage directory file:/usr/local/hadoop/hadoop_hadoop/dfs/name has been successfully formatted.
15/01/14 18:04:16 INFO namenode.NameNode: SHUTDOWN_MSG:
/************************************************************
SHUTDOWN_MSG: Shutting down NameNode at localhost.localdomain/127.0.0.1
************************************************************/
在看到successfully formatted之后说明初始化成功了。
然后用如下命令启动所有节点,可以通过提示信息得知所有的启动信息都写入了对应的日志文件中,如果出现启动错误,则我们可以在日志中查看错误原因:
[hadoop@localhost hadoop]$ ./bin/start-all.sh
运行之后,我们输入jps指令,查看所有的java进程,在正常启动时,我们可以得到如下结果:
[hadoop@localhost conf]$ jps
18271 JobTracker
18860 Jps
17998 DataNode
17854 NameNode
18431 TaskTracker
18171 SecondaryNameNode
此时可以访问Web界面 http://localhost:50070来查看Hadoop的信息。
接下来我们执行命令./bin/hadoop dfs -mkdir input 创建存储数据的文件夹,然后执行命令./bin/hadoop fs -put ./input/ input 将之前文件夹中的数据移动到新的input文件夹中,然后我们执行字数统计测试样例:
[hadoop@localhost hadoop]$ ./bin/hadoop jar hadoop-examples-1.2.1.jar wordcount input output
然后在输出的信息中可以看到相关信息
15/01/16 17:41:50 INFO input.FileInputFormat: Total input paths to process : 7
15/01/16 17:41:50 INFO util.NativeCodeLoader: Loaded the native-hadoop library
15/01/16 17:41:50 WARN snappy.LoadSnappy: Snappy native library not loaded
15/01/16 17:41:51 INFO mapred.JobClient: Running job: job_201501161728_0002
15/01/16 17:41:52 INFO mapred.JobClient: map 0% reduce 0%
15/01/16 17:41:58 INFO mapred.JobClient: map 28% reduce 0%
15/01/16 17:42:01 INFO mapred.JobClient: map 57% reduce 0%
15/01/16 17:42:03 INFO mapred.JobClient: map 85% reduce 0%
15/01/16 17:42:05 INFO mapred.JobClient: map 100% reduce 0%
15/01/16 17:42:06 INFO mapred.JobClient: map 100% reduce 28%
15/01/16 17:42:13 INFO mapred.JobClient: map 100% reduce 100%
15/01/16 17:42:14 INFO mapred.JobClient: Job complete: job_201501161728_0002
15/01/16 17:42:14 INFO mapred.JobClient: Counters: 29
15/01/16 17:42:14 INFO mapred.JobClient: Job Counters
15/01/16 17:42:14 INFO mapred.JobClient: Launched reduce tasks=1
15/01/16 17:42:14 INFO mapred.JobClient: SLOTS_MILLIS_MAPS=19671
15/01/16 17:42:14 INFO mapred.JobClient: Total time spent by all reduces waiting after reserving slots (ms)=0
15/01/16 17:42:14 INFO mapred.JobClient: Total time spent by all maps waiting after reserving slots (ms)=0
15/01/16 17:42:14 INFO mapred.JobClient: Launched map tasks=7
15/01/16 17:42:14 INFO mapred.JobClient: Data-local map tasks=7
15/01/16 17:42:14 INFO mapred.JobClient: SLOTS_MILLIS_REDUCES=14965
15/01/16 17:42:14 INFO mapred.JobClient: File Output Format Counters
15/01/16 17:42:14 INFO mapred.JobClient: Bytes Written=6289
15/01/16 17:42:14 INFO mapred.JobClient: FileSystemCounters
15/01/16 17:42:14 INFO mapred.JobClient: FILE_BYTES_READ=10153
15/01/16 17:42:14 INFO mapred.JobClient: HDFS_BYTES_READ=15849
15/01/16 17:42:14 INFO mapred.JobClient: FILE_BYTES_WRITTEN=466761
15/01/16 17:42:14 INFO mapred.JobClient: HDFS_BYTES_WRITTEN=6289
15/01/16 17:42:14 INFO mapred.JobClient: File Input Format Counters
15/01/16 17:42:14 INFO mapred.JobClient: Bytes Read=14995
15/01/16 17:42:14 INFO mapred.JobClient: Map-Reduce Framework
15/01/16 17:42:14 INFO mapred.JobClient: Map output materialized bytes=10189
15/01/16 17:42:14 INFO mapred.JobClient: Map input records=369
15/01/16 17:42:14 INFO mapred.JobClient: Reduce shuffle bytes=10189
15/01/16 17:42:14 INFO mapred.JobClient: Spilled Records=1164
15/01/16 17:42:14 INFO mapred.JobClient: Map output bytes=20817
15/01/16 17:42:14 INFO mapred.JobClient: Total committed heap usage (bytes)=1243086848
15/01/16 17:42:14 INFO mapred.JobClient: CPU time spent (ms)=4540
15/01/16 17:42:14 INFO mapred.JobClient: Combine input records=1741
15/01/16 17:42:14 INFO mapred.JobClient: SPLIT_RAW_BYTES=854
15/01/16 17:42:14 INFO mapred.JobClient: Reduce input records=582
15/01/16 17:42:14 INFO mapred.JobClient: Reduce input groups=419
15/01/16 17:42:14 INFO mapred.JobClient: Combine output records=582
15/01/16 17:42:14 INFO mapred.JobClient: Physical memory (bytes) snapshot=1402548224
15/01/16 17:42:14 INFO mapred.JobClient: Reduce output records=419
15/01/16 17:42:14 INFO mapred.JobClient: Virtual memory (bytes) snapshot=7075622912
15/01/16 17:42:14 INFO mapred.JobClient: Map output records=1741
在计算完成后,大家可以输入命令./bin/hadoop fs -cat output/* 查看最终结果。当需要重新运行程序时,请首先将output文件夹删除。