阿里云-云小站(无限量代金券发放中)
【腾讯云】云服务器、云数据库、COS、CDN、短信等热卖云产品特惠抢购

Hadoop入门基础教程

209次阅读
没有评论

共计 59103 个字符,预计需要花费 148 分钟才能阅读完成。

本文以 K -Master 服务器基础环境配置为例分别演示用户配置、sudo 权限配置、网路配置、关闭防火墙、安装 JDK 工具等。用户需参照以下步骤完成 KVMSlave1~KVMSlave3 服务器的基础环境配置。

开发环境


硬件环境:CentOS 6.5 服务器 4 台(一台为 Master 节点,三台为 Slave 节点)
软件环境:Java 1.7.0_45、Hadoop-1.2.1

1、安装环境


硬件环境:CentOS 6.5 服务器 4 台(一台为 Master 节点,三台为 Slave 节点)

软件环境:Java 1.7.0_45、hadoop-1.2.1

2、用户配置


1)添加一个用户

[hadoop@K-Master hadoop]$ adduser hadoop                       #新建 hadoop 用户
[hadoop@K-Master hadoop]$ passwd hadoop                            #hadoop 用户设置密码

2)建工作组

[hadoop@K-Master hadoop]$ groupadd hadoop                      #新建 hadoop 工作组

3)给已有的用户增加工作组

[hadoop@K-Master hadoop]$ usermod -G hadoop hadoop

2、sudo 权限配置


1)新建个用户组 admin

[hadoop@K-Master hadoop]# groupadd admin

2)将已有用户添加到 admin 用户组

[hadoop@K-Master hadoop]# usermod -G admin,hadoop hadoop

3)赋予修改 /etc/sudoers 文件写权限

[hadoop@K-Master hadoop]# chmod u+w /etc/sudoers 

4)编辑 /etc/sudoers 文件

[hadoop@K-Master hadoop]# vi /etc/sudoers
缺省只有一条配置:root    ALL=(ALL) ALL 
在下边再加一条配置:%admin    ALL=(ALL) ALL

这样 admin 用户组就拥有了 sudo 权限,属于 admin 用户组的 hadoop 用户同样拥有了 sudo 权限。

5)编辑完成后降低权限

[hadoop@K-Master hadoop]$ chmod u-w /etc/sudoers

3、网络配置


1)配置 IP 地址
Hadoop 入门基础教程

详细配置信息如下所示:

[hadoop@K-Master hadoop]$ su hadoop                #切换为 hadoop 用户
[hadoop@K-Master hadoop]$ sudo vi /etc/sysconfig/network-scripts/ifcfg-eth0
HWADDR=06:8D:30:00:00:27
TYPE=Ethernet
BOOTPROTO=static
IPADDR=192.168.100.147
PREFIX=24
GATEWAY=192.168.100.1
DNS1=192.168.100.1
DEFROUTE=yes
IPV4_FAILURE_FATAL=yes
IPV6INIT=no
NAME=eth0
UUID=660a57a1-5edf-4cdd-b456-e7e1059aef11
ONBOOT=yes
LAST_CONNECT=1411901185

2)重启网络服务使网络设置生效

[hadoop@K-Master hadoop]$ sudo service network restart
Shutting down interface eth0:  Device state: 3 (disconnected)
                                                    [OK]
Shutting down loopback interface:                   [OK]
Bringing up loopback interface:                     [OK]
Bringing up interface eth0:  Active connection state: activated
Active connection path: /org/freedesktop/NetworkManager/ActiveConnection/1
                                                    [OK]

3)测试 IP 网络配置

通过 ifconfig 命令查看网络的 ip 地址,如下信息显示 eth0 无线网卡的 IP 地址为 192.168.100.147,与上述我们配置的 IP 地址吻合,表明 IP 地址配置成功。

[hadoop@K-Master ~]$ ifconfig
eth0  Link encap:Ethernet  HWaddr 06:8D:30:00:00:27
  inet addr:192.168.100.147  Bcast:192.168.100.255  Mask:255.255.255.0
  inet6 addr: fe80::48d:30ff:fe00:27/64 Scope:Link
  UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
  RX packets:59099169 errors:0 dropped:0 overruns:0 frame:0
  TX packets:30049168 errors:0 dropped:0 overruns:0 carrier:0
  collisions:0 txqueuelen:1000
  RX bytes:12477388443 (11.6 GiB)  TX bytes:8811418526 (8.2 GiB)

loLink encap:Local Loopback
  inet addr:127.0.0.1  Mask:255.0.0.0
  inet6 addr: ::1/128 Scope:Host
  UP LOOPBACK RUNNING  MTU:16436  Metric:1
  RX packets:2266013 errors:0 dropped:0 overruns:0 frame:0
  TX packets:2266013 errors:0 dropped:0 overruns:0 carrier:0
  collisions:0 txqueuelen:0
  RX bytes:666482169 (635.6 MiB)  TX bytes:666482169 (635.6 MiB)

4)修改 Host 主机名

[hadoop@K-Master hadoop]$ sudo vi /etc/sysconfig/network
NETWORKING=yes
NETWORKING_IPV6=no
HOSTNAME=Master
[hadoop@K-Master hadoop]$ sudo vi /etc/hosts
127.0.0.1               localhost.localdomain
::1                     hdirect30 hdirect30
192.168.100.201         K-Master

5)重启主机使得主机名生效

[hadoop@K-Master hadoop]$ sudo reboot

4、关闭防火墙


在启动前关闭集群中所有机器的防火墙,不然会出现 datanode 开后又自动关闭。

1)查看防火墙状态

[hadoop@K-Master ~]$ sudo service iptables status
iptables: Firewall is not running.

2)关闭防火墙

[hadoop@K-Master hadoop]$ sudo service iptables stop
iptables: Setting chains to policy ACCEPT: filter   [OK]
iptables: Flushing firewall rules:                  [OK]
iptables: Unloading modules:                        [OK]

3)永久关闭防火墙

[hadoop@K-Master hadoop]$ sudo chkconfig iptables off

4)关闭 SELINUX

[hadoop@K-Master hadoop]$ sudo vi /etc/selinux/config
SELINUX=disabled

5、安装 JDK 工具


1)解压

[hadoop@K-Master ~]$ scp hadoop@192.168.0.201:/home/hadoop/jdk-7u65-linux-x64.rpm .
[hadoop@K-Master ~]$ sudo rpm -ivh jdk-7u65-linux-x64.rpm

2)编辑”/etc/profile”文件,在后面添加 Java 的”JAVA_HOME”、”CLASSPATH”以及”PATH”内容。

[hadoop@K-Master ~]$ sudo vim /etc/profile
#JAVA
export JAVA_HOME=/usr/java/jdk1.7.0_65
export JRE_HOME=$JAVA_HOME/jre
export CLASSPATH=.:$CLASSPATH:$JAVA_HOME/lib:$JRE_HOME/lib
export PATH=$PATH:$JAVA_HOME/bin:$JRE_HOME/bin
#HADOOP
export HADOOP_HOME=/usr/hadoop-1.2.1
export PATH=$PATH:$HADOOP_HOME/bin
export HADOOP_HOME_WARN_SUPPRESS=1

3)使配置文件生效

[hadoop@K-Master ~]$ source /etc/profile

更多详情见请继续阅读下一页的精彩内容:http://www.linuxidc.com/Linux/2015-03/114669p2.htm

————————————– 分割线 ————————————–

Ubuntu14.04 下 Hadoop2.4.1 单机 / 伪分布式安装配置教程  http://www.linuxidc.com/Linux/2015-02/113487.htm

CentOS 安装和配置 Hadoop2.2.0  http://www.linuxidc.com/Linux/2014-01/94685.htm

Ubuntu 13.04 上搭建 Hadoop 环境 http://www.linuxidc.com/Linux/2013-06/86106.htm

Ubuntu 12.10 +Hadoop 1.2.1 版本集群配置 http://www.linuxidc.com/Linux/2013-09/90600.htm

Ubuntu 上搭建 Hadoop 环境(单机模式 + 伪分布模式)http://www.linuxidc.com/Linux/2013-01/77681.htm

Ubuntu 下 Hadoop 环境的配置 http://www.linuxidc.com/Linux/2012-11/74539.htm

单机版搭建 Hadoop 环境图文教程详解 http://www.linuxidc.com/Linux/2012-02/53927.htm

搭建 Hadoop 环境(在 Winodws 环境下用虚拟机虚拟两个 Ubuntu 系统进行搭建)http://www.linuxidc.com/Linux/2011-12/48894.htm

单机模式所需要的系统资源是最少的,这种安装模式下,Hadoop 的 core-site.xml、mapred-site.xml、hdfs-site.xml 配置文件均为空。默认情况下,官方 hadoop-1.2.1.tar.gz 文件默认使用的就是单机安装模式。当配置文件为空时,Hadoop 完全运行在本地,不与其他节点交互,也不使用 Hadoop 文件系统,不加载任何守护进程,该模式主要用于开发调试 MapReduce 应用程序的逻辑,不与任何守护进程交互进而避免复杂性。以 hadoop 用户远程登录 K -Master 服务器,在 K -Master 服务器上安装 Hadoop 过程如下。

开发环境


硬件环境:CentOS 6.5 服务器 4 台(一台为 Master 节点,三台为 Slave 节点)

软件环境:Java 1.7.0_45、hadoop-1.2.1

1、安装 Hadoop


1)以 hadoop 用户远程登录 K -Master 服务器,下载 hadoop-1.2.1.tar.gz,并将其拷贝到 K -Master 服务器的 /home/hadoop/ 目录下。

2)解压 hadoop-1.2.1.tar.gz

[hadoop@KVM-Master ~]$ su hadoop

[hadoop@KVM-Master ~]$ cd /usr

[hadoop@KVM-Master usr]$ sudo tar –zxvf  /home/hadoop/hadoop-1.2.1.tar.gz

3) 重命名 hadoop

[hadoop@KVM-Master usr]$ sudo mv hadoop-1.2.1/ hadoop/

4)将文件夹”hadoop”读权限分配给 hadoop 用户

很关键到一步,便于 hadoop 用户对该文件夹的文件拥有读写权限,不然后续 hadoop 启动后,无法在该文件夹创建文件和写入日志信息。

[hadoop@KVM-Master usr]$ sudo chown -R hadoop:hadoop /usr/hadoop

5)删除安装包

[hadoop@KVM-Master ~]$ rm –rf /home/hadoop/hadoop-1.2.1.tar.gz #删除”hadoop-1.2.1.tar.gz”安装包

2、配置环境变量


1)配置 /etc/profile

[hadoop@KVM-Master ~]$ sudo vi /etc/profile

#HADOOP

export HADOOP_HOME=/usr/hadoop

export PATH=$PATH:$HADOOP_HOME/bin 

export HADOOP_HOME_WARN_SUPPRESS=1 

2)使得配置文件在当前终端立即生效

[hadoop@KVM-Master ~] $source /etc/profile

3、启动 Hadoop


1)使用 start-al.sh 命令启动 hadoop

[hadoop@KVM-Master ~] $start-all.sh

2)使用 jps 查看启动是否成功

[hadoop@KVM-Master ~] $jps

jps

因为是单机模式,NameNode 和 JobTracker 等都没有启动,怎么知道安装是否成功了?

3)查看 HDFS 系统

[hadoop@KVM-Master ~] $ hadoop fs -ls /

通过 hadoop fs -ls / 命令查看 Hadoop HDFS 文件管理系统,显示的像 Linux 文件系统目录。若出现上述所示结果,表明 Hadoop 单机版安装成功。到目前为止,我们并没有对 Hadoop 的配置文件做任何修改,全是默认配置,即配置文件全为空,如下所示。

[hadoop@K-Master hadoop] vi conf/core-site.xml

<?xml version="1.0"?>

<?xml-stylesheet type="text/xsl" href="https://www.linuxidc.com/Linux/2015-03/configuration.xsl"?>



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



<configuration>



</configuration>

本文以 K -Master 服务器基础环境配置为例分别演示用户配置、sudo 权限配置、网路配置、关闭防火墙、安装 JDK 工具等。用户需参照以下步骤完成 KVMSlave1~KVMSlave3 服务器的基础环境配置。

开发环境


硬件环境:CentOS 6.5 服务器 4 台(一台为 Master 节点,三台为 Slave 节点)
软件环境:Java 1.7.0_45、Hadoop-1.2.1

1、安装环境


硬件环境:CentOS 6.5 服务器 4 台(一台为 Master 节点,三台为 Slave 节点)

软件环境:Java 1.7.0_45、hadoop-1.2.1

2、用户配置


1)添加一个用户

[hadoop@K-Master hadoop]$ adduser hadoop                       #新建 hadoop 用户
[hadoop@K-Master hadoop]$ passwd hadoop                            #hadoop 用户设置密码

2)建工作组

[hadoop@K-Master hadoop]$ groupadd hadoop                      #新建 hadoop 工作组

3)给已有的用户增加工作组

[hadoop@K-Master hadoop]$ usermod -G hadoop hadoop

2、sudo 权限配置


1)新建个用户组 admin

[hadoop@K-Master hadoop]# groupadd admin

2)将已有用户添加到 admin 用户组

[hadoop@K-Master hadoop]# usermod -G admin,hadoop hadoop

3)赋予修改 /etc/sudoers 文件写权限

[hadoop@K-Master hadoop]# chmod u+w /etc/sudoers 

4)编辑 /etc/sudoers 文件

[hadoop@K-Master hadoop]# vi /etc/sudoers
缺省只有一条配置:root    ALL=(ALL) ALL 
在下边再加一条配置:%admin    ALL=(ALL) ALL

这样 admin 用户组就拥有了 sudo 权限,属于 admin 用户组的 hadoop 用户同样拥有了 sudo 权限。

5)编辑完成后降低权限

[hadoop@K-Master hadoop]$ chmod u-w /etc/sudoers

3、网络配置


1)配置 IP 地址
Hadoop 入门基础教程

详细配置信息如下所示:

[hadoop@K-Master hadoop]$ su hadoop                #切换为 hadoop 用户
[hadoop@K-Master hadoop]$ sudo vi /etc/sysconfig/network-scripts/ifcfg-eth0
HWADDR=06:8D:30:00:00:27
TYPE=Ethernet
BOOTPROTO=static
IPADDR=192.168.100.147
PREFIX=24
GATEWAY=192.168.100.1
DNS1=192.168.100.1
DEFROUTE=yes
IPV4_FAILURE_FATAL=yes
IPV6INIT=no
NAME=eth0
UUID=660a57a1-5edf-4cdd-b456-e7e1059aef11
ONBOOT=yes
LAST_CONNECT=1411901185

2)重启网络服务使网络设置生效

[hadoop@K-Master hadoop]$ sudo service network restart
Shutting down interface eth0:  Device state: 3 (disconnected)
                                                    [OK]
Shutting down loopback interface:                   [OK]
Bringing up loopback interface:                     [OK]
Bringing up interface eth0:  Active connection state: activated
Active connection path: /org/freedesktop/NetworkManager/ActiveConnection/1
                                                    [OK]

3)测试 IP 网络配置

通过 ifconfig 命令查看网络的 ip 地址,如下信息显示 eth0 无线网卡的 IP 地址为 192.168.100.147,与上述我们配置的 IP 地址吻合,表明 IP 地址配置成功。

[hadoop@K-Master ~]$ ifconfig
eth0  Link encap:Ethernet  HWaddr 06:8D:30:00:00:27
  inet addr:192.168.100.147  Bcast:192.168.100.255  Mask:255.255.255.0
  inet6 addr: fe80::48d:30ff:fe00:27/64 Scope:Link
  UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
  RX packets:59099169 errors:0 dropped:0 overruns:0 frame:0
  TX packets:30049168 errors:0 dropped:0 overruns:0 carrier:0
  collisions:0 txqueuelen:1000
  RX bytes:12477388443 (11.6 GiB)  TX bytes:8811418526 (8.2 GiB)

loLink encap:Local Loopback
  inet addr:127.0.0.1  Mask:255.0.0.0
  inet6 addr: ::1/128 Scope:Host
  UP LOOPBACK RUNNING  MTU:16436  Metric:1
  RX packets:2266013 errors:0 dropped:0 overruns:0 frame:0
  TX packets:2266013 errors:0 dropped:0 overruns:0 carrier:0
  collisions:0 txqueuelen:0
  RX bytes:666482169 (635.6 MiB)  TX bytes:666482169 (635.6 MiB)

4)修改 Host 主机名

[hadoop@K-Master hadoop]$ sudo vi /etc/sysconfig/network
NETWORKING=yes
NETWORKING_IPV6=no
HOSTNAME=Master
[hadoop@K-Master hadoop]$ sudo vi /etc/hosts
127.0.0.1               localhost.localdomain
::1                     hdirect30 hdirect30
192.168.100.201         K-Master

5)重启主机使得主机名生效

[hadoop@K-Master hadoop]$ sudo reboot

4、关闭防火墙


在启动前关闭集群中所有机器的防火墙,不然会出现 datanode 开后又自动关闭。

1)查看防火墙状态

[hadoop@K-Master ~]$ sudo service iptables status
iptables: Firewall is not running.

2)关闭防火墙

[hadoop@K-Master hadoop]$ sudo service iptables stop
iptables: Setting chains to policy ACCEPT: filter   [OK]
iptables: Flushing firewall rules:                  [OK]
iptables: Unloading modules:                        [OK]

3)永久关闭防火墙

[hadoop@K-Master hadoop]$ sudo chkconfig iptables off

4)关闭 SELINUX

[hadoop@K-Master hadoop]$ sudo vi /etc/selinux/config
SELINUX=disabled

5、安装 JDK 工具


1)解压

[hadoop@K-Master ~]$ scp hadoop@192.168.0.201:/home/hadoop/jdk-7u65-linux-x64.rpm .
[hadoop@K-Master ~]$ sudo rpm -ivh jdk-7u65-linux-x64.rpm

2)编辑”/etc/profile”文件,在后面添加 Java 的”JAVA_HOME”、”CLASSPATH”以及”PATH”内容。

[hadoop@K-Master ~]$ sudo vim /etc/profile
#JAVA
export JAVA_HOME=/usr/java/jdk1.7.0_65
export JRE_HOME=$JAVA_HOME/jre
export CLASSPATH=.:$CLASSPATH:$JAVA_HOME/lib:$JRE_HOME/lib
export PATH=$PATH:$JAVA_HOME/bin:$JRE_HOME/bin
#HADOOP
export HADOOP_HOME=/usr/hadoop-1.2.1
export PATH=$PATH:$HADOOP_HOME/bin
export HADOOP_HOME_WARN_SUPPRESS=1

3)使配置文件生效

[hadoop@K-Master ~]$ source /etc/profile

更多详情见请继续阅读下一页的精彩内容:http://www.linuxidc.com/Linux/2015-03/114669p2.htm

————————————– 分割线 ————————————–

Ubuntu14.04 下 Hadoop2.4.1 单机 / 伪分布式安装配置教程  http://www.linuxidc.com/Linux/2015-02/113487.htm

CentOS 安装和配置 Hadoop2.2.0  http://www.linuxidc.com/Linux/2014-01/94685.htm

Ubuntu 13.04 上搭建 Hadoop 环境 http://www.linuxidc.com/Linux/2013-06/86106.htm

Ubuntu 12.10 +Hadoop 1.2.1 版本集群配置 http://www.linuxidc.com/Linux/2013-09/90600.htm

Ubuntu 上搭建 Hadoop 环境(单机模式 + 伪分布模式)http://www.linuxidc.com/Linux/2013-01/77681.htm

Ubuntu 下 Hadoop 环境的配置 http://www.linuxidc.com/Linux/2012-11/74539.htm

单机版搭建 Hadoop 环境图文教程详解 http://www.linuxidc.com/Linux/2012-02/53927.htm

搭建 Hadoop 环境(在 Winodws 环境下用虚拟机虚拟两个 Ubuntu 系统进行搭建)http://www.linuxidc.com/Linux/2011-12/48894.htm

伪分布式模式即单节点集群模式,所有的守护进程都运行在同一台机器上。这种模式下增加了代码调试功能,可以查看内存、HDFS 文件系统的输入 / 输出,以及与其他守护进程交互。以 Hadoop 用户远程登录 K -Master 服务器,在单机模式安装的基础上,我们增加对 core-site.xml、hdfs-site.xml、mapred-site.xml 核心文件的配置步骤。

开发环境


硬件环境:CentOS 6.5 服务器 4 台(一台为 Master 节点,三台为 Slave 节点)
软件环境:Java 1.7.0_45、hadoop-1.2.1

1、配置 Hadoop


1)配置 core-site.xml

修改 Hadoop 核心配置文件 /usr/hadoop/conf/core-site.xml,通过 fs.default.name 指定 NameNode 的 IP 地址和端口号,通过 hadoop.tmp.dir 指定 hadoop 数据存储的临时文件夹。

[hadoop@K-Master hadoop] vi conf/core-site.xml
<configuration>
    <property>
        <name>fs.default.name</name>
        <value>hdfs://K-Master:9000</value>
    </property>
    <property>
        <name>hadoop.tmp.dir</name>
        <value>/usr/hadoop/tmp</value>
    </property>
</configuration>

特别注意:如没有配置 hadoop.tmp.dir 参数,此时系统默认的临时目录为:/tmp/hadoo-hadoop。而这个目录在每次重启后都会被删除,必须重新执行 format 才行,否则会出错。

2)配置 hdfs-site.xml

修改 HDFS 核心配置文件 /usr/hadoop/conf/hdfs-site.xml,通过 dfs.replication 指定 HDFS 的备份因子为 1,通过 dfs.name.dir 指定 namenode 节点的文件存储目录,通过 dfs.data.dir 指定 datanode 节点的文件存储目录。

[hadoop@K-Master hadoop] vi conf/hdfs-site.xml
<configuration>
    <property>
        <name>dfs.replication</name>
        <value>1</value>
    </property>
    <property>
        <name>dfs.name.dir</name>
        <value>/usr/hadoop/hdfs/name</value>
    </property>
    <property>
        <name>dfs.data.dir</name>
        <value>/usr/hadoop/hdfs/data</value>
    </property>
</configuration>

2)配置 mapred-site.xml

修改 MapReduce 核心配置文件 /usr/hadoop/conf/mapred-site.xml,通过 mapred.job.tracker 属性指定 JobTracker 的地址和端口。

[hadoop@K-Master hadoop] vi conf/mapred-site.xml
<configuration>
    <property>
        <name>mapred.job.tracker</name>
        <value>http://K-Master:9001</value>
    </property>
</configuration>

2、格式化 HDFS 文件系统


格式化 HDFS 文件系统需要在 namenode 节点上通过 hadoop 用户执行,而且只需要执行一次,下次启动时不需要再格式化,直接启动 HDFS 文件管理系统和 MapReduce 服务即可。

[hadoop@K-Master ~]$ hadoop namenode -format
14/07/24 16:37:57 INFO namenode.NameNode: STARTUP_MSG: 
/************************************************************
STARTUP_MSG: Starting NameNode
STARTUP_MSG:   host = K-Master/192.168.100.147
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_65
********************a****************************************/
14/07/24 16:37:57 INFO util.GSet: Computing capacity for map BlocksMap
14/07/24 16:37:57 INFO util.GSet: VM type   = 64-bit
14/07/24 16:37:57 INFO util.GSet: 2.0% max memory = 932184064
14/07/24 16:37:57 INFO util.GSet: capacity  = 2^21 = 2097152 entries
14/07/24 16:37:57 INFO util.GSet: recommended=2097152, actual=2097152
14/07/24 16:37:58 INFO namenode.FSNamesystem: fsOwner=hadoop
14/07/24 16:37:58 INFO namenode.FSNamesystem: supergroup=supergroup
14/07/24 16:37:58 INFO namenode.FSNamesystem: isPermissionEnabled=true
14/07/24 16:37:58 INFO namenode.FSNamesystem: dfs.block.invalidate.limit=100
14/07/24 16:37:58 INFO namenode.FSNamesystem: isAccessTokenEnabled=false accessKeyUpdateInterval=0 min(s), accessTokenLifetime=0 min(s)
14/07/24 16:37:58 INFO namenode.FSEditLog: dfs.namenode.edits.toleration.length = 0
14/07/24 16:37:58 INFO namenode.NameNode: Caching file names occuring more than 10 times 
14/07/24 16:37:58 INFO common.Storage: Image file /usr/hadoop/hdfs/name/current/fsimage of size 112 bytes saved in 0 seconds.
14/07/24 16:37:59 INFO namenode.FSEditLog: closing edit log: position=4, editlog=/usr/hadoop/hdfs/name/current/edits
14/07/24 16:37:59 INFO namenode.FSEditLog: close success: truncate to 4, editlog=/usr/hadoop/hdfs/name/current/edits
14/07/24 16:37:59 INFO common.Storage: Storage directory /usr/hadoop/hdfs/name has been successfully formatted.
14/07/24 16:37:59 INFO namenode.NameNode: SHUTDOWN_MSG: 
/************************************************************
SHUTDOWN_MSG: Shutting down NameNode at K-Master/192.168.100.147
************************************************************/

3、启动 HDFS 文件管理系统


1)通过 start-dfs.sh 命令启动 HDFS 文件管理系统,启动后通过如下日志信息可以看到在 K -Master 服务器上分别启动了 namenode、datanode 和 secondarynamenode。

[hadoop@K-Master ~]$ start-dfs.sh
starting namenode, logging to /usr/hadoop/libexec/../logs/hadoop-hadoop-namenode-K-Master.out
K-Master: starting datanode, logging to /usr/hadoop/libexec/../logs/hadoop-hadoop-datanode- K-Master.out
K-Master: starting secondarynamenode, logging to /usr/hadoop/libexec/../logs/hadoop-hadoop-secondarynamenode-K-Master.out

2)在 K -Master 节点上查看启动进程

若打印如下日志信息,表明 K -Master 服务器上启动了 NameNode、SecondaryNameNode2、DataNode 服务进程,即 K -Master 服务器上 HDFS 文件管理系统启动成功。

[hadoop@K-Master ~]$ jps
6164 Jps
5971 NameNode
6108 SecondaryNameNode
1265 DataNode

4、启动 MapReduce


1)通过 start-mapred.sh 命令启动 MapReduce 分布式计算服务,启动后通过以下日志信息可以看到在 K -Master 服务器上启动了 jobtracker、tasktracker 进程。

[hadoop@K-Master ~]$ start-mapred.sh
starting jobtracker, logging to /usr/hadoop/libexec/../logs/hadoop-hadoop-jobtracker-K-Master.out
K-Master: starting tasktracker, logging to /usr/hadoop/libexec/../logs/hadoop-hadoop-tasktracker- K-Master.out

2)K-Master 节点上查看启动进程

若打印如下日志信息,表明 K -Master 服务器上新启动了 JobTracker、TaskTracker 服务进程,即 K -Master 服务器上 MapReduce 启动成功。

[hadoop@K-Master ~]$ jps
1342 NameNode
1726 Jps
1619 JobTracker
1480 SecondaryNameNode
1549 TaskTracker
1265 DataNode

完成上述 4 步,表明我们成功的完成了 Hadoop 伪分布式环境的部署,伪分布式模式也叫单节点集群模式,所有的守护进程都运行在同一台机器上,上述实验也证明了这一点,NameNode、SecondaryNameNode、DataNode、JobTracker、TaskTracker 所有的守护进程全部运行在 K -Master 节点之上。

上一篇我们完成了 Hadoop 伪分布式环境的搭建,伪分布式模式也叫单节点集群模式,NameNode、SecondaryNameNode、DataNode、JobTracker、TaskTracker 所有的守护进程全部运行在 K -Master 节点之上。在本篇 blog 我们将搭建完全分布式环境,运行 NameNode、SecondaryNameNode、JobTracker 守护进程在主节点上,运行 DataNode、TaskTracker 在从节点上。特别注意:在搭建 Hadoop 完全分布式环境前请确保完成了【Hadoop 入门基础教程】1、Hadoop 之服务器基础环境搭建。

开发环境


硬件环境:CentOS 6.5 服务器 4 台(一台为 Master 节点,三台为 Slave 节点)
软件环境:Java 1.7.0_45、hadoop-1.2.1

1、集群拓扑图


我们使用 4 台机器来搭建 Hadoop 完全分布式环境,4 台机器的拓扑图如下图所示:

Hadoop 入门基础教程

Hadoop 集群中每个节点的角色如下表所示:

Hadoop 入门基础教程

2、配置 SSH


  • 环境准备

下面以配置 K -Master 启动 SSH 服务为例进行演示,用户需参照下面步骤完成 KVMSlave1~KVMSlave3 三台子节点机器的 SSH 服务启动;

1)以 hadoop 用户远程登录 K -Master 服务器,启动 SSH 服务;

[hadoop@K-Master hadoop]$ sudo /etc/init.d/sshd start

2)设置开机启动:

[hadoop@K-Master hadoop]$ sudo chkconfig sshd on
  • 配置 K -Master 本机无密码登录

下面以配置 K -Master 本机无密码登录为例进行讲解,用户需参照下面步骤完成 KVMSlave1~KVMSlave3 三台子节点机器的本机无密码登录;

1)以 hadoop 用户远程登录 K -Master 服务器,在 K -Master 服务器上生成公钥和私钥密码对,密钥默认存储在”/home/hadoop/.ssh”目录下,生成公钥和私钥密码对时,无需输入密码,直接回车即可。

# 切换到 hadoop 用户,不能使用 root 用户生成密钥
[hadoop@K-Master hadoop]$ su hadoop
[hadoop@K-Master hadoop]$ cd /home/hadoop/
[hadoop@K-Master hadoop]$ ssh-keygen -t rsa -P ""

2)将公钥追加到”authorized_keys”文件

[hadoop@K-Master hadoop]$ cd /home/hadoop/
[hadoop@K-Master hadoop]$ cat .ssh/id_rsa.pub >> .ssh/authorized_keys

3)赋予权限

[hadoop@K-Master hadoop]$ chmod 600 .ssh/authorized_keys

4)验证本机能无密码访问

[hadoop@K-Master hadoop]$ ssh K-Master
  • 配置 K -Master 本机无密码登录 KVMSlave1~KVMSlave3

下面以 K -Master 无密码登录 KVMSlave1 为例进行讲解,用户需参照下面步骤完成 K -Master 无密码登录 KVMSlave2~KVMSlave3。

1)以 hadoop 用户远程登录 KVMSlave1 服务器,复制 K -Master 服务器的公钥”id_rsa.pub”到 KVMSlave1 服务器的”/home/hadoop/”目录下。

[hadoop@KVMSlave1 hadoop]$ cd /home/hadoop/
[hadoop@KVMSlave1 hadoop]$ scp hadoop@K-Master:/home/hadoop/.ssh/id_rsa.pub /home/hadoop/

2)将 K -Master 的公钥(/home/hadoop/id_rsa.pub)追加到 KVMSlave1 的 authorized_keys 中。

[hadoop@KVMSlave1 hadoop]$ cd /home/hadoop
[hadoop@KVMSlave1 hadoop]$ cat id_rsa.pub >> .ssh/authorized_keys
[hadoop@KVMSlave1 hadoop]$ rm -r /home/hadoop/id_rsa.pub

3)另外开启一个终端,远程登录 K -Master 服务器,在 K -Master 服务器测试通过 SSH 无密码登录 KVMSlave1。

[hadoop@K-Master hadoop]$ ssh KVMSlave1
  • 配置 KVMSlave1~KVMSlave3 本机无密码登录 K -Master

下面以 KVMSlave1 无密码登录 K -Master 为例进行讲解,用户需参照下面步骤完成 KVMSlave2~KVMSlave3 无密码登录 K -Master。

1)以 hadoop 用户远程登录 K -Master,复制 KVMSlave1 服务器的公钥”id_rsa.pub”到 KVMSlave1 服务器的”/home/hadoop/”目录下。

[hadoop@K-Master hadoop]$ scp hadoop@KVMSlave1:/home/hadoop/.ssh/id_rsa.pub /home/hadoop

2)将 KVMSlave1 的公钥(/home/hadoop/id_rsa.pub)追加到 K -Master 的 authorized_keys 中。

[hadoop@K-Master hadoop]$ cd /home/hadoop
[hadoop@K-Master hadoop]$ cat id_rsa.pub >> .ssh/authorized_keys
[hadoop@K-Master hadoop]$ rm –r /home/hadoop/id_rsa.pub

3)以 hadoop 用户远程登录 KVMSlave1 服务器,在 KVMSlave1 服务器测试通过 SSH 无密码登录 K -Master。

[hadoop@KVMSlave1 hadoop]$ ssh K-Master

3、安装 Hadoop


如果用户已经完成了 Hadoop 伪分布式环境搭建,建议删除 /usr/hadoop/ 安装环境,从零开始配置 Hadoop 完全分布式环境。

1)以 hadoop 用户远程登录 K -Master 服务器,下载 hadoop-1.2.1.tar.gz,并将其拷贝到 K -Master 服务器的 /home/hadoop/ 目录下。

2)解压 Hadoop 源文件

[hadoop@K-Master ~]$ su hadoop
[hadoop@K-Master ~]$ cd /usr
[hadoop@K-Master usr]$ sudo tar -zxvf  /home/hadoop/hadoop-1.2.1.tar.gz        // 将文件减压在当前路径

3)重命名 hadoop

[hadoop@K-Master usr]$ sudo mv hadoop-1.2.1/ hadoop/

4)设置 hadoop 文件夹的用户属组和用户组

很关键到一步,便于 hadoop 用户对该文件夹的文件拥有读写权限,不然后续 hadoop 启动后,无法在该文件夹创建文件和写入日志信息。

[hadoop@K-Master usr]$ sudo chown -R hadoop:hadoop /usr/hadoop

5)删除安装包

    [hadoop@K-Master ~]$ rm -rf  /home/hadoop/hadoop-1.2.1.tar.gz    #删除 "hadoop-1.2.1.tar.gz" 安装包

4、配置 K -Master 的 hadoop 环境


1)配置环境变量

[hadoop@K-Master ~]$ sudo vi /etc/profile
#HADOOP
export HADOOP_HOME=/usr/hadoop
export PATH=$PATH:$HADOOP_HOME/bin 
export HADOOP_HOME_WARN_SUPPRESS=1 

使得 hadoop 命令在当前终端立即生效;

[hadoop@K-Master ~] $source /etc/profile

2)配置 hadoop-env.sh

hadoop 环境是基于 JVM 虚拟机环境的,故需在 hadoop-env.sh 配置文件中指定 JDK 环境。修改 /usr/hadoop/conf/hadoop-env.sh 文件,添加如下 JDK 配置信息。

[hadoop@K-Master ~] cd /usr/hadoop/
[hadoop@K-Master hadoop] vi conf/hadoop-env.sh
export JAVA_HOME=/usr/java/jdk1.7.0_65

3)配置 core-site.xml

修改 Hadoop 核心配置文件 /usr/hadoop/conf/core-site.xml,通过 fs.default.name 指定 NameNode 的 IP 地址和端口号,通过 hadoop.tmp.dir 指定 hadoop 数据存储的临时文件夹。

[hadoop@K-Master hadoop] vi conf/core-site.xml
<configuration>
    <property>
        <name>fs.default.name</name>
        <value>hdfs://K-Master:9000</value>
    </property>
    <property>
        <name>hadoop.tmp.dir</name>
        <value>/usr/hadoop/tmp</value>
    </property>
</configuration>

特别注意:如没有配置 hadoop.tmp.dir 参数,此时系统默认的临时目录为:/tmp/hadoo-hadoop。而这个目录在每次重启后都会被删除,必须重新执行 format 才行,否则会出错。

4)配置 hdfs-site.xml

修改 HDFS 核心配置文件 /usr/hadoop/conf/hdfs-site.xml,通过 dfs.replication 指定 HDFS 的备份因子为 3,通过 dfs.name.dir 指定 namenode 节点的文件存储目录,通过 dfs.data.dir 指定 datanode 节点的文件存储目录。

[hadoop@K-Master hadoop] vi conf/hdfs-site.xml
<configuration>
    <property>
        <name>dfs.replication</name>
        <value>3</value>
    </property>
    <property>
        <name>dfs.name.dir</name>
        <value>/usr/hadoop/hdfs/name</value>
    </property>
    <property>
        <name>dfs.data.dir</name>
        <value>/usr/hadoop/hdfs/data</value>
    </property>
</configuration>

5)配置 mapred-site.xml

修改 MapReduce 核心配置文件 /usr/hadoop/conf/mapred-site.xml,通过 mapred.job.tracker 属性指定 JobTracker 的地址和端口。

[hadoop@K-Master hadoop] vi conf/mapred-site.xml
<configuration>
    <property>
        <name>mapred.job.tracker</name>
        <value>http://K-Master:9001</value>
    </property>
</configuration>

6)配置 masters 文件

修改 /user/hadoop/conf/masters 文件,该文件指定 namenode 节点所在的服务器机器。删除 localhost,添加 namenode 节点的主机名 K -Master;不建议使用 IP 地址,因为 IP 地址可能会变化,但是主机名一般不会变化。

[hadoop@K-Master hadoop] vi conf/masters
K-Master

7)配置 slaves 文件(Master 主机特有)

修改 /usr/hadoop/conf/slaves 文件,该文件指定哪些服务器节点是 datanode 节点。删除 locahost,添加所有 datanode 节点的主机名,如下所示。

[hadoop@K-Master hadoop] vi conf/slaves
KVMSlave1
KVMSlave2
KVMSlave3

5、配置 KVMSlave 的 hadoop 环境


下面以配置 KVMSlave1 的 hadoop 为例进行演示,用户需参照以下步骤完成其他 KVMSlave 服务器的配置。

1)以 hadoop 用户远程登录 KVMSlave1 服务器,拷贝 K -Master 主机的 hadoop 文件夹到本地 /usr/ 目录下;

[hadoop@KVMSlave1 ~]$ cd /usr/
[hadoop@KVMSlave1 usr]$ sudo scp -r hadoop@K-Master:/usr/hadoop/ .
[hadoop@KVMSlave1 usr]$ sudo chown -R hadoop:hadoop hadoop/
#slaves 文件内容删除,或者直接删除 slaves
[hadoop@KVMSlave1 usr]$ rm /usr/hadoop/conf/slaves

2)配置环境变量

[hadoop@KVMSlave1 ~]$ sudo vi /etc/profile
#HADOOP
export HADOOP_HOME=/usr/hadoop
export PATH=$PATH:$HADOOP_HOME/bin 
export HADOOP_HOME_WARN_SUPPRESS=1 

使得 hadoop 命令在当前终端立即生效;

[hadoop@KVMSlave1 ~]$ source /etc/profile

6、格式化 HDFS 文件系统


格式化 HDFS 文件系统需要在 namenode 节点上通过 hadoop 用户执行,而且只需要执行一次,下次启动时不需要��格式化,直接启动 HDFS 文件管理系统和 MapReduce 服务即可。

[hadoop@K-Master ~]$ hadoop namenode -format
14/07/24 16:37:57 INFO namenode.NameNode: STARTUP_MSG: 
/************************************************************
STARTUP_MSG: Starting NameNode
STARTUP_MSG:   host = K-Master/192.168.100.147
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_65
********************a****************************************/
14/07/24 16:37:57 INFO util.GSet: Computing capacity for map BlocksMap
14/07/24 16:37:57 INFO util.GSet: VM type   = 64-bit
14/07/24 16:37:57 INFO util.GSet: 2.0% max memory = 932184064
14/07/24 16:37:57 INFO util.GSet: capacity  = 2^21 = 2097152 entries
14/07/24 16:37:57 INFO util.GSet: recommended=2097152, actual=2097152
14/07/24 16:37:58 INFO namenode.FSNamesystem: fsOwner=hadoop
14/07/24 16:37:58 INFO namenode.FSNamesystem: supergroup=supergroup
14/07/24 16:37:58 INFO namenode.FSNamesystem: isPermissionEnabled=true
14/07/24 16:37:58 INFO namenode.FSNamesystem: dfs.block.invalidate.limit=100
14/07/24 16:37:58 INFO namenode.FSNamesystem: isAccessTokenEnabled=false accessKeyUpdateInterval=0 min(s), accessTokenLifetime=0 min(s)
14/07/24 16:37:58 INFO namenode.FSEditLog: dfs.namenode.edits.toleration.length = 0
14/07/24 16:37:58 INFO namenode.NameNode: Caching file names occuring more than 10 times 
14/07/24 16:37:58 INFO common.Storage: Image file /usr/hadoop/hdfs/name/current/fsimage of size 112 bytes saved in 0 seconds.
14/07/24 16:37:59 INFO namenode.FSEditLog: closing edit log: position=4, editlog=/usr/hadoop/hdfs/name/current/edits
14/07/24 16:37:59 INFO namenode.FSEditLog: close success: truncate to 4, editlog=/usr/hadoop/hdfs/name/current/edits
14/07/24 16:37:59 INFO common.Storage: Storage directory /usr/hadoop/hdfs/name has been successfully formatted.
14/07/24 16:37:59 INFO namenode.NameNode: SHUTDOWN_MSG: 
/************************************************************
SHUTDOWN_MSG: Shutting down NameNode at K-Master/192.168.100.147
************************************************************/

7、启动 HDFS 文件管理系统


1)通过 start-dfs.sh 命令启动 HDFS 文件管理系统,启动后通过如下日志信息可以看到分别启动了 namenode 节点(K-Master)、datanode 节点(KVMSlave1、KVMSlave2、KVMSlave3)和 secondarynamenode 节点(K-Master)。

[hadoop@K-Master ~]$ start-dfs.sh
starting namenode, logging to /usr/hadoop/libexec/../logs/hadoop-hadoop-namenode-K-Master.out
KVMSlave1: starting datanode, logging to /usr/hadoop/libexec/../logs/hadoop-hadoop-datanode-KVMSlave1.out
KVMSlave2: starting datanode, logging to /usr/hadoop/libexec/../logs/hadoop-hadoop-datanode-KVMSlave2.out
KVMSlave3: starting datanode, logging to /usr/hadoop/libexec/../logs/hadoop-hadoop-datanode-KVMSlave3.out
K-Master: starting secondarynamenode, logging to /usr/hadoop/libexec/../logs/hadoop-hadoop-secondarynamenode-K-Master.out

2)在 K -Master 节点上查看启动进程

若打印如下日志信息,表明 namenode 节点启动了 NameNode 和 SecondaryNameNode2 服务进程,即 namenode 节点 HDFS 文件管理系统启动成功。

[hadoop@K-Master ~]$ jps
6164 Jps
5971 NameNode
6108 SecondaryNameNode

3)在 KVMSlave1 节点上查看启动进程

以 hadoop 用户远程登录 KVMSlave1 服务器,通过 jps 命令查看启动进程。若打印如下日志信息,表明 datanode 节点启动了 DataNode 服务进程,即 KVMSlave1 节点 HDFS 文件管理系统启动成功,用户可在远程登录其他 datanode 节点上查看其 HDFS 文件管理系统启动是否成功。

[hadoop@KVMSlave1 ~]$ jps
1327 Jps
1265 DataNode

8、启动 MapReduce


1)通过 start-mapred.sh 命令启动 MapReduce 分布式计算服务,启动后通过以下日志信息可以看出在 namenode 节点上启动了 jobtracker 进程,分别在 datanode 节点(KVMSlave1、KVMSlave2、KVMSlave3)上启动了 tasktracker 进程。

[hadoop@K-Master ~]$ start-mapred.sh
starting jobtracker, logging to /usr/hadoop/libexec/../logs/hadoop-hadoop-jobtracker-K-Master.out
KVMSlave1: starting tasktracker, logging to /usr/hadoop/libexec/../logs/hadoop-hadoop-tasktracker-KVMSlave1.out
KVMSlave2: starting tasktracker, logging to /usr/hadoop/libexec/../logs/hadoop-hadoop-tasktracker-KVMSlave2.out
KVMSlave3: starting tasktracker, logging to /usr/hadoop/libexec/../logs/hadoop-hadoop-tasktracker-KVMSlave3.out

2)K-Master 节点上查看启动进程

若打印如下日志信息,表明 namenode 节点上新启动了 JobTracker 进程,即 namenode 节点的 JobTracker 启动成功。

[hadoop@K-Master ~]$ jps
1342 NameNode
1726 Jps
1619 JobTracker
1480 SecondaryNameNode

3)KVMSlave1 节点上查看启动进程

以 hadoop 用户远程登录 KVMSlave1 服务器,通过 jps 命令查看启动进程。若打印如下日志信息,表明 KVMSlave1 节点上新启动了 TaskTracker 进程,即 KVMSlave1 节点的 TaskTracker 启动成功。用户可远程登录其他的 datanode 节点上查看 TaskTracker 是否启动成功。

[hadoop@KVMSlave1 ~]$ jps
1549 TaskTracker
1265 DataNode
1618 Jps

9、命令查看 Hadoop 集群的状态


通过简单的 jps 命令虽然可以查看 HDFS 文件管理系统、MapReduce 服务是否启动成功,但是无法查看到 Hadoop 整个集群的运行状态。我们可以通过 hadoop dfsadmin -report 进行查看。用该命令可以快速定位出哪些节点挂掉了,HDFS 的容量以及使用了多少,以及每个节点的硬盘使用情况。

[hadoop@K-Master ~]$ hadoop dfsadmin -report
Configured Capacity: 238417846272 (222.04 GB)
Present Capacity: 219128426496 (204.08 GB)
DFS Remaining: 218227326976 (203.24 GB)
DFS Used: 901099520 (859.36 MB)
DFS Used%: 0.41%
Under replicated blocks: 72
Blocks with corrupt replicas: 0
Missing blocks: 0

-------------------------------------------------
Datanodes available: 3 (3 total, 0 dead)

Name: 192.168.100.144:50010
Decommission Status : Normal
Configured Capacity: 79472615424 (74.01 GB)
DFS Used: 300367872 (286.45 MB)
Non DFS Used: 6218309632 (5.79 GB)
DFS Remaining: 72953937920(67.94 GB)
DFS Used%: 0.38%
DFS Remaining%: 91.8%
Last contact: Tue Feb 03 16:50:00 CST 2015


Name: 192.168.100.148:50010
Decommission Status : Normal
Configured Capacity: 79472615424 (74.01 GB)
DFS Used: 300367872 (286.45 MB)
Non DFS Used: 6242603008 (5.81 GB)
DFS Remaining: 72929644544(67.92 GB)
DFS Used%: 0.38%
DFS Remaining%: 91.77%
Last contact: Tue Feb 03 16:49:59 CST 2015


Name: 192.168.100.146:50010
Decommission Status : Normal
Configured Capacity: 79472615424 (74.01 GB)
DFS Used: 300363776 (286.45 MB)
Non DFS Used: 6828507136 (6.36 GB)
DFS Remaining: 72343744512(67.38 GB)
DFS Used%: 0.38%
DFS Remaining%: 91.03%
Last contact: Tue Feb 03 16:50:00 CST 2015

单词计数是最简单也是最能体现 MapReduce 思想的程序之一,可以称为 MapReduce 版“Hello World”,该程序的完整代码可以在 Hadoop 安装包的 src/example 目录下找到。单词计数主要完成的功能:统计一系列文本文件中每个单词出现的次数,如下图所示。本 blog 将通过分析 WordCount 源码来帮助大家摸清 MapReduce 程序的基本结构和运行机制。

Hadoop 入门基础教程

开发环境


硬件环境:CentOS 6.5 服务器 4 台(一台为 Master 节点,三台为 Slave 节点)
软件环境:Java 1.7.0_45、hadoop-1.2.1

1、WordCount 的 Map 过程


Map 过程需要继承 org.apache.hadoop.mapreduce 包中 Mapper 类,并重写其 map 方法。Map 方法中的 value 值存储的是文本文件中的一行记录(以回车符为结束标记),而 key 值为该行的首字符相对于文本文件的首地址的偏移量。然后 StringTokenizer 类将每一行拆分成一个个的单词,并将

2、WordCount 的 Reduce 过程


Reduce 过程需要继承 org.apache.hadoop.mapreduce 包中的 Reduce 类,并重写其 reduce 方法。Reduce 方法的输入参数 key 为单个单词,而 values 是由各 Mapper 上对应单词的计数值所组成的列表,所以只要遍历 values 并求和,即可得到某个单词出现的总次数。
IntSumReducer 类的实现代码如下,详细源码请参考:WordCount\src\WordCount.java。

public static class IntSumReducer 
   extends Reducer<Text,IntWritable,Text,IntWritable> {private IntWritable result = new IntWritable();

    public void reduce(Text key, Iterable<IntWritable> values, Context context) throws IOException, InterruptedException {
      // 输入参数 key 为单个单词;
      // 输入参数 Iterable<IntWritable> values 为各个 Mapper 上对应单词的计数值所组成的列表。int sum = 0;
      for (IntWritable val : values) {// 遍历求和
        sum += val.get();}
      result.set(sum);
      context.write(key, result);// 输出求和后的 <key,value>
    }
}

3、WordCount 的驱动执行过程


在 MapReduce 中,由 Job 对象负责管理和运行一个计算任务,并通过 Job 的一些方法对任务的参数进行相关的设置。此处设置了使用 TokenizerMapper 完成 Map 过程和使用 IntSumReducer 完成 Combine 和 Reduce 过程。还设置了 Map 过程和 Reduce 过程的输出类型:key 的类型为 Text,value 的类型为 IntWritable。任务的输入和输出路径则由命令行参数指定,并由 FileInputFormat 和 FileOutputFormat 分别设定。完成相应任务的参数设定后,即可调用 job.waitForCompletion()方法执行任务。
驱动函数实现代码如下,详细源码请参考:WordCount\src\WordCount.java。

public static void main(String[] args) throws Exception {Configuration conf = new Configuration();
    String[] otherArgs = new GenericOptionsParser(conf, args).getRemainingArgs();
    if (otherArgs.length != 2) {System.err.println("Usage: wordcount <in> <out>");
      System.exit(2);
    }
    Job job = new Job(conf, "word count");
    job.setJarByClass(WordCount.class);
    // 设置 Mapper、Combiner、Reducer 方法
    job.setMapperClass(TokenizerMapper.class);
    job.setCombinerClass(IntSumReducer.class);
    job.setReducerClass(IntSumReducer.class);
    // 设置了 Map 过程和 Reduce 过程的输出类型,设置 key 的输出类型为 Text,value 的输出类型为 IntWritable;job.setOutputKeyClass(Text.class);
    job.setOutputValueClass(IntWritable.class);
    // 设置任务数据的输入、输出路径;FileInputFormat.addInputPath(job, new Path(otherArgs[0]));
    FileOutputFormat.setOutputPath(job, new Path(otherArgs[1]));
    // 执行 job 任务,执行成功后退出;System.exit(job.waitForCompletion(true) ? 0 : 1);
}

4、WordCount 的处理过程


如上所述给出了 WordCount 的设计思路及源码分析过程,但很多细节都未被提及,本节将根据 MapReduce 的处理工程,对 WordCount 进行更详细的讲解。详细的执行步骤如下:
1)将文件拆分成 splits,由于测试用的文件较小,所以每个文件为一个 split,并将文件按行分割形成 < key,value > 对,如图所示。这一步由 MapReduce 框架自动完成,其中偏移量(即 key 值)包括了回车符所占的字符数(Windows 和 Linux 环境下会不同)。

Hadoop 入门基础教程

2)将分割好的 < key,value> 对交给用户定义的 map 方法进行处理,生成新的 < key,value > 对,如图所示:

Hadoop 入门基础教程

3)得到 map 方法输出的 < key,value> 对后,Mapper 会将它们按照 key 值进行排序,并执行 Combine 过程,将 key 值相同的 value 值累加,得到 Mapper 的最终输出结果,如图所示:

Hadoop 入门基础教程

4)Reducer 先对从 Mapper 接收的数据进行排序,再交由用户自定义的 reducer 方法进行处理,得到新的 < key,value> 对,并作为 WordCount 的输出结果,如图所示:

Hadoop 入门基础教程

5、WordCount 的最小驱动


MapReduce 框架在幕后默默地完成了很多事情,如果不重写 map 和 reduce 方法,它会不会就此罢工了?下面设计一个“WordCount 最小驱动”MapReduce—LazyMapReduce,该类只对任务进行必要的初始化及输入 / 输出路径的设置,其余的参数(如输入 / 输出类型、map 方法、reduce 方法等)均保持默认状态。LazyMapReduce 的实现代码如下:

public class LazyMapReduce {public static void main(String[] args) throws Exception {Configuration conf = new Configuration();
    String[] otherArgs = new GenericOptionsParser(conf, args).getRemainingArgs();
    if (otherArgs.length != 2) {System.err.println("Usage: wordcount <in> <out>");
      System.exit(2);
    }
    Job job = new Job(conf, "LazyMapReduce");
        // 设置任务数据的输入、输出路径;FileInputFormat.addInputPath(job, new Path(otherArgs[0]));
    FileOutputFormat.setOutputPath(job, new Path(otherArgs[1]));
        // 执行 job 任务,执行成功后退出;System.exit(job.waitForCompletion(true) ? 0 : 1);
  }
}

可以看出在默认情况下,MapReduce 原封不动地将输入

6、部署运行


1)部署源码

# 设置工作环境
[hadoop@K-Master ~]$ mkdir -p /usr/hadoop/workspace/MapReduce
#部署源码
将 WordCount 文件夹拷贝到 /usr/hadoop/workspace/MapReduce/ 路径下;

… 你可以直接 下载 WordCount

—————————————— 分割线 ——————————————

免费下载地址在 http://linux.linuxidc.com/

用户名与密码都是www.linuxidc.com

具体下载目录在 /2015 年资料 / 3 月 / 8 日 /Hadoop 入门基础教程 /

下载方法见 http://www.linuxidc.com/Linux/2013-07/87684.htm

—————————————— 分割线 ——————————————

2)编译文件

在使用 javac 编译命令时,我们用到了两个参数:-classpath 指定编译该类所需要的核心包,- d 指定编译后生成的 class 文件的存放路径;最后的 WordCount.java 表示编译的对象是当前文件夹下的 WordCount.java 类。

[hadoop@K-Master ~]$ cd /usr/hadoop/workspace/MapReduce/WordCount
[hadoop@K-Master WordCount]$ javac -classpath /usr/hadoop/hadoop-core-1.2.1.jar:/usr/hadoop/lib/commons-cli-1.2.jar -d bin/ src/WordCount.java
#查看编译结果
[hadoop@K-Master WordCount]$ ls bin/ -la
总用量 12
drwxrwxr-x 2 hadoop hadoop  102 9 月  15 11:08 .
drwxrwxr-x 4 hadoop hadoop   69 9 月  15 10:55 ..
-rw-rw-r-- 1 hadoop hadoop 1830 9 月  15 11:08 WordCount.class
-rw-rw-r-- 1 hadoop hadoop 1739 9 月  15 11:08 WordCount$IntSumReducer.class
-rw-rw-r-- 1 hadoop hadoop 1736 9 月  15 11:08 WordCount$TokenizerMapper.class

3)打包 jar 文件

在使用 jar 命令进行打包 class 文件时,我们用到了两个参数:-cvf 表示打包 class 文件并显示详细的打包信息,- C 指定打包的对象;命令最后的“.”表示将打包生成的文件保存在当前目录下。

[hadoop@K-Master WordCount]$ jar -cvf WordCount.jar -C bin/ .
已添加清单
正在添加: WordCount$TokenizerMapper.class(输入 = 1736) (输出 = 754)(压缩了 56%)
正在添加: WordCount$IntSumReducer.class(输入 = 1739) (输出 = 74

特别注意:打包命令最后一个字符为“.”,表示将打包生成的文件 WordCount.jar 保存到当前文件夹下,输入命令时特别留心。

4)启动 Hadoop 集群

如果 HDFS 已经启动,则不需要执行以下命令,可通过 jps 命令查看 HDFS 是否已经启动

[hadoop@K-Master WordCount]$ start-dfs.sh      #启动 HDFS 文件系统
[hadoop@K-Master WordCount]$ start-mapred.sh       #启动 MapReducer 服务
[hadoop@K-Master WordCount]$ jps
5082 JobTracker
4899 SecondaryNameNode
9048 Jps
4735 NameNode

5)上传输入文件到 HDFS

在 MapReduce 中,一个准备提交执行的应用程序称为“作业(Job)”,Master 节点将对该 Job 划分成多个 task 运行于各计算节点上(Slave 节点),而 task 任务输入输出的数据均是基于 HDFS 分布式文件管理系统,故需要将输入数据上传到 HDFS 分布式文件管理系统之上,如下所示。

# 在 HDFS 上创建输入 / 输出文件夹
[hadoop@K-Master WordCount]$ hadoop fs -mkdir wordcount/input/ 
#传本地 file 中文件到集群的 input 目录下
[hadoop@K-Master WordCount]$ hadoop fs -put input/file0*.txt wordcount/input
#查看上传到 HDFS 输入文件夹中到文件
[hadoop@K-Master WordCount]$ hadoop fs -ls wordcount/input
Found 2 items
-rw-r--r--   1 hadoop supergroup 22 2014-07-12 19:50 /user/hadoop/wordcount/input/file01.txt
-rw-r--r--   1 hadoop supergroup 28 2014-07-12 19:50 /user/hadoop/wordcount/input/file02.txt

6)运行 Jar 文件

我们通过 hadoop jar 命令运行一个 job 任务,关于该命令各个参数的含义如下图所示:

Hadoop 入门基础教程

[hadoop@K-Master WordCount]$ hadoop jar WordCount.jar WordCount wordcount/input wordcount/output
14/07/12 22:06:42 INFO input.FileInputFormat: Total input paths to process : 2
14/07/12 22:06:42 INFO util.NativeCodeLoader: Loaded the native-hadoop library
14/07/12 22:06:42 WARN snappy.LoadSnappy: Snappy native library not loaded
14/07/12 22:06:42 INFO mapred.JobClient: Running job: job_201407121903_0004
14/07/12 22:06:43 INFO mapred.JobClient:  map 0% reduce 0%
14/07/12 22:06:53 INFO mapred.JobClient:  map 50% reduce 0%
14/07/12 22:06:55 INFO mapred.JobClient:  map 100% reduce 0%
14/07/12 22:07:03 INFO mapred.JobClient:  map 100% reduce 33%
14/07/12 22:07:05 INFO mapred.JobClient:  map 100% reduce 100%
14/07/12 22:07:07 INFO mapred.JobClient: Job complete: job_201407121903_0004
14/07/12 22:07:07 INFO mapred.JobClient: Counters: 29

7)查看运行结果

结果文件一般由三部分组成:
1) _SUCCESS 文件:表示 MapReduce 运行成功。
2) _logs 文件夹:存放运行 MapReduce 的日志。
3) Part-r-00000 文件:存放结果,也是默认生成的结果文件。
使用 hadoop fs -ls wordcount/output 命令查看输出结果目录,如下所示:

# 查看 FS 上 output 目录内容
[hadoop@K-Master WordCount]$ hadoop fs -ls wordcount/output
Found 3 items
-rw-r--r--   1 hadoop supergroup  0 2014-09-15 11:11 /user/hadoop/wordcount/output/_SUCCESS
drwxr-xr-x   - hadoop supergroup  0 2014-09-15 11:10 /user/hadoop/wordcount/output/_logs
-rw-r--r--   1 hadoop supergroup 41 2014-09-15 11:11 /user/hadoop/wordcount/output/part-r-00000
使用 hadoop fs –cat wordcount/output/part-r-00000 命令查看输出结果,如下所示:#查看结果输出文件内容
[hadoop@K-Master WordCount]$ hadoop fs -cat wordcount/output/part-r-00000
Bye     1
Goodbye 1
Hadoop  2
Hello       2
World   2

到这里,整个 MapReduce 的快速入门就结束了。本篇使用一个完整的案例,从开发到部署再到查看结果,让大家对 MapReduce 的基本使用有所了解。

本文主要通过输入文件中的 child 字段和 parent 字段进行单表关联查询,推导出哪些用户具有 child 与 grandparent 关系。

开发环境


硬件环境:CentOS 6.5 服务器 4 台(一台为 Master 节点,三台为 Slave 节点)
软件环境:Java 1.7.0_45、Hadoop-1.2.1

1、输入数据分析


输入文件数据示例:

child parent
Tom Jack 
Jack Alice
Jack Jesse

第 1 列表示 child,第 2 列表示 parent,我们需要根据 child 和 parent 的关系得出 child 和 grantparent 的关系。比如说 Tom 的 parent 是 Jack,Jack 的 parent 是 Alice 和 Jesse,由此我们可以得出 Tom 的 grantparent 是{Alice,Jesse}。

2、Map 过程


首先使用默认的 TextInputFormat 类对输入文件进行处理,得到文本中每行的偏移量及其内容。Map 过程首先将输入分割成 child 和 parent,然后正序输出一次作为右表,反序输出一次作为左表,需要注意的是在输出的 value 中必须加上左右表区别标志,其中左表标识符为 1,右表标识符为 2,如图所示。

Hadoop 入门基础教程

Map 端核心代码实现如下,详细源码请参考:SingletonTableJoin\src\com\zonesion\tablejoin\SingletonTableJoin.java。

@Override
protected void map(Object key, Text value, Context context)
        throws IOException, InterruptedException {String childName = new String();
    String parentName = new String();
    String relationType = new String();
    String line = value.toString();
    String[] values = line.split(" ");
    if(values.length >= 2){if(values[0].compareTo("child") != 0){childName = values[0];
            parentName = values[1];
            relationType = "1";
            context.write(new Text(parentName), new Text(relationType+""+childName));//<"Lucy","1 Tom">
            relationType = "2";
            context.write(new Text(childName), new Text(relationType+""+parentName));//<"Jone","2 Lucy">
        }
    }
}

3、Reduce 过程


Reduce 过程首先对输入 < key,values > 即 <”Lucy”,[“1 Tom”,”2 Mary”,”2 Ben”]> 的 values 值进行遍历获取到单元信息(例如”1 Tom”),然后将单元信息中的用户 ID(例如 Tom)按照左表、右表标识符分别存入到 grandChild 集合和 grandParent 集合,最后对 grandChild 集合和 grandParent 集合进行笛卡尔积运算得到 child 与 grandParent 的关系,并进行输出,如图所示。

Hadoop 入门基础教程

Reduce 端核心代码如下,详细源码请参考:SingletonTableJoin\src\com\zonesion\tablejoin\SingletonTableJoin.java。

public static class JoinReducer extends Reducer<Text, Text, Text, Text>{

    @Override
    protected void reduce(Text key, Iterable<Text> values,Context context)
            throws IOException, InterruptedException {List<String> grandChild = new ArrayList<String>();// 孙子
        List<String> grandParent = new ArrayList<String>();// 爷爷
        Iterator<Text> it = values.iterator();//["1 Tom","2 Mary","2 Ben"]
        while(it.hasNext()){String[] record = it.next().toString().split("");//"1 Tom"---[1,Tom]
            if(record.length == 0) continue;
            if(record[0].equals("1")){// 左表,取出 child 放入 grandchild
                grandChild.add(record[1]);
            }else if(record[0].equals("2")){// 右表,取出 parent 放入 grandParent
                grandParent.add(record[1]);
            }
        }
        //grandchild 和 grandparent 数组求笛卡尔积
        if(grandChild.size() != 0 && grandParent.size() != 0){for(int i=0;i<grandChild.size();i++){for(int j=0;j<grandParent.size();j++){context.write(new Text(grandChild.get(i)), new Text(grandParent.get(j)));
                }
            }
        }
    }
}

4、驱动实现


驱动实现核心代码如下,详细源码请参考:SingletonTableJoin\src\com\zonesion\tablejoin\SingletonTableJoin.java。

public static void main(String[] args) throws Exception {Configuration conf = new Configuration();
        String[] otherArgs = new GenericOptionsParser(conf,args).getRemainingArgs();
        if(otherArgs.length != 2){System.err.println("Usage: SingletonTableJoin <in> <out>");
        }
        Job job = new Job(conf,"SingletonTableJoin Job");
        job.setJarByClass(SingletonTableJoin.class);
        job.setMapperClass(JoinMapper.class);
        job.setReducerClass(JoinReducer.class);
        job.setOutputKeyClass(Text.class);
        job.setOutputValueClass(Text.class);
        FileInputFormat.addInputPath(job, new Path(otherArgs[0]));
        FileOutputFormat.setOutputPath(job, new Path(otherArgs[1]));
        System.exit(job.waitForCompletion(true) ? 0 : -1);
    }

5、部署运行


1)启动 Hadoop 集群

[hadoop@K-Master ~]$ start-dfs.sh
[hadoop@K-Master ~]$ start-mapred.sh
[hadoop@K-Master ~]$ jps
5283 SecondaryNameNode
5445 JobTracker
5578 Jps
5109 NameNode

2)部署源码

# 设置工作环境
[hadoop@K-Master ~]$ mkdir -p /usr/hadoop/workspace/MapReduce
#部署源码
将 SingletonTableJoin 文件夹拷贝到 /usr/hadoop/workspace/MapReduce/ 路径下;

… 你可以直接 下载 SingletonTableJoin

3)编译文件

# 切换工作目录
[hadoop@K-Master ~]$ cd /usr/hadoop/workspace/MapReduce/SingletonTableJoin
#编译文件
[hadoop@K-Master SingletonTableJoin]$ javac -classpath /usr/hadoop/hadoop-core-1.2.1.jar:/usr/hadoop/lib/commons-cli-1.2.jar -d bin src/com/zonesion/tablejoin/SingletonTableJoin.java
#查看编译文件
[hadoop@K-Master SingletonTableJoin]$ ls -la bin/com/zonesion/tablejoin/
总用量 12
drwxrwxr-x 2 hadoop hadoop  122 7 月  31 11:02 .
drwxrwxr-x 3 hadoop hadoop   22 7 月  31 11:02 ..
-rw-rw-r-- 1 hadoop hadoop 1856 7 月  31 11:02 SingletonTableJoin.class
-rw-rw-r-- 1 hadoop hadoop 2047 7 月  31 11:02 SingletonTableJoin$JoinMapper.class
-rw-rw-r-- 1 hadoop hadoop 2074 7 月  31 11:02 SingletonTableJoin$JoinReducer.class

4)打包 jar 文件

[hadoop@K-Master SingletonTableJoin]$ jar -cvf SingletonTableJoin.jar -C bin/ .
added manifest
adding: com/(in = 0) (out= 0)(stored 0%)
adding: com/zonesion/(in = 0) (out= 0)(stored 0%)
adding: com/zonesion/tablejoin/(in = 0) (out= 0)(stored 0%)
adding: com/zonesion/tablejoin/SingletonTableJoin$JoinReducer.class(in = 2217) (out= 1006)(deflated 54%)
adding: com/zonesion/tablejoin/SingletonTableJoin$JoinMapper.class(in = 1946) (out= 823)(deflated 57%)
adding: com/zonesion/tablejoin/SingletonTableJoin.class(in = 1856) (out= 955)(deflated 48%)

5)上传输入文件

[hadoop@K-Master SingletonTableJoin]$ hadoop fs -mkdir /user/hadoop/SingletonTableJoin/input/
[hadoop@K-Master SingletonTableJoin]$ hadoop fs -put input/file01.txt  /user/hadoop/SingletonTableJoin/input/
[hadoop@K-Master SingletonTableJoin]$ hadoop fs -ls /user/hadoop/SingletonTableJoin/input/ 
Found 1 items
-rw-r--r--   1 hadoop supergroup163 2014-07-31 11:08 /user/hadoop/SingletonTableJoin/input/file01.txt

6)运行 Jar 文件

[hadoop@K-Master SingletonTableJoin]$ hadoop jar SingletonTableJoin.jar com.zonesion.tablejoin.SingletonTableJoin SingletonTableJoin/input SingletonTableJoin/output

14/07/31 14:47:55 INFO input.FileInputFormat: Total input paths to process : 1
14/07/31 14:47:55 INFO util.NativeCodeLoader: Loaded the native-hadoop library
14/07/31 14:47:55 WARN snappy.LoadSnappy: Snappy native library not loaded
14/07/31 14:47:56 INFO mapred.JobClient: Running job: job_201407310921_0012
14/07/31 14:47:57 INFO mapred.JobClient:  map 0% reduce 0%
14/07/31 14:48:00 INFO mapred.JobClient:  map 100% reduce 0%
14/07/31 14:48:07 INFO mapred.JobClient:  map 100% reduce 33%
14/07/31 14:48:08 INFO mapred.JobClient:  map 100% reduce 100%
14/07/31 14:48:08 INFO mapred.JobClient: Job complete: job_201407310921_0012
.....

特别注意:在指定主类时,一定要使用完整包名 com.zonesion.tablejoin.SingletonTableJoin,不然提示找不到。

7)查看输出结果

[hadoop@K-Master SingletonTableJoin]$ hadoop fs -cat SingletonTableJoin/output/part-r-00000
Tom     Alice
Tom     Jesse
Jone    Alice
Jone    Jesse
Tom     Mary
Tom     Ben
Jone    Mary
Jone    Ben
Philip  Alice
Philip  Jesse
Mark    Alice
Mark    Jesse

我们都知道一个产品唯一对应一个单价,本案例将通过两种类型输入文件:product 类(产品)和 price 类(价格)进行一对一的关联查询,得到产品名(例如:手表)与产品价格(例如:$100)的关联信息。

开发环境


硬件环境:CentOS 6.5 服务器 4 台(一台为 Master 节点,三台为 Slave 节点)
软件环境:Java 1.7.0_45、Hadoop-1.2.1

1、Map 过程


首先使用默认的 TextInputFormat 类对输入文件进行处理,得到文本中每行的偏移量及其内容并存入

2、Reduce 过程


Reduce 过程首先对输入

3、驱动实现


驱动核心代码实现如下,详细源码请参考:ProductJoinPrice\src\com\zonesion\tablejoin\ProductJoinPrice.java。

    public static void main(String[] args) throws Exception {Configuration conf = new Configuration();
        String[] otherArgs = new GenericOptionsParser(conf,args).getRemainingArgs();
        if(otherArgs.length != 3){System.err.println("Usage:Join <productTableDir> <priceTableDir> <output>");
        }
        // 定义 Job
        Job job = new Job(conf,"join productTable and priceTable");
        // 定义输入文件路径:商品表 & 价格表
        FileInputFormat.addInputPath(job, new Path(otherArgs[0]));//<productTableDir>
        FileInputFormat.addInputPath(job, new Path(otherArgs[1]));//<priceTableDir>
        // 定义输出文件路径
        FileOutputFormat.setOutputPath(job, new Path(otherArgs[2]));//<output>
        // 设置 Jar 运行入口类和 Mapper 类和 Reducer 类
        job.setJarByClass(ProductJoinPrice.class);
        job.setMapperClass(MapperClass.class);
        job.setReducerClass(ReducerClass.class);
        // 设置输出文件的 key 和 value 类型
        job.setOutputKeyClass(Text.class);
        job.setOutputValueClass(Text.class);
        System.exit(job.waitForCompletion(true) ? 0 : -1);
    }

4、部署运行


1)启动 Hadoop 集群

[hadoop@K-Master ~]$ start-dfs.sh
[hadoop@K-Master ~]$ start-mapred.sh
[hadoop@K-Master ~]$ jps
5283 SecondaryNameNode
5445 JobTracker
5578 Jps
5109 NameNode

2)部署源码

# 设置工作环境
[hadoop@K-Master ~]$ mkdir -p /usr/hadoop/workspace/MapReduce
#部署源码
将 ProductJoinPrice 文件夹拷贝到 /usr/hadoop/workspace/MapReduce/ 路径下;

… 你可以直接 下载 ProductJoinPrice

3)编译文件

# 切换工作目录
[hadoop@K-Master ~]$ cd /usr/hadoop/workspace/MapReduce/ProductJoinPrice
#编译文件
[hadoop@K-Master ProductJoinPrice]$ javac -classpath /usr/hadoop/hadoop-core-1.2.1.jar:/usr/hadoop/lib/commons-cli-1.2.jar -d bin src/com/zonesion/tablejoin/ProductJoinPrice.java
[hadoop@K-Master ProductJoinPrice]$ ls bin/com/zonesion/tablejoin/ -la
总用量 12
drwxrwxr-x 2 hadoop hadoop  110 7 月  31 17:19 .
drwxrwxr-x 3 hadoop hadoop   22 7 月  31 17:19 ..
-rw-rw-r-- 1 hadoop hadoop 1770 7 月  31 17:39 ProductJoinPrice.class
-rw-rw-r-- 1 hadoop hadoop 2134 7 月  31 17:39 ProductJoinPrice$CommonReduce.class
-rw-rw-r-- 1 hadoop hadoop 2375 7 月  31 17:39 ProductJoinPrice$PreMapper.class

4)打包 jar 文件

[hadoop@K-Master ProductJoinPrice]$ jar -cvf ProductJoinPrice.jar -C bin/ .
added manifest
adding: com/(in = 0) (out= 0)(stored 0%)
adding: com/zonesion/(in = 0) (out= 0)(stored 0%)
adding: com/zonesion/tablejoin/(in = 0) (out= 0)(stored 0%)
adding: com/zonesion/tablejoin/ProductJoinPrice$MapperClass.class(in = 2277) (out= 967)(deflated 57%)
adding: com/zonesion/tablejoin/ProductJoinPrice.class(in = 1897) (out= 970)(deflated 48%)
adding: com/zonesion/tablejoin/ProductJoinPrice$ReducerClass.class(in = 1999) (out= 880)(deflated 55%)

5)上传输入文件

# 创建 product 输入文件夹
[hadoop@K-Master ProductJoinPrice]$ hadoop fs -mkdir ProductJoinPrice/input/product/
#创建 price 输入文件夹
[hadoop@K-Master ProductJoinPrice]$ hadoop fs -mkdir ProductJoinPrice/input/price/
#上传文件到 product 文件夹
[hadoop@K-Master ProductJoinPrice]$ hadoop fs -put input/product* ProductJoinPrice/input/product/
#上传文件到 price 文件夹
[hadoop@K-Master ProductJoinPrice]$ hadoop fs -put input/price* ProductJoinPrice/input/price/

6)运行 Jar 文件

[hadoop@K-Master ProductJoinPrice]$ hadoop jar ProductJoinPrice.jar com.zonesion.tablejoin.ProductJoinPrice ProductJoinPrice/input/product/ ProductJoinPrice/input/price/ ProductJoinPrice/output
14/08/01 09:32:53 INFO input.FileInputFormat: Total input paths to process : 4
14/08/01 09:32:53 INFO util.NativeCodeLoader: Loaded the native-hadoop library
14/08/01 09:32:53 WARN snappy.LoadSnappy: Snappy native library not loaded
14/08/01 09:32:54 INFO mapred.JobClient: Running job: job_201408010921_0004
14/08/01 09:32:55 INFO mapred.JobClient:  map 0% reduce 0%
14/08/01 09:32:57 INFO mapred.JobClient:  map 50% reduce 0%
14/08/01 09:32:59 INFO mapred.JobClient:  map 100% reduce 0%
14/08/01 09:33:06 INFO mapred.JobClient:  map 100% reduce 100%
14/08/01 09:33:06 INFO mapred.JobClient: Job complete: job_201408010921_0004
14/08/01 09:33:06 INFO mapred.JobClient: Counters: 29
......

7)查看输出结果

[hadoop@K-Master ProductJoinPrice]$ hadoop fs -ls ProductJoinPrice/output
Found 3 items
-rw-r--r--   1 hadoop supergroup   0 2014-08-01 09:33 /user/hadoop/ProductJoinPrice/output/_SUCCESS
drwxr-xr-x   - hadoop supergroup  0 2014-08-01 09:32 /user/hadoop/ProductJoinPrice/output/_logs
-rw-r--r--   1 hadoop supergroup   107 2014-08-01 09:33 /user/hadoop/ProductJoinPrice/output/part-r-00000
[hadoop@K-Master ProductJoinPrice]$ hadoop fs -cat ProductJoinPrice/output/part-r-00000
手表      $100
休闲帽 $200
移动硬盘    $300
u 盘      $900
三星手机    $800
联想笔记本   $2000
钱包      $100

我们都知道一个地址拥有着多家公司,本案例将通过两种类型输入文件:address 类(地址)和 company 类(公司)进行一对多的关联查询,得到地址名(例如:Beijing)与公司名(例如:Beijing JD、Beijing Red Star)的关联信息。

开发环境


硬件环境:CentOS 6.5 服务器 4 台(一台为 Master 节点,三台为 Slave 节点)
软件环境:Java 1.7.0_45、Hadoop-1.2.1

1、Map 过程


首先使用默认的 TextInputFormat 类对输入文件进行处理,得到文本中每行的偏移量及其内容并存入 < key,value> 例如 <0,”1:Beijing”>。Map 过程首先按照输入文件的类型不同对输入信息进行不同的处理,例如,对于 address 类型输入文件将 value 值(”1:Beijing”)处理成 <”1”,”address:Beijing”>,对于 company 类型输入文件将 value 值(”Beijing Red Star:1”)处理成 <”1”,”company:Beijing Red Star”>,如图所示:

Hadoop 入门基础教程

Map 端核心代码实现如下,详细源码请参考:CompanyJoinAddress\src\com\zonesion\tablejoin\CompanyJoinAddress.java。

public static class MapClass extends Mapper<LongWritable, Text, Text, Text>{

    @Override
    protected void map(LongWritable key, Text value,Context context)
            throws IOException, InterruptedException {Text addressId = new Text();
        Text info = new Text();
        String[] line = value.toString().split(":");// 获取文件的每一行数据,并以 ":" 分割
        String path = ((FileSplit) context.getInputSplit()).getPath().toString();
        if (line.length < 2) {return;}
        if (path.indexOf("company") >= 0) {// 处理 company 文件的 value 信息:"Beijing Red Star:1"
            addressId.set(line[1]);//"1"
            info.set("company" + ":" + line[0]);//"company:Beijing Red Star"
            context.write(addressId,info);//<key,value> --<"1","company:Beijing Red Star">
        } else if (path.indexOf("address") >= 0) {// 处理 adress 文件的 value 信息:"1:Beijing"
            addressId.set(line[0]);//"1"
            info.set("address" + ":" + line[1]);//"address:Beijing"
            context.write(addressId,info);//<key,value> --<"1","address:Beijing">
        }
    }
}

2、Reduce 过程


Reduce 过程首先对输入 < key,values> 即 <”1”,[“company:Beijing Red Star”,”company:Beijing JD”,”address:Beijing”]> 的 values 值进行遍历获取到单元信息 value(例如”company:Beijing Red Star”),然后根据 value 中的标识符(company 和 address)将公司名和地址名分别存入到 company 集合和 address 集合,最后对 company 集合和 address 集合进行笛卡尔积运算得到 company 与 address 的关系,并进行输出,如图所示。

Hadoop 入门基础教程

Reduce 端核心代码实现如下,详细源码请参考:CompanyJoinAddress\src\com\zonesion\tablejoin\CompanyJoinAddress.java。

public static class ReduceClass extends Reducer<Text, Text, Text, Text>{

    @Override
    protected void reduce(Text key, Iterable<Text> values,Context context)
            throws IOException, InterruptedException {List<String> companys = new ArrayList<String>();
        List<String> addresses = new ArrayList<String>();
//["company:Beijing Red Star","company:Beijing JD","address:Beijing"]
        Iterator<Text> it = values.iterator();
        while(it.hasNext()){String value = it.next().toString();//"company:Beijing Red Star"
            String[] result = value.split(":");
            if(result.length >= 2){if(result[0].equals("company")){companys.add(result[1]);
                }else if(result[0].equals("address")){addresses.add(result[1]);
                }
            }
        }
        // 求笛卡尔积
        if(0 != companys.size()&& 0 != addresses.size()){for(int i=0;i<companys.size();i++){for(int j=0;j<addresses.size();j++){context.write(new Text(companys.get(i)), new Text(addresses.get(j)));//<key,value>--<"Beijing JD","Beijing">
                }
            }
        }
    }
}

3、驱动实现


驱动核心代码实现如下,详细源码请参考:CompanyJoinAddress\src\com\zonesion\tablejoin\CompanyJoinAddress.java。

public static void main(String[] args) throws Exception {Configuration conf = new Configuration();
        String[] otherArgs = new GenericOptionsParser(conf, args).getRemainingArgs();
        if (otherArgs.length != 3) {System.err.println("Usage: company Join address <companyTableDir> <addressTableDir> <out>");
            System.exit(2);
        }
        Job job = new Job(conf, "company Join address");
        // 设置 Job 入口类
        job.setJarByClass(CompanyJoinAddress.class);
        // 设置 Map 和 Reduce 处理类
        job.setMapperClass(MapClass.class);
        job.setReducerClass(ReduceClass.class);
        // 设置输出类型
        job.setOutputKeyClass(Text.class);
        job.setOutputValueClass(Text.class);
        // 设置输入和输出目录
        FileInputFormat.addInputPath(job, new Path(otherArgs[0]));//companyTableDir
        FileInputFormat.addInputPath(job, new Path(otherArgs[1]));//addressTableDir
        FileOutputFormat.setOutputPath(job, new Path(otherArgs[2]));//out
        System.exit(job.waitForCompletion(true) ? 0 : 1);
    }

4、部署运行


1)启动 Hadoop 集群

[hadoop@K-Master ~]$ start-dfs.sh
[hadoop@K-Master ~]$ start-mapred.sh
[hadoop@K-Master ~]$ jps
5283 SecondaryNameNode
5445 JobTracker
5578 Jps
5109 NameNode

2)部署源码

# 设置工作环境
[hadoop@K-Master ~]$ mkdir -p /usr/hadoop/workspace/MapReduce
#部署源码
将 CompanyJoinAddress 文件夹拷贝到 /usr/hadoop/workspace/MapReduce/ 路径下;

… 你可以直接 下载 CompanyJoinAddress

3)编译文件

# 切换工作目录
[hadoop@K-Master ~]$ cd /usr/hadoop/workspace/MapReduce/CompanyJoinAddress
#编译文件
[hadoop@K-Master CompanyJoinAddress]$ javac -classpath /usr/hadoop/hadoop-core-1.2.1.jar:/usr/hadoop/lib/commons-cli-1.2.jar -d bin src/com/zonesion/tablejoin/CompanyJoinAddress.java 
[hadoop@K-Master CompanyJoinAddress]$ ls bin/com/zonesion/tablejoin/* -la
-rw-rw-r-- 1 hadoop hadoop 1909 8 月   1 10:29 bin/com/zonesion/tablejoin/CompanyJoinAddress.class
-rw-rw-r-- 1 hadoop hadoop 2199 8 月  1 10:29 bin/com/zonesion/tablejoin/CompanyJoinAddress$MapClass.class
-rw-rw-r-- 1 hadoop hadoop 2242 8 月   1 10:29 bin/com/zonesion/tablejoin/CompanyJoinAddress$ReduceClass.class

4)打包 jar 文件

[hadoop@K-Master CompanyJoinAddress]$ jar -cvf CompanyJoinAddress.jar -C bin/ .
added manifest
adding: com/(in = 0) (out= 0)(stored 0%)
adding: com/zonesion/(in = 0) (out= 0)(stored 0%)
adding: com/zonesion/tablejoin/(in = 0) (out= 0)(stored 0%)
adding: com/zonesion/tablejoin/CompanyJoinAddress$MapClass.class(in = 2273) (out= 951)(deflated 58%)
adding: com/zonesion/tablejoin/CompanyJoinAddress$ReduceClass.class(in = 2242) (out= 1029)(deflated 54%)
adding: com/zonesion/tablejoin/CompanyJoinAddress.class(in = 1909) (out= 983)(deflated 48%)

5)上传输入文件

# 创建 company 输入文件夹
[hadoop@K-Master CompanyJoinAddress]$ hadoop fs -mkdir CompanyJoinAddress/input/company/
#创建 address 输入文件夹
[hadoop@K-Master CompanyJoinAddress]$ hadoop fs -mkdir CompanyJoinAddress/input/address/
#上传文件到 company 输入文件夹
[hadoop@K-Master CompanyJoinAddress]$ hadoop fs -put input/company* CompanyJoinAddress/input/company/
#上传文件到 address 输入文件夹
[hadoop@K-Master CompanyJoinAddress]$ hadoop fs -put input/address* CompanyJoinAddress/input/address/

6)运行 Jar 文件

[hadoop@K-Master CompanyJoinAddress]$ hadoop jar CompanyJoinAddress.jar com.zonesion.tablejoin.CompanyJoinAddress CompanyJoinAddress/input/company/  CompanyJoinAddress/input/address/ CompanyJoinAddress/output
14/08/01 10:50:05 INFO input.FileInputFormat: Total input paths to process : 4
14/08/01 10:50:05 INFO util.NativeCodeLoader: Loaded the native-hadoop library
14/08/01 10:50:05 WARN snappy.LoadSnappy: Snappy native library not loaded
14/08/01 10:50:05 INFO mapred.JobClient: Running job: job_201408010921_0008
14/08/01 10:50:06 INFO mapred.JobClient:  map 0% reduce 0%
14/08/01 10:50:09 INFO mapred.JobClient:  map 50% reduce 0%
14/08/01 10:50:10 INFO mapred.JobClient:  map 100% reduce 0%
14/08/01 10:50:17 INFO mapred.JobClient:  map 100% reduce 100%
14/08/01 10:50:17 INFO mapred.JobClient: Job complete: job_201408010921_0008
14/08/01 10:50:17 INFO mapred.JobClient: Counters: 29
......

7)查看输出结果

[hadoop@K-Master CompanyJoinAddress]$ hadoop fs -ls CompanyJoinAddress/output
Found 3 items
-rw-r--r--   1 hadoop supergroup 0 2014-08-01 10:50 /user/hadoop/CompanyJoinAddress/output/_SUCCESS
drwxr-xr-x   - hadoop supergroup  0 2014-08-01 10:50 /user/hadoop/CompanyJoinAddress/output/_logs
-rw-r--r-- 1 hadoop supergroup 241 2014-08-01 10:50 /user/hadoop/CompanyJoinAddress/output/part-r-00000
[hadoop@K-Master CompanyJoinAddress]$ hadoop fs -cat CompanyJoinAddress/output/part-r-00000
Beijing Red Star        Beijing
Beijing Rising          Beijing
Back of Beijing     Beijing
Beijing JD          Beijing
xiaomi              Beijing
Guangzhou Honda     Guangzhou
Guangzhou Development Bank  Guangzhou
Shenzhen Thunder        Shenzhen
Tencent             Shenzhen
aiplay              hangzhou
huawei              wuhan

开发环境


硬件环境:CentOS 6.5 服务器 4 台(一台为 Master 节点,三台为 Slave 节点)
软件环境:Java 1.7.0_45、Hadoop-1.2.1

1、倒排索引


倒排索引是文档检索系统中最常用的数据结构,被广泛用于全文搜索引擎。它主要是用来存储某个单词(或词组)在一个文档或一组文档的存储位置的映射,即提供了一种根据内容来查找文档的方式。由于不是根据文档来确定文档所包含的内容,而是进行了相反的操作(根据关键字来查找文档),因而称为倒排索引(Inverted Index)。通常情况下,倒排索引由一个单词(词组)以及相关的文档列表(标示文档的 ID 号,或者是指定文档所在位置的 URI)组成,如下图所示:

Hadoop 入门基础教程

从上图可以看出,单词 1 出现在 {文档 1、文档 4、文档 13、……} 中,单词 2 出现在 {文档 3、文档 5、文档 15、…..} 中,而单词 3 出现在 {文档 1、文档 8、文档 20、….} 中,还需要给每个文档添加一个权值,用来指出每个文档与搜素内容相关的相关度,如下图所示:

Hadoop 入门基础教程

最常用的是使用词频作为权重,即记录单词在文档中出现的次数了。以英文为例,如下图所示,索引文件中的“MapReduce”一行表示:“MapReduce”这个单词在文本 T0 中出现过 1 次,T1 中出现过 1 次,T2 中出现过 2 次。当搜索条件为“MapReduce”、“is”、“simple”时,对应的集合为:{T0,T1,T2}∩{T0,T1}∩{T0,T1}={T0,T1},即文本 T0 和 T1 包含所要索引的单词,而且只有 T0 是连续的。

Hadoop 入门基础教程

2、Map 过程

首先使用默认的 TextInputFormat 类对输入文件进行处理,得到文本中每行的偏移量及其内容。显然,Map 过程首先必须分析输入的 < key,value> 对,得到倒排索引中需要的三个信息:单词、文档 URI 和词频,如下图所示。这里存在两个问题:第一,< key,value> 对只能有两个值,在不使用 Hadoop 自定义数据类型的情况下,需要根据情况将其中两个值合并成一个值,作为 key 或 value 值;第二,通过一个 Reduce 过程无法同时完成词频统计和文档列表,所以必须增加一个 Combine 过程完成词频统计。

Hadoop 入门基础教程

这里将单词和 URI 组成 Key 值(如“MapReduce :1.txt”),将词频作为 value,这样做的好处是可以利用 MapReduce 框架自带的 Map 端排序,将同一文档的相同单词的词频组成列表,传递给 Combine 过程,实现类似于 WordCount 的功能。
Map 过程核心代码实现如下,详细源码请参考:InvertedIndex\src\com\zonesion\hdfs\InvertedIndex.java。

public static class InvertedIndexMapper extends 
    Mapper<Object,Text,Object,Text>{private Text keyInfo = new Text();// 存储单词和 URI 的组合
    private  Text valueInfo = new Text();// 存储词频
    private FileSplit split;// 存储 Split 对象
    @Override
    public void map(Object key, Text value, Context context)
            throws IOException, InterruptedException {split = (FileSplit)context.getInputSplit();
        StringTokenizer itr = new StringTokenizer(value.toString());
        while(itr.hasMoreTokens()){
            //key 值由单词和 URI 组成
            keyInfo.set(itr.nextToken()+":"+split.getPath().toString());
            valueInfo.set("1");
            context.write(keyInfo, valueInfo);// 输出:<key,value>---<"MapReduce:1.txt",1>
        }
    }
}

3、Combine 过程

经过 map 方法处理之后,Combine 过程将 key 值相同的 value 值累加,得到一个单词在文档中的词频,如下图所示。如果直接将 Map 的输出结果作为 Reduce 过程的输入,在 Shuffle 过程时将面临一个问题:所有具有相同单词的记录(由单词、URI 和词频组成)应该交由同一个 Reduce 处理,但当前 key 值无法保证这一点,所以必须修改 key 值和 value 值。这次将单词作为 key 值,URI 和词频作为 value 值。这样做的好处是可以利用 MapReduce 框架默认的 HashPartitioner 类完成 Shuffle 过程,将相同单词的所有记录发送给同一个 Reducer 处理。

Hadoop 入门基础教程

Combine 过程核心代码实现如下,详细源码请参考:InvertedIndex\src\com\zonesion\hdfs\InvertedIndex.java。

public static class InvertedIndexCombiner 
    extends Reducer<Text, Text, Text, Text>{private Text info = new Text();
    @Override
    protected void reduce(Text key, Iterable<Text> values,Context context)
            throws IOException, InterruptedException {// 输入:<key,value>---<"MapReduce:1.txt",list(1,1,1,1)>
        int sum = 0;
        for(Text value : values){sum += Integer.parseInt(value.toString());
        }
        int splitIndex = key.toString().indexOf(":");
        info.set(key.toString().substring(splitIndex+1)+":"+sum);
        key.set(key.toString().substring(0,splitIndex));
        context.write(key, info);// 输出:<key,value>----<"Mapreduce","0.txt:2">
    }
}

4、Reduce 过程


经过上述两个过程后,Reduce 过程只需要将相同 key 值的 value 值组合成倒排索引文件所需的格式即可,剩下的事情就可以直接交给 MapReduce 框架处理了,如下图所示。

Hadoop 入门基础教程

Reduce 过程核心代码实现如下,详细源码请参考:InvertedIndex\src\com\zonesion\hdfs\InvertedIndex.java。

public static class InvertedIndexReducer 
    extends Reducer<Text, Text, Text, Text>{private Text result = new Text();
    @Override
    protected void reduce(Text key, Iterable<Text> values,Context context)
            throws IOException, InterruptedException {// 输入:<"MapReduce",list("0.txt:1","1.txt:1","2.txt:1")>
        String fileList = new String();
        for(Text value : values){//value="0.txt:1"
            fileList += value.toString()+";";}
        result.set(fileList);
        context.write(key, result);// 输出:<"MapReduce","0.txt:1,1.txt:1,2.txt:1">
    }
}

5、驱动实现


驱动核心代码实现如下,详细源码请参考:InvertedIndex\src\com\zonesion\hdfs\InvertedIndex.java。

public static void main(String[] args) throws Exception {Configuration conf = new Configuration();
    String[] otherArgs = new GenericOptionsParser(conf, args).getRemainingArgs();
    if (otherArgs.length != 2) {System.err.println("Usage: InvertedIndex <in> <out>");
      System.exit(2);
    }
    Job job = new Job(conf, "InvertedIndex");
    job.setJarByClass(InvertedIndex.class);
    // 设置 Mapper 类、Combiner 类、Reducer 类;job.setMapperClass(InvertedIndexMapper.class);
    job.setCombinerClass(InvertedIndexCombiner.class);
    job.setReducerClass(InvertedIndexReducer.class);
    // 设置了 Map 过程和 Reduce 过程的输出类型,设置 key、value 的输出类型为 Text;job.setOutputKeyClass(Text.class);
    job.setOutputValueClass(Text.class);
    // 设置任务数据的输入、输出路径;FileInputFormat.addInputPath(job, new Path(otherArgs[0]));
    FileOutputFormat.setOutputPath(job, new Path(otherArgs[1]));
    // 执行 job 任务,执行成功后退出;System.exit(job.waitForCompletion(true) ? 0 : 1);
}

6、部署运行


1)启动 Hadoop 集群

[hadoop@K-Master CompanyJoinAddress]$ start-dfs.sh
[hadoop@K-Master CompanyJoinAddress]$ start-mapred.sh
[hadoop@K-Master CompanyJoinAddress]$ jps
5283 SecondaryNameNode
5445 JobTracker
5578 Jps
5109 NameNode

2)部署源码

# 设置工作环境
[hadoop@K-Master ~]$ mkdir -p /usr/hadoop/workspace/MapReduce
#部署源码
将 InvertedIndex 文件夹拷贝到 /usr/hadoop/workspace/MapReduce/ 路径下;

… 你可以直接 下载 InvertedIndex

—————————————— 分割线 ——————————————

免费下载地址在 http://linux.linuxidc.com/

用户名与密码都是www.linuxidc.com

具体下载目录在 /2015 年资料 / 3 月 / 8 日 /Hadoop 入门基础教程 /

下载方法见 http://www.linuxidc.com/Linux/2013-07/87684.htm

—————————————— 分割线 ——————————————

3)编译文件

# 切换工作目录
[hadoop@K-Master ~]$ cd /usr/hadoop/workspace/MapReduce/InvertedIndex
#编译文件
[hadoop@K-Master InvertedIndex]$ javac -classpath /usr/hadoop/hadoop-core-1.2.1.jar:/usr/hadoop/lib/commons-cli-1.2.jar -d bin src/com/zonesion/hdfs/InvertedIndex.java
[hadoop@K-Master InvertedIndex]$ ls bin/com/zonesion/hdfs/ -la
总用量 20
drwxrwxr-x 2 hadoop hadoop 4096 9 月  18 17:09 .
drwxrwxr-x 3 hadoop hadoop   17 9 月  18 17:09 ..
-rw-rw-r-- 1 hadoop hadoop 1982 9 月  18 17:09 InvertedIndex.class
-rw-rw-r-- 1 hadoop hadoop 2173 9 月  18 17:09 InvertedIndex$InvertedIndexCombiner.class
-rw-rw-r-- 1 hadoop hadoop 2103 9 月  18 17:09 InvertedIndex$InvertedIndexMapper.class
-rw-rw-r-- 1 hadoop hadoop 1931 9 月  18 17:09 InvertedIndex$InvertedIndexReducer.class

4)打包 jar 文件

[hadoop@K-Master InvertedIndex]$ jar -cvf InvertedIndex.jar -C bin/ .
已添加清单
正在添加: com/(输入 = 0) (输出 = 0)(存储了 0%)
正在添加: com/zonesion/(输入 = 0) (输出 = 0)(存储了 0%)
正在添加: com/zonesion/hdfs/(输入 = 0) (输出 = 0)(存储了 0%)
正在添加: com/zonesion/hdfs/InvertedIndex$InvertedIndexMapper.class(输入 = 2103) (输出 = 921)(压缩了 56%)
正在添加: com/zonesion/hdfs/InvertedIndex$InvertedIndexCombiner.class(输入 = 2173) (输出 = 944)(压缩了 56%)
正在添加: com/zonesion/hdfs/InvertedIndex$InvertedIndexReducer.class(输入 = 1931) (输出 = 830)(压缩了 57%)
正在添加: com/zonesion/hdfs/InvertedIndex.class(输入 = 1982) (输出 = 1002)(压缩了 49%)

5)上传输入文件

# 创建 InvertedIndex/input/ 输入文件夹
[hadoop@K-Master InvertedIndex]$ hadoop fs -mkdir InvertedIndex/input/
#上传文件到 InvertedIndex/input/ 输入文件夹
[hadoop@K-Master InvertedIndex]$ hadoop fs -put input/*.txt /user/hadoop/InvertedIndex/input
#验证上传文件是否成功
[hadoop@K-Master InvertedIndex]$ hadoop fs -ls /user/hadoop/InvertedIndex/input
Found 3 items
-rw-r--r--   1 hadoop supergroup 20 2014-09-18 17:12 /user/hadoop/InvertedIndex/input/0.txt
-rw-r--r--   1 hadoop supergroup 32 2014-09-18 17:12 /user/hadoop/InvertedIndex/input/1.txt
-rw-r--r--   1 hadoop supergroup 30 2014-09-18 17:12 /user/hadoop/InvertedIndex/input/2.txt

6)运行 Jar 文件

[hadoop@K-Master InvertedIndex]$ hadoop jar InvertedIndex.jar com.zonesion.hdfs.InvertedIndex InvertedIndex/input InvertedIndex/output
14/09/18 17:16:40 INFO input.FileInputFormat: Total input paths to process : 3
14/09/18 17:16:40 INFO util.NativeCodeLoader: Loaded the native-hadoop library
14/09/18 17:16:40 WARN snappy.LoadSnappy: Snappy native library not loaded
14/09/18 17:16:41 INFO mapred.JobClient: Running job: job_201409150922_0003
14/09/18 17:16:42 INFO mapred.JobClient:  map 0% reduce 0%
14/09/18 17:16:45 INFO mapred.JobClient:  map 100% reduce 0%
14/09/18 17:16:51 INFO mapred.JobClient:  map 100% reduce 33%
14/09/18 17:16:53 INFO mapred.JobClient:  map 100% reduce 100%
14/09/18 17:16:53 INFO mapred.JobClient: Job complete: job_201409150922_0003
14/09/18 17:16:53 INFO mapred.JobClient: Counters: 29
......

7)查看输出结果

# 查看 HDFS 上 output 目录内容
[hadoop@K-Master InvertedIndex]$ hadoop fs -ls /user/hadoop/InvertedIndex/output
Found 3 items
-rw-r--r--   1 hadoop supergroup  0 2014-07-21 15:31 /user/hadoop/InvertedIndex/output/_SUCCESS
drwxr-xr-x   - hadoop supergroup  0 2014-07-21 15:30 /user/hadoop/InvertedIndex/output/_logs
-rw-r--r--   1 hadoop supergroup665 2014-07-21 15:31 /user/hadoop/InvertedIndex/output/part-r-00000
#查看结果输出文件内容
[hadoop@K-Master InvertedIndex]$ hadoop fs -cat /user/hadoop/InvertedIndex/output/part-r-00000
Hello           hdfs://Master:9000/user/hadoop/InvertedIndex/input/2.txt:1;
MapReduce   hdfs://Master:9000/user/hadoop/InvertedIndex/input/2.txt:2;hdfs://Master:9000/user/hadoop/InvertedIndex/input/1.txt:1;hdfs://Master:9000/user/hadoop/InvertedIndex/input/0.txt:1;
Powerful    hdfs://Master:9000/user/hadoop/InvertedIndex/input/1.txt:1;
bye         hdfs://Master:9000/user/hadoop/InvertedIndex/input/2.txt:1;
is          hdfs://Master:9000/user/hadoop/InvertedIndex/input/0.txt:1;hdfs://Master:9000/user/hadoop/InvertedIndex/input/1.txt:2;
simple      hdfs://Master:9000/user/hadoop/InvertedIndex/input/1.txt:1;hdfs://Master:9000/user/hadoop/InvertedIndex/input/0.txt:1;

 

更多 Hadoop 相关信息见Hadoop 专题页面 http://www.linuxidc.com/topicnews.aspx?tid=13

正文完
星哥玩云-微信公众号
post-qrcode
 0
星锅
版权声明:本站原创文章,由 星锅 于2022-01-20发表,共计59103字。
转载说明:除特殊说明外本站文章皆由CC-4.0协议发布,转载请注明出处。
【腾讯云】推广者专属福利,新客户无门槛领取总价值高达2860元代金券,每种代金券限量500张,先到先得。
阿里云-最新活动爆款每日限量供应
评论(没有评论)
验证码
【腾讯云】云服务器、云数据库、COS、CDN、短信等云产品特惠热卖中