1、Linux下Hadoop的分布式配置和使用Linux下Hadoop分布式配置和使用詹坤林 2010年5月目 录介绍20 集群网络环境介绍21 /etc/hosts文件配置22 SSH无密码验证配置32.1 选择一:配置Namenode无密码登录所有Datanode32.1选择二:配置所有节点之间SSH无密码验证43 JDK安装和Java环境变量配置53.1 安装 JDK 1.653.2 Java环境变量配置54 Hadoop集群配置55 Hadoop集群启动86 Hadoop使用106.1 客户机与HDFS进行交互106.1.1 客户机配置106.1.2 列出HDFS根目录/下的文件116.1
2、.3 列出当前用户主目录下的文件116.1.4 HDFS用户管理116.1.5 复制本地数据到HDFS中126.1.6 数据副本说明126.1.7 hadoop-site.xml参数说明136.1.8 HDFS中的路径136.1.8 Hadoop相关命令146.2 客户机提交作业到集群146.2.1 客户机配置146.2.2 一个测试例子WordCount156.2.3 编写Hadoop应用程序并在集群上运行166.2.4 三种模式下编译运行Hadoop应用程序166.2.5 提交多个作业到集群18附 程序19介绍这是本人在完全分布式环境下在Cent-OS中配置Hadoop-0.19.1时的总
3、结文档,但该文档也适合其他版本的Linux系统和目前各版本的Hadoop(Hadoop-0.20之后的版本配置文件hadoop-site.xml被拆分成了三个core-site.xml,hdfs-site.xml和mapred-site.xml,这里会说明0.20后的版本中如何配置这三个文件)。Hadoop配置建议所有配置文件中使用主机名进行配置,并且机器上应在防火墙中开启相应端口,并设置SSHD服务为开机启动,此外java环境变量可以在/etc/profile中配置。0 集群网络环境介绍集群包含三个节点:1个namenode,2个datanode,节点之间局域网连接,可以相互ping通。节点
4、IP地址和主机名分布如下:10.10.97.132 gc03vm12 namenode 10.10.97.142 gc04vm12 datanode0110.10.97.144 gc04vm14 datanode02所有节点均是Cent-OS系统,防火墙均禁用,sshd服务均开启并设置为开机启动。所有节点上均创建了一个hadoop用户,用户主目录是/home/hadoop。所有节点上均创建了一个目录/usr/local/hadoop,并且拥有者是hadoop用户。因为该目录用于安装hadoop,用户对其必须有rwx权限。(一般做法是root用户在/usr/local下创建hadoop目录,并修
5、改该目录拥有者为nutch(chown R nutch:nutch /usr/local/hadoop)。1 /etc/hosts文件配置(1)namenode节点上编辑/etc/hosts文件将所有节点的名字和IP地址写入其中,写入如下内容,注意注释掉127.0.0.1行,保证内容如下:10.10.97.132 gc03vm12 10.10.97.142 gc04vm12 10.10.97.144 gc04vm14 # 127.0.0.1 centos54 localhost.localdomain localhost(2)将Namenode上的/etc/hosts文件复制到所有数据节点上,
6、操作步骤如下:root用户登录namenode;执行命令:scp /etc/hosts rootdatanode ip:/etc/hosts2 SSH无密码验证配置Hadoop需要使用SSH协议,namenode将使用SSH协议启动namenode和datanode进程,datanode向namenode传递心跳信息可能也是使用SSH协议,这是我认为的,还没有做深入了解,datanode之间可能也需要使用SSH协议。假若是,则需要配置使得所有节点之间可以相互SSH无密码登陆验证。下面给出了两种配置方式,用户可以选择第一种,若实验中出现问题可选择第二种进行尝试。2.1 选择一:配置Namenod
7、e无密码登录所有Datanode(0)原理Namenode作为客户端,要实现无密码公钥认证,连接到服务端datanode上时,需要在namenode上生成一个密钥对,包括一个公钥和一个私钥,而后将公钥复制到datanode上。当namenode通过ssh连接datanode时,datanode就会生成一个随机数并用namenode的公钥对随机数进行加密,并发送给namenode。namenode收到加密数之后再用私钥进行解密,并将解密数回传给datanode,datanode确认解密数无误之后就允许namenode进行连接了。这就是一个公钥认证过程,其间不需要用户手工输入密码。重要过程是将客户
8、端namenode公钥复制到datanode上。所有机器上生成密码对,所有节点上执行以下命令:ssh-keygen -t rsa Generating public/private rsa key pair.Enter file in which to save the key (/home/ hadoop /.ssh/id_rsa): 默认路径Enter passphrase (empty for no passphrase): 回车,空密码Enter same passphrase again: Your identification has been saved in /home/ ha
9、doop /.ssh/id_rsa.Your public key has been saved in /home/ hadoop /.ssh/id_rsa.pub.这将在/home/hadoop/.ssh/目录下生成一个私钥id_rsa和一个公钥id_rsa.pub。在namenode节点上做如下配置cp id_rsa.pub authorized_keys namenode的公钥使用SSH协议将namenode的公钥信息authorized_keys复制到所有DataNode的.ssh目录下。scp authorized_keys data节点ip地址:/home/hadoop/.ssh
10、这样配置过后,namenode可以无密码登录所有datanode,可以通过命令“ssh 节点ip地址”来验证。配置完毕,在namenode上执行“ssh 本机,所有数据节点”命令,因为ssh执行一次之后将不会再询问。2.1选择二:配置所有节点之间SSH无密码验证(0)原理节点A要实现无密码公钥认证连接到节点B上时,节点A是客户端,节点B是服务端,需要在客户端A上生成一个密钥对,包括一个公钥和一个私钥,而后将公钥复制到服务端B上。当客户端A通过ssh连接服务端B时,服务端B就会生成一个随机数并用客户端A的公钥对随机数进行加密,并发送给客户端A。客户端A收到加密数之后再用私钥进行解密,并将解密数回
11、传给B,B确认解密数无误之后就允许A进行连接了。这就是一个公钥认证过程,其间不需要用户手工输入密码。重要过程是将客户端A公钥复制到B上。因此如果要实现所有节点之间无密码公钥认证,则需要将所有节点的公钥都复制到所有节点上。(1)所有机器上生成密码对(a)所有节点用hadoop用户登陆,并执行以下命令,生成rsa密钥对:ssh-keygen -t rsa 这将在/home/hadoop/.ssh/目录下生成一个私钥id_rsa和一个公钥id_rsa.pub。(b)将所有datanode节点的公钥id_rsa.pub传送到namenode上:cp id_rsa.pub datanode01.id_r
12、sa.pubscp datanode01.id_rsa.pub namenode节点ip地址:/home/hadoop/.ssh .cp id_rsa.pub datanoden.id_rsa.pubscp datanoden.id_rsa.pub namenode节点ip地址:/home/hadoop/.ssh (c)namenode节点上综合所有公钥(包括自身)并传送到所有节点上cp id_rsa.pub authorized_keys 这是namenode自己的公钥cat datanode01.id_rsa.pub authorized_keys.cat datanode0n.id_rs
13、a.pub authorized_keys然后使用SSH协议将所有公钥信息authorized_keys复制到所有DataNode的.ssh目录下scp authorized_keys data节点ip地址:/home/hadoop/.ssh 这样配置过后,所有节点之间可以相互SSH无密码登陆,可以通过命令“ssh 节点ip地址”来验证。配置完毕,在namenode上执行“ssh 本机,所有数据节点”命令,因为ssh执行一次之后将不会再询问。3 JDK安装和Java环境变量配置3.1 安装 JDK 1.6root用户登陆,在Namenode节点上新建文件夹/usr/program,下载JDK安
14、装包jdk-6u13-linux-i586.bin,复制到目录/usr/ program下,在命令行进入该目录,执行命令“./ jdk-6u13-linux-i586.bin”,命令运行完毕,将在目录下生成文件夹jdk1.6.0_13,安装完毕。安装完成后,修改/usr/program目录拥有着为nutch用户,Chown -R nutch:nutch /usr/program/usr/ program目录需要复制到所有数据节点上。3.2 Java环境变量配置root用户登陆,命令行中执行命令”vi /etc/profile”,并加入以下内容,配置环境变量(注意/etc/profile这个文件
15、很重要,后面Hadoop的配置还会用到)。# set java environmentexport JAVA_HOME=/usr/program/jdk1.6.0_13/export JRE_HOME=/usr/program/jdk1.6.0_13/jreexport CLASSPATH=.:$JAVA_HOME/lib:$JAVA_HOME/jre/lib export PATH=$JAVA_HOME/bin:$JAVA_HOME/jre/bin:$PATH保存并退出,执行以下命令使配置生效chmod +x /etc/profilesource /etc/profile配置完毕,在命令行中
16、使用命令”java -version”可以判断是否成功。在hadoop用户下测试java version,一样成功。将Namenode上的/etc/profile复制到所有数据节点上。操作步骤如下:root用户登录namenode;执行命令:scp /etc/profile rootdatanode ip:/etc/profile4 Hadoop集群配置在namenode上执行:Hadoop用户登录。下载hadoop-0.19.1,将其解压到/usr/local/hadoop目录下,解压后目录形式是/usr/local/hadoop/hadoop-0.19.1。使用如下命令:tar zxvf
17、hadoop-0.19.1.tar.gz(1)配置Hadoop的配置文件 (a)配置hadoop-env.sh $ vi nutch-1.0/conf/hadoop-env.sh# set java environmentexport JAVA_HOME=/usr/program/jdk1.6.0_13/(b)配置conf/hadoop-site.xmlHadoop配置参数的含义请参考conf/Hadoop-default.xml。Hadoop-0.20之后的版本请分别配置core-site.xml,hdfs-site.xml和mapred-site.xml三个配置文件,配置方法即将下面had
18、oop-site.xml文件中的三块参数分别复制到三个文件当中。fs.default.namehdfs:/gc03vm12:9000HDFS的URI,文件系统:/namenode标识:端口号hadoop.tmp.dir/usr/local/hadoop/hadooptmp namenode上本地的hadoop临时文件夹 dfs.name.dir /usr/local/hadoop/hdfs/name namenode上存储hdfs名字空间元数据 dfs.data.dir /usr/local/hadoop/hdfs/data datanode上数据块的物理存储位置 dfs.replicatio
19、n 2副本个数,不配置默认是3,应小于datanode机器数量 mapred.job.trackergc03vm12:9001jobtracker标识:端口号,不是URI mapred.local.dir /usr/local/hadoop/mapred/local tasktracker上执行mapreduce程序时的本地目录 mapred.system.dir /tmp/hadoop/mapred/system 这个是hdfs中的目录,存储执行mr程序时的共享文件 (c)配置masters文件,加入namenode的主机名gc03vm12 (d)配置slaves文件, 加入所有datano
20、de的主机名gc04vm12gc04vm14(2)复制配置好的各文件到所有数据节点上。root用户下:scp /etc/hosts 数据节点ip地址:/etc/hostsscp /etc/profile 数据节点ip地址:/etc/profilescp /usr/program 数据节点ip地址:/usr/programnutch用户下:scp /usr/local/hadoop 数据节点ip地址: /usr/local/5 Hadoop集群启动Namenode执行:格式化namenode,格式化后在namenode生成了hdfs/name文件夹bin/hadoop namenode form
21、at启动hadoop所有进程,bin/start-all.sh(或者先后执行start-dfs.sh和start-mapreduce.sh)。可以通过以下启动日志看出,首先启动namenode,然后启动datanode1,datanode2,然后启动secondarynamenode。再启动jobtracker,然后启动tasktracker1,最后启动tasktracker2。启动hadoop成功后,在namenode中生成了hadooptmp文件夹,在datanode中生成了hdfs文件夹和mapred文件夹。namenode上用java自带的小工具jps查看进程# jps8383 Job
22、Tracker8733 Jps8312 SecondaryNameNode8174 NameNode每个datanode上查看进程# jps7636 DataNode7962 Jps7749 TaskTracker在namenode上查看集群状态bin/hadoop dfsadmin reportConfigured Capacity: 16030539776 (14.93 GB)Present Capacity: 7813902336 (7.28 GB)DFS Remaining: 7748620288 (7.22 GB)DFS Used: 65282048 (62.26 MB)DFS Us
23、ed%: 0.84%-Datanodes available: 2 (2 total, 0 dead)Name: 10.10.97.142:50010Decommission Status : NormalConfigured Capacity: 8015269888 (7.46 GB)DFS Used: 32641024 (31.13 MB)Non DFS Used: 4364853248 (4.07 GB)DFS Remaining: 3617775616(3.37 GB)DFS Used%: 0.41%DFS Remaining%: 45.14%Last contact: Thu May
24、 13 06:17:57 CST 2010Name: 10.10.97.144:50010Decommission Status : NormalConfigured Capacity: 8015269888 (7.46 GB)DFS Used: 32641024 (31.13 MB)Non DFS Used: 3851784192 (3.59 GB)DFS Remaining: 4130844672(3.85 GB)DFS Used%: 0.41%DFS Remaining%: 51.54%Last contact: Thu May 13 06:17:59 CST 2010Hadoop 的w
25、eb 方式查看:http:/ namenode ip地址:50070Hadoop查看工作情况: http:/ namenode ip地址:500306 Hadoop使用Hadoop有两个重要的模块:MapReduce和HDFS,HDFS是一个分布式文件系统,用于存储数据,MapReduce是一个编程框架,Hadoop中运行的程序均是MapReduce作业,一个作业分为若干个Map任务和Reduce任务。6.1 客户机与HDFS进行交互6.1.1 客户机配置可以查看HDFS中的数据,向HDFS中写入数据。(1)选择一台机器,该机器可以是Hadoop集群中的节点,也可以是集群之外的机器。下面说明在
26、集群之外的客户机上如何操作与HDFS交互,集群之内的节点省去配置过程。(2)集群之外的机器请保证和Hadoop集群是网络连通的,并且安装了Hadoop(解压安装包即可)并在conf/hadoop-site.xml中做了相关配置,至少配置如下: fs.default.name hdfs:/gc04vm12:9000 mapred.job.trackergc03vm12:9001jobtracker标识:端口号,不是URI(3)按照以上步骤配置完成后,即可在客户机的命令行中执行命令,查看HDFS文件系统。6.1.2 列出HDFS根目录/下的文件rootgc03vm12 nutch-1.0# bin
27、/hadoop dfs -ls /Found 3 itemsdrwxr-xr-x - hadoop supergroup 0 2010-05-21 00:42 /tmpdrwxr-xr-x - hadoop supergroup 0 2010-05-21 00:53 /userdrwxr-xr-x - hadoop supergroup 0 2010-05-21 00:55 /usr第一列是目录权限,第二列的hadoop是目录拥有者,第三列是组名,第4列是目录大小(单位是B),第5列是目录的绝对路径。这里表示/目录下有三个目录。这里的用户hadoop是安装hadoop的用户,是超级用户,相当于
28、Linux操作系统的root用户,组supergroup相当于root用户组。6.1.3 列出当前用户主目录下的文件Hadoop默认当前HDFS中的用户就是当前登录客户机的用户。rootgc03vm12 nutch-1.0# bin/hadoop dfs lsls: Cannot access .: No such file or directory. 提示不能访问时因为hdfs中没有/user/root目录。注意:这里的当前用户主目录是客户机中当前登录用户的主目录,即HDFS中的“/user/用户名”目录,由于当前是root用户登录,命令“bin/hadoop dfs ls”访问的是HDFS
29、中的“/user/root目录”。此时若/user/root目录不存在,则会出现上面的提示。由于HDFS中不存在root用户,所以客户机当前登录用户无法向HDFS中写入数据,因为对HDFS中的所有目录没有写权限,只有r读权限。要使当前用户能够向HDFS中写入数据,必须在HDFS中创建root用户并且创建相应目录,赋予相关权限。总之,HDFS的用户权限和Linux一样重要。6.1.4 HDFS用户管理创建HDFS用户需要使用hadoop用户登录客户机器,并且执行hadoop相关命令。由于Hadoop默认当前HDFS中的用户就是当前登录客户机的用户,所以当前HDFS用户即为Hadoop超级用户ha
30、doop。Hadoop似乎没有提供创建用户的命令,但要在HDFS中创建用户和用户组可以这样做。(i)Hadoop超级用户hadoop在hdfs中创建目录/user/root,即 bin/hadoop dfs -mkdir /user/root(ii)更改/user/root目录所属用户和组, 即bin/hadoop dfs -chown -R root:root /user/root,命令执行完毕Hadoop将默认创建有用户root,用户组root。注意:若此处没有指定组,则默认将root用户分配到supergroup组, bin/hadoop dfs -chown -R root /user
31、/root(ii)这样就相当于在hdfs中创建了用户root,组root。并且当前客户机的root用户对hdfs中的/user/root目录进行rwx。6.1.5 复制本地数据到HDFS中rootgc03vm12 nutch-1.0# bin/hadoop dfs copyFromLocal /local/x /user/root/执行以上命令即能将本地数据上传到HDFS中,上传的文件将会被分块,并且数据块将物理存储在集群数据节点的hadoop-site.xml文件中的dfs.data.dir参数指定的目录下,用户可以登录数据节点查看相应数据块。HDFS中一个文件对应若干数据块,如果文件小于块
32、大小(默认64M),则将会存储到一个块中,块大小即文件大小。若文件很大,则分为多个块存储。6.1.6 数据副本说明Hadoop-site.xml文件中的dfs.replication参数指定了数据块的副本数量。一个文件被分为若干数据块,其所有数据块副本的名字和元数据都是一样的,例如下图显示了上传一个目录(包含两个小文件)到HDFS后数据节点中数据块情况:图 节点一上的副本图 节点二上的副本6.1.7 hadoop-site.xml参数说明(1) hadoop.tmp.dir该参数默认值是“/tmp/hadoop-当前登录用户名”。它是本地路径,当第一次启动Hadoop集群进程时在namenod
33、e节点的本地创建该目录,其作用是存储相关临时文件。(2)mapred.system.dir 该参数默认值是$hadoop.tmp.dir/mapred/system,它所表示的目录是hdfs中的路径,是相对于dfs.default.name的路径,即它在hdfs中的绝对路径是$dfs.default.name/$mapred.system.dir。该参数指定的目录的作用是当作业运行时,存储作业相关文件,供tasktracker节点共享。一般hdfs系统中/目录下可以看到该参数指定的目录,如nutchgc04vm12 nutch-1.0$ bin/hadoop dfs -lsr /drwxr-x
34、r-x - nutch supergroup /tmpdrwxr-xr-x - nutch supergroup /tmp/hadoopdrwxr-xr-x - nutch supergroup /tmp/hadoop/mapreddrwx-wx-wx - nutch supergroup /tmp/hadoop/mapred/system (即此)其他参数参见hadoop-default.xml中的说明。6.1.8 HDFS中的路径首先请查阅资料,把握URI的概念。在HDFS中,例如下面这些形式均是URI(注意不是URL,URI概念比URL更广)。例如file:/,hdfs:/x/y/z,/
35、x/y/z,z。HDFS路径应该可以分为三种:绝对URI路径,即hdfs:/namenode:端口/xxxx/xxxx这种形式;HDFS绝对路径 ,例如/user或者/user,注意使用/或者/表示根目录,而不能使用/;HDFS相对路径,例如x,此路径往往是相对于当前用户主目录/user/用户名而言,例如x对应的HDFS绝对路径是/user/hadoop/x。Hadoop-site.xml中参数mapred.system.dir的值所指的路径是HDFS的绝对路径,它和fs.default.name参数一起构成了绝对URI,例如参数值/tmp/hadoop/mapred/system最终将对应的
36、是绝对URI:hdfs:/gc04vm12:9000/tmp/hadoop/mapred/system无论使用何种路径,均能查看HDFS中的数据,例如:6.1.8 Hadoop相关命令Hadoop提供一系列的命令,在bin中,例如bin/hadoop fs x;bin/hadoop namenode x等等。其中有些命令只能在namenode上执行。bin下还有一些控制脚本,例如start-all.sh、start-mapred.sh、start-dfs.sh等等。数据节点上运行start-all.sh将会只启动本节点上的进程,如datanode、tasktracker。6.2 客户机提交作业
37、到集群6.2.1 客户机配置可以在客户机上向Hadoop集群提交作业。(1)选择一台机器,该机器可以是Hadoop集群中的节点,也可以是集群之外的机器。下面说明在集群之外的客户机上如何向hadoop提交作业,集群之内的节点省去配置过程。(2)集群之外的机器请保证和Hadoop集群是网络连通的,并且安装了Hadoop(解压安装包即可)并在conf/hadoop-site.xml中做了相关配置,至少配置如下: fs.default.name hdfs:/gc04vm12:9000 mapred.job.trackergc03vm12:9001jobtracker标识:端口号,不是URI(3)按照以
38、上步骤配置完成后,即可在客户机的命令行中执行命令,向hadoop提交作业。6.2.2 一个测试例子WordCount计算输入文本中词语数量的程序WordCount在Hadoop主目录下的java程序包hadoop-0.19.1-examples.jar中,执行步骤如下:(1)上传数据到HDFS中bin/hadoop fs -mkdir mytestbin/hadoop fs -copyFromLocal /home/hadoop/mytest/input1bin/hadoop fs -copyFromLocal /home/hadoop/mytest/input2(2)执行命令,提交作业bin
39、/hadoop jar hadoop-0.19.1-examples.jar wordcount mytest/* output命令执行完毕,在页面http:/namenodeip:50030/中能够看到作业执行情况。(3)程序输出程序将统计mytest目录下的所有文本文件中词语的数量,并将结果输出到hdfs的output目录下的part-00000文件中。这里的output目录是程序生成的目录,程序运行前不可存在。执行以下命令可以查看结果。bin/hadoop fs -cat output/part-000006.2.3 编写Hadoop应用程序并在集群上运行这里介绍一个向HDFS中写入数据
40、的例子(注意不是MR程序)来说明编写Hadoop应用程序并放到集群上运行的步骤。(1)客户端编写应用程序并编译运行,进行测试。编写程序一般需要引入hadoop相关jar包或者直接使用hadoop整个程序包,相关代码见附录。(2)打包应用程序在eclipse中打包成jar文件存储到相应目录下,例如/hadoop/ jarseclipse/dfsOperator.jar。(3)上传数据到HDFSbin/hadoop fs copyFromLocal local dst本实例中不需要上传数据,一般的程序都涉及输入数据。(4)执行应用程序bin/hadoop jar x.jar jar包中主类名 输入
41、参数 输出参数 这里使用的命令是:bin/hadoop jar /jarseclipse/dfsOperator.jar DFSOperator6.2.4 三种模式下编译运行Hadoop应用程序集群是完全分布式环境,Hadoop的MR程序将以作业的形式提交到集群中运行。我们在客户端编写Hadoop应用程序时一般是在伪分布式模式或单击模式下进行编译,然后将编译无误的程序打成包提交到Hadoop集群中,当然我们仍可直接让程序在Hadoop集群中编译。(1)让Hadoop应用程序在直接在集群中编译将hadoop整个包导入eclipse中,配置hadoop-site.xml文件如下: fs.default.name hdfs:/gc04vm12:9000 m