摘要:尽管 Hadoop 是一些大型搜索引擎数据缩减功能的核心部分,但是它实际上是一个分布式数据处理框架。搜索引擎需要收集数据,而且是数量极大的数据。作为分布式框架,Hadoop 让许多应用程序能够受益于并行数据处理。
导读:本文是嵌入式固件架构师M. Tim Jones所撰写的,次文是讨论 Hadoop 的系列中的第一篇,主要介绍Hadoop框架,包括 Hadoop 文件系统 (HDFS) 等基本元素和常用的节点类型。学习如何安装和配置单节点 Hadoop 集群,然后研究 MapReduce 应用程序。最后,学习使用核心 Web 界面监视和管理 Hadoop 的方法。
初始设置
对于本文中的示例,我们使用 Cloudera Hadoop 发行版。Cloudera 提供对各种 Linux 发行版的支持,所以很适合初学者。(本文假设您的系统上已经安装了 Java(至少是 1.6 版)和 cURL。)
因为我运行 Ubuntu(Intrepid 版),所以使用 apt 实用程序获取 Hadoop 发行版。这个过程非常简单,我可以获取二进制包,而不需要下载并构建源代码。首先,告诉 apt Cloudera 站点的信息。然后,在 /etc/apt/sources.list.d/cloudera.list 中创建一个新文件并添加以下文本:
deb http://archive.cloudera.com/debian intrepid-cdh3 contrib deb-src http://archive.cloudera.com/debian intrepid-cdh3 contrib |
如果您运行 Jaunty 或其他版本,只需把 intrepid 替换为您的版本名(当前支持 Hardy、Intrepid、Jaunty、Karmic 和 Lenny)。
接下来,从 Cloudera 获取 apt-key 以检查下载的包:
$ curl -s http://archive.cloudera.com/debian/archive.key | \ sudo apt-key add - sudo apt-get update |
然后,安装采用伪分布式配置的 Hadoop(所有 Hadoop 守护进程在同一个主机上运行):
$ sudo apt-get install hadoop-0.20-conf-pseudo $ |
注意,这个配置大约 23MB(不包括 apt 可能下载的其他包)。这个配置非常适合体验 Hadoop 以及了解它的元素和界面。
最后,我设置了不需要密码的 SSH。如果打算使用 ssh localhost 并请求密码,就需要执行以下步骤。我假设这是专用的 Hadoop 机器,因为这个步骤对安全性有影响(见清单 1)。
清单 1. 设置不需要密码的 SSH
$ sudo su - # ssh-keygen -t dsa -P '' -f ~/.ssh/id_dsa # cat ~/.ssh/id_dsa.pub >> ~/.ssh/authorized_keys |
最后,需要确保主机上有供 datanode使用的足够存储空间(缓存)。存储空间不足会导致系统表现异常(比如出现无法把数据复制到节点的错误)。
启动 Hadoop
现在可以启动 Hadoop 了,这实际上要启动每个 Hadoop 守护进程。但是,首先使用 hadoop 命令对 Hadoop File System (HDFS) 进行格式化。hadoop 命令有许多用途,稍后讨论其中一部分。
首先,请求 namenode 对 DFS 文件系统进行格式化。在安装过程中完成了这个步骤,但是了解是否需要生成干净的文件系统是有用的。
# hadoop-0.20 namenode -format |
在确认请求之后,文件系统进行格式化并返回一些信息。接下来,启动 Hadoop 守护进程。Hadoop 在这个伪分布式配置中启动 5 个守护进程:namenode、secondarynamenode、datanode、jobtracker 和 tasktracker。在启动每个守护进程时,会看到一些相关信息(指出存储日志的位置)。每个守护进程都在后台运行。图 1 说明完成启动之后伪分布式配置的架构。
图 1. 伪分布式 Hadoop 配置
Hadoop 提供一些简化启动的辅助工具。这些工具分为启动(比如 start-dfs)和停止(比如 stop-dfs)两类。下面的简单脚本说明如何启动 Hadoop 节点:
# /usr/lib/hadoop-0.20/bin/start-dfs.sh # /usr/lib/hadoop-0.20/bin/start-mapred.sh # |
要想检查守护进程是否正在运行,可以使用 jps 命令(这是用于 JVM 进程的 ps 实用程序)。这个命令列出 5 个守护进程及其进程标识符。
既然 Hadoop 守护进程已经在运行了,现在看看每个守护进程在 Hadoop 框架中的作用。namenode 是 Hadoop 中的主服务器,它管理文件系统名称空间和对集群中存储的文件的访问。还有一个 secondary namenode,它不是 namenode 的冗余守护进程,而是提供周期检查点和清理任务。在每个 Hadoop 集群中可以找到一个 namenode 和一个 secondary namenode。
datanode 管理连接到节点的存储(一个集群中可以有多个节点)。每个存储数据的节点运行一个 datanode 守护进程。
最后,每个集群有一个 jobtracker,它负责调度 datanode 上的工作。每个 datanode 有一个 tasktracker,它们执行实际工作。jobtracker 和 tasktracker 采用主-从形式,jobtracker 跨 datanode 分发工作,而 tasktracker 执行任务。jobtracker 还检查请求的工作,如果一个 datanode 由于某种原因失败,jobtracker 会重新调度以前的任务。
在这个简单的配置中,所有节点都驻留在同一个主机上(见 图 1)。但是,通过前面的讨论很容易看出 Hadoop 如何提供并行处理。尽管架构很简单,但是 Hadoop 能够方便地实现数据分发、负载平衡以及以容错的方式并行处理大量数据。
检查 HDFS
可以通过几个检查确认 Hadoop(至少是 namenode)已经启动并正常运行。确认所有进程都在运行之后,可以使用 hadoop 命令检查本地名称空间(见清单 2)。
清单 2. 检查对 HDFS 的访问
# hadoop-0.20 fs -ls / Found 2 items drwxr-xr-x - root supergroup 0 2010-04-29 16:38 /user drwxr-xr-x - root supergroup 0 2010-04-29 16:28 /var # |
可以看出 namenode 已经启动,能够为本地名称空间提供服务。注意,使用 hadoop-0.20 命令检查文件系统。这个实用程序用于与 Hadoop 集群交互,包括检查文件系统、在集群中运行作业等等。请注意命令的结构:指定 hadoop-0.20 实用程序之后,定义一个命令(在这里是通用文件系统 shell)以及一个或多个选项(在这里使用 ls 请求文件列表)。因为 hadoop-0.20 是 Hadoop 集群的主要接口之一,您会看到本文中多次使用这个实用程序。清单 3 提供另外几个文件系统操作示例(创建子目录 test,列出它的内容,然后删除它),可以通过它们进一步了解这个接口。
清单 3. Hadoop 中的文件系统操作
# hadoop-0.20 fs -mkdir test # hadoop-0.20 fs -ls test # hadoop-0.20 fs -rmr test Deleted hdfs://localhost/user/root/test # |
测试 Hadoop
既然已经安装了 Hadoop 并测试了文件系统的基本接口,现在就该在真实的应用程序中测试 Hadoop 了。在这个示例中,我们使用 MapReduce 处理一个小数据集。map(映射) 和 reduce(缩减) 源自函数式编程中的函数名,但是这个应用程序的核心功能是数据缩减。映射 是指把大量输入处理成更小的子问题集(然后把这些子问题分发给并行的工作系统)。缩减 是指把子问题的答案组合成单一输出集。注意,这里没有定义处理 的含义,因为框架允许您自己定义什么是处理。典型的 MapReduce 示例是计算单词在文档集中出现的频率。
根据前面的讨论,我们需要一个输入集并产生一个输出集。第一步是在文件系统中创建一个 input 子目录,工作将放在这个目录中。使用以下命令:
# hadoop-0.20 fs -mkdir input |
接下来,在 input 目录中放一些工作。在这里,使用 put 命令把文件从本地文件系统转移到 HDFS 中(见清单 4)。注意,下面的命令格式把源文件转移到 HDFS 子目录 (input) 中。完成之后,在 HDFS 中就有两个文本文件等待处理。
清单 4. 把文件转移到 HDFS 中
# hadoop-0.20 fs -put /usr/src/linux-source-2.6.27 /Doc*/memory-barriers.txt input # hadoop-0.20 fs -put /usr/src/linux-source-2.6.27/Doc*/rt-mutex-design.txt input # |
接下来,使用 ls 命令检查文件是否存在(见清单 5)。
清单 5. 检查 HDFS 中的文件
# hadoop-0.20 fs -ls input Found 2 items -rw-r--r-- 1 root supergroup 78031 2010-04-29 17:35 /user/root/input/memory-barriers.txt -rw-r--r-- 1 root supergroup 33567 2010-04-29 17:36 /user/root/input/rt-mutex-design.txt # |
确认工作已经放在 HDFS 中之后,就可以执行 MapReduce 函数了。这个函数只需要一个命令,但是需要很长的请求,见清单 6。这个命令请求执行一个 JAR。它实际上实现许多功能,但是这个示例只使用 wordcount。jobtracker 守护进程请求 datanode 执行 MapReduce 作业,这会产生相当多的输出(这里的输出比较少是因为只处理两个文件)。它显示 map 和 reduce 函数的进度,然后提供与文件系统的 I/O 和记录处理相关的统计数据。
清单 6. 执行计算单词频率的 MapReduce 作业
# hadoop-0.20 jar /usr/lib/hadoop-0.20/hadoop- 0.20.2+228-examples.jar \ wordcount input output 10/04/29 17:36:49 INFO input.FileInputFormat: Total input paths to process : 2 10/04/29 17:36:49 INFO mapred.JobClient: Running job: job_201004291628_0009 10/04/29 17:36:50 INFO mapred.JobClient: map 0% reduce 0% 10/04/29 17:37:00 INFO mapred.JobClient: map 100% reduce 0% 10/04/29 17:37:06 INFO mapred.JobClient: map 100% reduce 100% 10/04/29 17:37:08 INFO mapred.JobClient: Job complete: job_201004291628_0009 10/04/29 17:37:08 INFO mapred.JobClient: Counters: 17 10/04/29 17:37:08 INFO mapred.JobClient: Job Counters 10/04/29 17:37:08 INFO mapred.JobClient: Launched reduce tasks=1 10/04/29 17:37:08 INFO mapred.JobClient: Launched map tasks=2 10/04/29 17:37:08 INFO mapred.JobClient: Data-local map tasks=2 10/04/29 17:37:08 INFO mapred.JobClient: FileSystemCounters 10/04/29 17:37:08 INFO mapred.JobClient: FILE_BYTES_READ=47556 10/04/29 17:37:08 INFO mapred.JobClient: HDFS_BYTES_READ=111598 10/04/29 17:37:08 INFO mapred.JobClient: FILE_BYTES_WRITTEN=95182 10/04/29 17:37:08 INFO mapred.JobClient: HDFS_BYTES_WRITTEN=30949 10/04/29 17:37:08 INFO mapred.JobClient: Map-Reduce Framework 10/04/29 17:37:08 INFO mapred.JobClient: Reduce input groups=2974 10/04/29 17:37:08 INFO mapred.JobClient: Combine output records=3381 10/04/29 17:37:08 INFO mapred.JobClient: Map input records=2937 10/04/29 17:37:08 INFO mapred.JobClient: Reduce shuffle bytes=47562 10/04/29 17:37:08 INFO mapred.JobClient: Reduce output records=2974 10/04/29 17:37:08 INFO mapred.JobClient: Spilled Records=6762 10/04/29 17:37:08 INFO mapred.JobClient: Map output bytes=168718 10/04/29 17:37:08 INFO mapred.JobClient: Combine input records=17457 10/04/29 17:37:08 INFO mapred.JobClient: Map output records=17457 10/04/29 17:37:08 INFO mapred.JobClient: Reduce input records=3381 |
处理结束之后,检查结果。这个作业的作用是计算单词在输入文件中出现的次数。输出是一个包含元组的文件,元组表示单词和它在输入中出现的次数。找到输出文件之后,可以通过 hadoop-0.20 实用程序使用 cat 命令查看数据(见清单 7)。
来源:csdn