Hadoop MapReduce v2 秘籍(一)
零、前言
我们目前正面临着雪崩般的数据,这些数据包含了许多洞察力,这些洞察力掌握着数据驱动的世界中成败的关键。 下一代 Hadoop(V2)提供了一个尖端平台来存储和分析这些海量数据集,并改进了广泛使用且非常成功的 Hadoop MapReduce v1。 将帮助您使用下一代 Hadoop MapReduce 分析大型复杂数据集的食谱将为您提供使用下一代 Hadoop 生态系统处理大型复杂数据集所需的技能和知识。
本书介绍了许多令人兴奋的主题,例如使用 Hadoop 解决分析、分类、数据索引和搜索的 MapReduce 模式。 您还将了解几个 Hadoop 生态系统组件,包括 Have、Pig、HBase、Mahout、Nutch 和 Sqoop。
本书向您介绍简单的示例,然后深入探讨如何解决深入的大数据使用案例。 本书以简单明了的方式介绍了 90 多个即用型 Hadoop MapReduce 食谱,并提供了分步说明和实际示例。
这本书涵盖了哪些内容
第 1 章,Hadoop v2入门,介绍 Hadoop MapReduce、Yarn 和 HDFS,并逐步完成 Hadoop v2 的安装。
第 2 章,云部署-在云环境中使用 Hadoop Yarn,说明如何使用 Amazon Elastic MapReduce(EMR)和 Apache Whirr 在云基础架构上部署和执行 Hadoop MapReduce、Pig、Have 和 HBase 计算。
第 3 章,Hadoop Essentials-配置、单元测试和其他 API介绍了基本的 Hadoop Yarn 和 HDFS 配置、HDFS Java API 以及 MapReduce 应用的单元测试方法。
第 4 章,开发复杂的 Hadoop MapReduce 应用向您介绍了几个高级 Hadoop MapReduce 功能,这些功能将帮助您开发高度自定义且高效的 MapReduce 应用。
第 5 章,Analytics解释了如何使用 Hadoop MapReduce 执行基本数据分析操作。
第 6 章,Hadoop 生态系统-Apache Have介绍了 Apache Have,它使用类似 SQL 的查询语言在 Hadoop 之上提供数据仓库功能。
第 7 章,Hadoop 生态系统 II-Pig、HBase、Mahout 和 Sqoop介绍了 Apache Pig 数据流样式数据处理语言、Apache HBase NoSQL 数据存储、Apache Mahout 机器学习和数据挖掘工具包,以及用于在 Hadoop 和关系数据库之间传输数据的 Apache Sqoop 批量数据传输实用程序。
第 8 章,搜索和索引介绍了几种可用于 Apache Hadoop 执行大规模搜索和索引的工具和技术。
第 9 章,分类、建议和查找关系解释了如何使用 Hadoop 实现复杂的算法,如分类、推荐和查找关系。
第 10 章,海量文本数据处理解释了如何使用 Hadoop 和 Mahout 处理大型文本数据集,以及如何使用 Hadoop 执行数据预处理和加载操作。
这本书你需要什么
您需要具备一定的 Java 知识,能够访问 Internet 和一台运行 Linux 操作系统的计算机。
这本书是给谁看的
如果您是一个大数据爱好者,并且希望使用 Hadoop v2 来解决您的问题,那么这本书是为您准备的。 本书面向对 Hadoop MapReduce 知之甚少的 Java 程序员。 这也是希望快速掌握使用 Hadoopv2 的开发人员和系统管理员的一站式参考。 掌握使用 Java 进行软件开发的基本知识和 Linux 的基本工作知识会很有帮助。
公约
在这本书中,你会发现许多区分不同信息的文本样式。 以下是这些风格的一些示例,并解释了它们的含义。
文本、数据库表名、文件夹名、文件名、文件扩展名、路径名、虚拟 URL、用户输入和 Twitter 句柄中的代码字如下所示:“以下是我们在hadoop.properties文件中使用的属性的说明。”
代码块设置如下:
Path file = new Path("demo.txt");
FSDataOutputStream outStream = fs.create(file);
outStream.writeUTF("Welcome to HDFS Java API!!!");
outStream.close();
当我们希望您注意代码块的特定部分时,相关行或项将以粗体显示:
Job job = Job.getInstance(getConf(), "MLReceiveReplyProcessor");
job.setJarByClass(CountReceivedRepliesMapReduce.class);
job.setMapperClass(AMapper.class);
job.setReducerClass(AReducer.class);
job.setNumReduceTasks(numReduce);
job.setOutputKeyClass(Text.class);
job.setOutputValueClass(Text.class);
job.setInputFormatClass(MBoxFileInputFormat.class);
FileInputFormat.setInputPaths(job, new Path(inputPath));
FileOutputFormat.setOutputPath(job, new Path(outputPath));
int exitStatus = job.waitForCompletion(true) ? 0 : 1;
任何命令行输入或输出都如下所示:
205.212.115.106 - - [01/Jul/1995:00:00:12 -0400] "GET /shuttle/countdown/countdown.html HTTP/1.0" 200 3985
新术语和重要单词以粗体显示。 例如,您在屏幕、菜单或对话框中看到的文字会出现在文本中,如下所示:“在Add Bootstrap Actions下拉框中选择Custom Action。单击Configure and Add。”
备注
警告或重要说明会出现在这样的框中。
提示
提示和技巧如下所示。
读者反馈
欢迎读者的反馈。 让我们知道你对这本书的看法-你喜欢什么或不喜欢什么。 读者反馈对于我们开发真正能让您获得最大收益的图书非常重要。
要向我们发送一般反馈,只需发送电子邮件至<[feedback@packtpub.com](mailto:feedback@packtpub.com)>,并通过消息主题提及书名。
如果有一个您擅长的主题,并且您有兴趣撰写或投稿一本书,请参阅我们位于www.Packtpub.com/Authors上的作者指南。
客户支持
现在您已经成为 Packt 图书的拥有者,我们有很多东西可以帮助您从购买中获得最大价值。
下载示例代码
您可以从您的帐户www.packtpub.com下载购买的所有 Packt 图书的示例代码文件。 如果您在其他地方购买了本书,您可以访问www.packtpub.com/support并注册,以便将文件通过电子邮件直接发送给您。
勘误表
虽然我们已经竭尽全力确保内容的准确性,但错误还是会发生。 如果您在我们的一本书中发现错误--可能是文本或代码中的错误--如果您能向我们报告,我们将不胜感激。 通过这样做,您可以将其他读者从挫折中解救出来,并帮助我们改进本书的后续版本。 如果您发现任何勘误表,请访问www.packtpub.com/submit-erra…,选择您的图书,单击勘误表提交表链接,然后输入勘误表的详细信息。 一旦您的勘误表被核实,您提交的勘误表将被接受,勘误表将被上传到我们的网站上,或添加到该标题勘误表部分下的任何现有勘误表列表中。 通过从www.packtpub.com/support中选择您的书目,可以查看任何现有勘误表。
盗版
在互联网上盗版版权材料是所有媒体持续存在的问题。 在 Packt,我们非常重视版权和许可证的保护。 如果您在互联网上发现任何形式的非法复制我们的作品,请立即提供我们的位置、地址或网站名称,以便我们采取补救措施。
请拨打<[copyright@packtpub.com](mailto:copyright@packtpub.com)>与我们联系,并提供疑似盗版材料的链接。
我们感谢您在保护我们的作者方面的帮助,以及我们为您提供有价值内容的能力。
问题
如果您对本书的任何方面有任何问题,可以拨打<[questions@packtpub.com](mailto:questions@packtpub.com)>与我们联系,我们将尽最大努力解决。
一、Hadoop v2 入门
在本章中,我们将介绍以下食谱:
- 在本地计算机上设置独立 Hadoop v2
- 编写字数统计 MapReduce 应用,捆绑它,并使用 Hadoop 本地模式运行它
- 向 Wordcount MapReduce 程序添加组合器步骤
- 设置 HDFS
- 使用 Hadoop v2 在分布式群集环境中设置 Hadoop Yarn
- 使用 Hadoop 发行版在分布式群集环境中设置 Hadoop 生态系统
- HDFS 命令行文件操作
- 在分布式集群环境中运行 WordCount 程序
- 使用 DFSIO 对 HDFS 进行基准测试
- 使用 TeraSort 对 Hadoop MapReduce 进行基准测试
简介
我们生活在大数据时代,网络、社交网络、智能手机等现象的指数级增长每天产生数万亿字节的数据。 从分析这些海量数据中获得洞察力已成为许多行业必备的竞争优势。 然而,这些数据源的大小和可能的非结构化性质使得不可能使用诸如关系数据库之类的传统解决方案来存储和分析这些数据集。
*要以有意义和及时的方式存储、处理和分析 PB 级数据,需要许多具有数千个磁盘和数千个处理器的计算节点,以及它们之间高效通信海量数据的能力。 这样的规模使得磁盘故障、计算节点故障、网络故障等故障屡见不鲜,使得容错成为此类系统的一个非常重要的方面。 出现的其他常见挑战包括巨大的资源成本、处理通信延迟、处理异构计算资源、跨节点同步以及负载平衡。 正如您可以推断的那样,开发和维护分布式并行应用以在处理所有这些问题的同时处理大量数据并非易事。 这就是 Apache Hadoop 拯救我们的地方。
备注
谷歌是首批面临处理海量数据问题的组织之一。 Google 借鉴了函数式编程领域的map和Reduce范例,构建了一个用于大规模数据处理的框架,并将其命名为MapReduce。 在 Google 的基础上,MapReduce 是 Google 文件系统,它是一个高吞吐量的并行文件系统,能够使用商用计算机可靠地存储海量数据。 介绍 Google MapReduce 和 Google File System 概念的开创性研究出版物可以在research.google.com/archive/map…和research.google.com/archive/gfs…找到。
Apache Hadoop MapReduce 是 Google MapReduce 范例中最广为人知、使用最广泛的开源实现。 ApacheHadoop 分布式文件系统(HDFS)提供了 Google 文件系统概念的开源实现。
Apache Hadoop MapReduce、HDFS 和 YAR 为跨商用计算机群集存储和处理超大型数据集提供了一个可伸缩的、容错的分布式平台。 与传统的高性能计算(HPC)群集不同,Hadoop 使用相同的计算节点集进行数据存储和执行计算,从而允许 Hadoop 通过将计算与存储进行配置来提高大规模计算的性能。 此外,由于使用商用硬件和商用互连,Hadoop 群集的硬件成本比 HPC 群集和数据库设备便宜数量级。 总之,基于 Hadoop 的框架已经成为存储和处理大数据的事实标准。
Hadoop 分布式文件系统-HDFS
HDFS 是一种块结构的分布式文件系统,旨在将 PB 级的数据可靠地存储在由商用硬件组成的计算集群上。 HDFS 覆盖在计算节点的现有文件系统之上,并通过将文件拆分成更粗粒度的块(例如,128 MB)来存储文件。 HDFS 在处理大文件时性能更好。 HDFS 将大文件的数据块分布到群集的所有节点,以便在处理数据时实现极高的并行聚合读取带宽。 HDFS 还将这些数据块的冗余副本存储在多个节点中,以确保可靠性和容错性。 数据处理框架(如 MapReduce)利用这些分布式数据块集和冗余来最大化大型数据集的数据本地处理,其中大多数数据块将在存储它们的同一物理节点中进行本地处理。
HDFS 由NameNode和DataNode服务组成,为分布式文件系统提供基础。 NameNode 存储、管理和服务文件系统的元数据。 NameNode 不存储任何实际数据块。 DataNode 是一项针对每个节点的服务,用于管理 DataNode 中的实际数据块存储。 在检索数据时,客户端应用首先联系 NameNode 以获取请求的数据所在位置的列表,然后直接联系 DataNode 以检索实际数据。 下图概括介绍了 HDFS 的结构:
Hadoop v2 为 HDFS 带来了几个性能、可伸缩性和可靠性改进。 其中最重要的是High Availability(HA)对 HDFSNameNode 的支持,它为 HDFS NameNode 服务提供手动和自动故障转移功能。 这解决了 HDFS 广为人知的 NameNode 单点故障弱点。 自动 NameNode Hadoop v2 的高可用性使用 Apache ZooKeeper 进行故障检测和活动 NameNode 选举。 另一个重要的新特性是对 HDFS 联合的支持。 HDFS 联合支持在单个 HDFS 群集中使用个独立的 HDFS 命名空间。 这些命名空间将由独立的 NameNode 管理,但是共享集群的 DataNode 来存储数据。 HDFS 联合功能通过允许我们分配 NameNode 的工作负载,提高了 HDFS 的水平可伸缩性。 Hadoop v2 中 HDFS 的其他重要改进包括对 HDFS 快照的支持、异构存储层次结构支持(Hadoop 2.3 或更高版本)、内存数据缓存支持(Hadoop 2.3 或更高版本)以及许多性能改进。
几乎所有 Hadoop 生态系统数据处理技术都使用 HDFS 作为主要数据存储。 HDFS 可以被认为是 Hadoop 生态系统中最重要的组件,因为它在 Hadoop 体系结构中具有中心性质。
Hadoop Yarn
Yarn(还有另一个资源谈判者)是 Hadoopv2 中引入的主要新改进。 Yar 是一个资源管理系统,它允许多个分布式处理框架有效地共享 Hadoop 集群的计算资源,并利用存储在 HDFS 中的数据。 Year 是 Hadoopv2 生态系统中的核心组件,为许多不同类型的分布式应用提供了一个公共平台。
基于批处理的 MapReduce 框架是 Hadoopv1 中唯一本地支持的数据处理框架。 虽然 MapReduce 可以很好地分析大量数据,但 MapReduce 本身不足以支持不断增加的其他分布式处理用例,例如实时数据计算、图形计算、迭代计算和实时数据查询。 YAIN 的目标是允许用户利用多个分布式应用框架,这些框架并排提供这样的功能,共享单个集群和 HDFS 文件系统。 当前 Yarn 应用的一些示例包括 MapReduce 框架、TEZ 高性能处理框架、Spark 处理引擎和 Storm 实时流处理框架。 下图描述了 Yarn 生态系统的高级架构:
YAR ResourceManager 进程是中央资源调度器,用于管理资源并将其分配给提交给集群的不同应用(也称为作业)。 Yanson NodeManager 是一个针对每个节点的进程,用于管理单个计算节点的资源。 ResourceManager 的调度器组件响应于应用做出的资源请求来分配资源,考虑到集群容量和可以通过 Yarn 策略插件框架指定的其他调度策略。
Yarn 有一个叫做容器的概念,它是资源分配的单位。 每个已分配的容器都有权访问特定计算节点中的一定数量的 CPU 和内存。 应用可以通过指定所需的容器数量以及每个容器所需的 CPU 和内存来请求来自 Yarn 的资源。
ApplicationMaster 是一个针对每个应用的进程,它协调单个应用的计算。 执行 Yarn 应用的第一步是部署 ApplicationMaster。 在 YAINE 客户端提交应用后,ResourceManager 为该应用分配一个容器并部署 ApplicationMaster。 部署后,ApplicationMaster 负责向 ResourceManager 请求和协商必要的资源容器。 一旦 ResourceManager 分配了资源,ApplicationMaster 就会与 NodeManagers 协调以启动和监视分配的资源中的应用容器。 将应用协调职责转移到 ApplicationMaster 减轻了 ResourceManager 的负担,使其能够只专注于管理群集资源。 此外,对于每个提交的应用都有单独的 ApplicationMaster 可以提高集群的可伸缩性,而不是使用单个进程瓶颈来协调所有应用实例。 下图描述了将 MapReduce 应用提交到群集时各种 Yarn 组件之间的交互:
虽然 Yar 支持许多不同的分布式应用执行框架,但本书主要关注传统的 MapReduce 和相关技术。
Hadoop MapReduce
HadoopMapReduce 是一个数据处理框架,可用于处理存储在 HDFS 中的海量数据。 正如我们前面提到的,以可靠和高效的方式分布式处理海量数据并非易事。 Hadoop MapReduce 旨在通过提供程序的自动并行化和框架管理的容错支持,为程序员提供清晰的抽象,从而简化用户。
MapReduce 编程模型由 Map 和 Reduce 函数组成。 Map 函数接收输入数据的每条记录(文件的行、数据库的行等)作为键-值对,并输出键-值对作为结果。 通过设计,每个 Map 函数调用都是相互独立的,从而允许框架使用分而治之的方式并行执行计算。 这还允许在出现故障或负载不平衡的情况下重复执行或重新执行 Map 任务,而不会影响计算结果。 通常,Hadoop 会为输入数据的每个 HDFS 数据块创建一个 Map 任务实例。 Map 任务实例内的 Map 函数调用数等于特定 Map 任务实例的输入数据块中的数据记录数。
Hadoop MapReduce 使用键对计算的所有 Map 任务的输出键值记录进行分组,并将它们分发给 Reduce 任务。 这种将数据分发和传输到 Reduce 任务的过程称为 MapReduce 计算的无序阶段。 每个 Reduce 任务的输入数据也将按键进行排序和分组。 将按键的排序顺序为每个键和该键的值组(Reduce<key,list_of_value>)调用 Reduce 函数。 在典型的 MapReduce 程序中,用户只需实现 Map 和 Reduce 函数,Hadoop 负责并行调度和执行它们。 Hadoop 将重新运行任何失败的任务,并提供缓解任何不平衡计算的措施。 为了更好地理解 MapReduce 数据流和计算流,请查看下图:
在 Hadoop1.x 中,MapReduce(MR1)组件由JobTracker进程和TaskTracker组成,前者在管理集群和协调作业的主节点上运行,后者在每个计算节点上运行,启动和协调在该节点中执行的任务。 Hadoop 2.x MapReduce(MR2)中没有这两个进程。 在 MR2 中,JobTracker 的工作协调职责由 ApplicationMaster 处理,该 ApplicationMaster 将通过 Yarn 按需部署。 JobTracker 的集群管理和作业调度职责在 MR2 中由 YAR ResourceManager 处理。 JobHistoryServer 已经接管了提供有关已完成的 MR2 作业的信息的责任。 通过在计算节点中管理资源和启动容器(在 MapReduce 2 中启动容器,在 MapReduce 2 中包含 Map 或 Reduce 任务),Yanson NodeManager 提供了与 MR1 TaskTracker 有些类似的功能。
Hadoop 安装模式
Hadoopv2 提供了三个安装选项:
- 本地模式:本地模式允许我们仅使用解压的 Hadoop 发行版运行 MapReduce 计算。 这种非分布式模式在单个 Java 进程中执行 Hadoop MapReduce 的所有部分,并使用本地文件系统作为存储。 本地模式对于本地测试/调试 MapReduce 应用非常有用。
- 伪分布式模式:使用此模式,我们可以在模拟分布式集群的单机上运行 Hadoop。 此模式将 Hadoop 的不同服务作为不同的 Java 进程运行,但在一台机器内运行。 这种模式很适合让您玩和体验 Hadoop。
- 分布式模式:这是真正的分布式模式,支持从几个节点到数千个节点的集群。 对于生产集群,我们建议使用众多打包的 Hadoop 发行版之一,而不是使用 Hadoop 发行版二进制文件从头开始安装 Hadoop,除非您有需要普通 Hadoop 安装的特定用例。 有关 Hadoop 发行版的更多信息,请参阅使用 Hadoop 发行版在分布式集群环境中建立 Hadoop 生态系统食谱。
备注
本书的示例代码文件可以在 giHub 上的github.com/thilg/hcb-v…获得。 代码库的chapter1文件夹包含本章的示例源代码文件。 您还可以使用github.com/thilg/hcb-v…链接下载存储库中的所有文件。
本书的示例代码使用 Gradle 自动编译和构建项目。 您可以按照www.gradle.org/docs/curren…提供的指南安装 Gradle。 通常,您只需从www.gradle.org/downloads下载并解压缩 Gradle 发行版,并将提取的 Gradle 发行版的 bin 目录添加到您的 PATH 变量中。
所有示例代码都可以通过在代码库的主文件夹中发出gradle build命令来构建。
Eclipse IDE 的项目文件可以通过在代码库的主文件夹中运行gradle eclipse命令来生成。
IntelliJ IDEA IDE 的项目文件可以通过在代码库的主文件夹中运行gradle idea命令来生成。
在本地计算机上设置 Hadoop v2
本菜谱介绍了如何使用本地模式在本地计算机上设置 Hadoop v2。 本地模式是一种非分布式模式,可用于测试和调试 Hadoop 应用。 在本地模式下运行 Hadoop 应用时,所有必需的 Hadoop 组件和应用都在单个Java 虚拟机(JVM)进程内执行。
做好准备
下载并安装 JDK 1.6 或更高版本,最好是 Oracle JDK 1.7。 Oracle JDK 可以从www.oracle.com/technetwork…下载。
怎么做……
现在,让我们开始 Hadoop v2 安装:
-
从hadoop.apache.org/releases.ht…下载最新的 Hadoopv2 分支发行版(Hadoop2.2.0 或更高版本)。
-
使用以下命令解压缩 Hadoop 发行版。 您必须将文件名中的
x.x.更改为您下载的实际版本。 从现在开始,我们将把解压后的 Hadoop 目录命名为{HADOOP_HOME}:$ tar -zxvf hadoop-2.x.x.tar.gz -
现在,您可以通过
{HADOOP_HOME}/bin/hadoop命令运行 Hadoop 作业,我们将在下一个菜谱中进一步详细说明这一点。
它是如何工作的.
Hadoop 本地模式不启动任何服务器,但在单个 JVM 内完成所有工作。 当您以本地模式向 Hadoop 提交作业时,Hadoop 会启动 JVM 来执行该作业。 该作业的输出和行为与分布式 Hadoop 作业相同,不同之处在于该作业仅使用当前节点运行任务,而本地文件系统用于数据存储。 在下一个菜谱中,我们将了解如何使用 Hadoop 本地模式运行 MapReduce 程序。
编写字数统计 MapReduce 应用,将其捆绑在一起,并使用 Hadoop 本地模式运行它
这个配方解释了如何实现一个简单的 MapReduce 程序来计算数据集中单词的出现次数。 Wordcount 作为 Hadoop MapReduce 的 HelloWorld 等价物而闻名。
要运行 MapReduce 作业,用户应该提供map函数、reduce函数、输入数据和存储输出数据的位置。 执行时,Hadoop 执行以下步骤:
- Hadoop 使用提供的InputFormat将输入数据分解为键-值对,并为每个键-值对调用
map函数,提供键-值对作为输入。 执行时,map函数可以输出零个或多个键值对。 - Hadoop 将映射器发出的键值对传输到还原器(此步骤称为无序)。 Hadoop 然后按键对这些键-值对进行排序,并将属于同一键的值分组在一起。
- 对于每个不同的键,Hadoop 调用一次 Reduce 函数,同时传递该键的特定键和值列表作为输入。
reduce函数可以输出零个或多个键值对,Hadoop 将它们写入输出数据位置作为最终结果。
做好准备
从本书的源代码存储库中选择第一章的源代码。 导出指向解压缩的 Hadoop 发行版的根的$HADOOP_HOME环境变量。
怎么做……
现在,让我们编写我们的第一个 Hadoop MapReduce 程序:
-
WordCount 示例使用 MapReduce 计算一组输入文档中出现的单词数。 示例代码位于本章源文件夹的
chapter1/Wordcount.java文件中。 代码由三部分组成-映射器、Reducer 和主程序。 -
映射器从
org.apache.hadoop.mapreduce.Mapper接口扩展。 Hadoop InputFormat 将输入文件中的每一行作为输入键-值对提供给map函数。 函数map使用空格字符(如分隔符)将每行分成子字符串,并为每个标记(Word)发出(word,1)作为输出。public void map(Object key, Text value, Context context) throws IOException, InterruptedException { // Split the input text value to words StringTokenizer itr = new StringTokenizer(value.toString()); // Iterate all the words in the input text value while (itr.hasMoreTokens()) { word.set(itr.nextToken()); context.write(word, new IntWritable(1)); } } -
每个
reduce函数调用都接收一个键和该键的所有值作为和输入。reduce函数输出键和键的出现次数作为输出。public void reduce(Text key, Iterable<IntWritable>values, Context context) throws IOException, InterruptedException { int sum = 0; // Sum all the occurrences of the word (key) for (IntWritableval : values) { sum += val.get(); } result.set(sum); context.write(key, result); } -
main驱动程序配置 MapReduce 作业并将其提交给 Hadoop Yarn 集群:Configuration conf = new Configuration(); …… // Create a new job Job job = Job.getInstance(conf, "word count"); // Use the WordCount.class file to point to the job jar job.setJarByClass(WordCount.class); job.setMapperClass(TokenizerMapper.class); job.setReducerClass(IntSumReducer.class); job.setOutputKeyClass(Text.class); job.setOutputValueClass(IntWritable.class); // Setting the input and output locations FileInputFormat.addInputPath(job, new Path(otherArgs[0])); FileOutputFormat.setOutputPath(job, newPath(otherArgs[1])); // Submit the job and wait for it's completion System.exit(job.waitForCompletion(true) ? 0 : 1); -
通过从示例代码库的
chapter1文件夹发出gradle build命令,使用本章介绍中提到的使用 Gradle 版本编译示例。 或者,您也可以通过发出ant compile命令来使用提供的 Apache Ant 构建文件。 -
使用以下命令运行 wordcount 示例。 在此命令中,
chapter1.WordCount是main类的名称。wc-input是输入数据目录,wc-output是输出路径。 源库的wc-input目录包含一个示例文本文件。 或者,您可以将任何文本文件复制到wc-input目录。$ $HADOOP_HOME/bin/hadoop jar \ hcb-c1-samples.jar \ chapter1.WordCount wc-input wc-output -
输出目录(
wc-output)将有一个名为part-r-XXXXX的文件,该文件将包含文档中每个单词的计数。 祝贺你!。 您已经成功运行了您的第一个 MapReduce 程序。$ cat wc-output/part*
它是如何工作的.
在前面的示例中,MapReduce 在本地模式下工作,不启动任何服务器,并使用本地文件系统作为输入、输出和工作数据的存储系统。 下图显示了隐藏在 WordCount 程序中发生的情况:
字数统计 MapReduce 工作流的工作方式如下:
- Hadoop 读取输入,使用新行个字符作为分隔符来中断它,然后运行
map函数,将每行作为参数传递,行号作为键,行内容作为值。 - 函数的作用是:标记该行,并为每个标记(Word)发出一个键-值对
(word,1)。 - Hadoop 收集所有
(word,1)对,按单词对它们进行排序,根据每个唯一键对发出的所有值进行分组,并为每个唯一键调用一次reduce函数,将该键的键和值作为参数传递。 reduce函数使用这些值计算每个单词的出现次数,并将其作为键-值对发出。- Hadoop 将最终输出写入输出目录。
还有更多...
作为可选步骤,您可以直接从您喜欢的Java 集成开发环境(IDE)设置和运行 WordCount 应用。 Eclipse IDE 和 IntelliJ IDEA IDE 的项目文件可以通过在代码库的主文件夹中分别运行gradle eclipse和gradle idea命令来生成。
对于其他 IDE,您必须将以下目录中的 JAR 文件添加到为示例代码创建的 IDE 项目的类路径中:
{HADOOP_HOME}/share/hadoop/common{HADOOP_HOME}/share/hadoop/common/lib{HADOOP_HOME}/share/hadoop/mapreduce{HADOOP_HOME}/share/hadoop/yarn{HADOOP_HOME}/share/hadoop/hdfs
通过传递wc-input和wc-output作为参数来执行chapter1.WordCount类。 这将像以前一样运行示例。 以这种方式从 IDE 运行 MapReduce 作业对于调试 MapReduce 作业非常有用。
另请参阅
尽管您在本地机器上安装了 Hadoop 来运行示例,但是您可以使用分布式 Hadoop 集群设置和 HDFS 分布式文件系统来运行它。 本章的在分布式集群环境中运行 Wordcount 程序配方将讨论如何在分布式设置中运行此示例。
向 Wordcount MapReduce 程序添加组合器步骤
一个单个映射任务可能会输出许多具有相同键的键值对,导致 Hadoop 通过网络混洗(移动)所有这些值到 Reduce 任务,这会产生很大的开销。 例如,在前面的 Wordcount MapReduce 程序中,当 Mapper 在单个 Map 任务中遇到同一单词的多次出现时,map函数将输出许多<word,1>个中间键-值对以通过网络传输。 但是,如果在通过网络将数据发送到减少器之前,我们可以将<word,1>对的所有实例求和为单个<word, count>对,则可以优化此场景。
为了优化这样的场景,Hadoop 支持一个称为组合器的特殊函数,该函数执行 Map 任务输出键-值对的本地聚合。 如果提供,Hadoop 会在将数据持久化到磁盘之前调用 Map 任务输出上的组合器函数,以调整 Reduce 任务。 这可以显著减少从 Map 任务转移到 Reduce 任务的数据量。 应该注意,组合器是 MapReduce 流的一个可选步骤。 即使您提供了组合器实现,Hadoop 也可能决定只为 Map 输出数据的子集调用它,或者根本不调用它。
本食谱解释了如何将组合器与前面食谱中介绍的 Wordcount MapReduce 应用结合使用。
怎么做……
现在,让我们向 Wordcount MapReduce 应用添加一个组合器:
-
组合器必须与
reduce函数具有相同的接口。 组合器发出的输出键-值对类型应该与 Reducer 输入键-值对的类型匹配。 对于 wordcount 示例,我们可以重用 wordcountreduce函数作为组合器,因为 wordcountreduce函数的输入和输出数据类型是相同的。 -
取消注释
WordCount.java文件中的以下行,以启用 WordCount 应用的组合器:job.setCombinerClass(IntSumReducer.class); -
通过重新运行 Gradle(
gradle build)或 Ant 构建(ant compile)重新编译代码。 -
使用以下命令运行 wordcount 示例。 在运行作业之前,请确保删除旧的输出目录(
wc-output)。$ $HADOOP_HOME/bin/hadoop jar \ hcb-c1-samples.jar \ chapter1.WordCount wc-input wc-output -
最终结果将从
wc-output目录中获得。
它是如何工作的.
如果提供,Hadoop 会在将数据持久存储到磁盘上以转移到 Reduce 任务之前,调用 Map 任务输出上的组合器函数。 组合器可以在将映射器生成的数据发送到 Reducer 之前对其进行预处理,从而减少需要传输的数据量。
在 WordCount 应用中,组合器接收N个(word,1)对作为输入,并输出单个(word, N)对。 例如,如果由 Map 任务处理的输入有 1,000 个单词“the”出现,映射器将生成 1,000 个(the,1)对,而组合器将生成一个(the,1000)对,从而减少需要传输到 Reduce 任务的数据量。 下图显示了 Wordcount MapReduce 应用中合并器的用法:
还有更多...
仅当reduce函数输入和输出键值数据类型相同时,才能将作业的reduce函数用作组合器。 在不能重用reduce函数作为组合器的情况下,可以编写专用的reduce函数实现来充当组合器。 组合器输入和输出键-值对类型应该与映射器输出键-值对类型相同。
我们重申,组合器是 MapReduce 流的一个可选步骤。 即使您提供了组合器实现,Hadoop 也可能决定只为 Map 输出数据的子集调用它,或者根本不调用它。 注意不要使用组合器执行计算的任何基本任务,因为 Hadoop 不保证组合器的执行。
在非分布式模式下使用组合器不会产生显著的增益。 但是,在使用 Hadoop v2配方在分布式群集环境中设置 Hadoop Yarn 中所述的分布式设置中,组合器可以提供显著的性能提升。
设置 HDFS
HDFS 是一个块结构的分布式文件系统,设计用于在商用硬件组成的集群上可靠地存储 PB 级的数据。 HDFS 支持存储海量数据,并提供对数据的高吞吐量访问。 HDFS 通过冗余跨多个节点存储文件数据,以确保容错和高聚合带宽。
HDFS 是 Hadoop MapReduce 计算使用的默认分布式文件系统。 Hadoop 支持对存储在 HDFS 中的数据进行数据位置感知处理。 HDFS 体系结构主要由处理文件系统元数据的集中式 NameNode 和存储实际数据块的 DataNode 组成。 HDFS 数据块通常粒度较粗,在大型流读取时性能更好。
要设置 HDFS,我们首先需要配置 NameNode 和 DataNodes,然后在slaves文件中指定 DataNode。 当我们启动 NameNode 时,启动脚本将启动 DataNode。
提示
建议使用本食谱中提到的 Hadoop 版本构件直接安装 HDFS,仅用于开发测试和高级使用情形。 对于常规生产集群,我们建议使用打包的 Hadoop 发行版,如使用 Hadoop 发行版配方在分布式集群环境中设置 Hadoop 生态系统中所述。 打包的 Hadoop 发行版使安装、配置、维护和更新 Hadoop 生态系统的组件变得更加容易。
做好准备
您可以使用一台机器或多台机器遵循此食谱。 如果您使用多台计算机,则应选择一台计算机作为运行 HDFS NameNode 的主节点。 如果您使用的是单台计算机,请同时将其用作名称节点和数据节点。
- 在将用于设置 HDFS 集群的所有计算机上安装 JDK 1.6 或更高版本(首选 Oracle JDK 1.7)。 将
JAVA_HOME环境变量设置为指向 Java 安装。 - 按照在本地计算机上设置 Hadoop v2 的方法下载 Hadoop。
怎么做……
现在,让我们在分布式模式下设置 HDFS:
-
Set up password-less SSH from the master node, which will be running the NameNode, to the DataNodes. Check that you can log in to localhost and to all other nodes using SSH without a passphrase by running one of the following commands:
$ ssh localhost $ ssh <IPaddress>提示
配置无密码 SSH
如果步骤 1 中的命令返回错误或要求输入密码,请通过执行以下命令创建 SSH 密钥(您可能需要事先手动启用 SSH,具体取决于您的操作系统):
$ ssh-keygen -t dsa -P '' -f ~/.ssh/id_dsa将
~/.ssh/id_dsa.pub文件移动到集群中的所有节点。 然后通过运行以下命令将 SSH 密钥添加到每个节点的~/.ssh/authorized_keys文件中(如果authorized_keys文件不存在,请运行以下命令。 否则,跳到cat命令):$ touch ~/.ssh/authorized_keys && chmod 600 ~/.ssh/authorized_keys现在,设置权限后,将您的密钥添加到
~/.ssh/authorized_keys文件:$ cat ~/.ssh/id_dsa.pub >> ~/.ssh/authorized_keys然后,您应该能够成功执行以下命令,而无需提供密码:
$ ssh localhost -
在每台服务器中,创建一个用于存储 HDFS 数据的目录。 让我们将该目录命名为
{HADOOP_DATA_DIR}。 在数据目录内创建两个子目录{HADOOP_DATA_DIR}/data和{HADOOP_DATA_DIR}/name。 通过对每个目录运行以下命令,将目录权限更改为755:$ chmod –R 755 <HADOOP_DATA_DIR> -
在 NameNode 中,将所有从节点的 IP 地址添加到
{HADOOP_HOME}/etc/hadoop/slaves文件中,每个从节点都在单独的一行上。 当我们启动 NameNode 时,它将使用这个slaves文件来启动 DataNode。 -
将以下配置添加到
{HADOOP_HOME}/etc/hadoop/core-site.xml。 在添加配置之前,请将{NAMENODE}字符串替换为主节点的 IP:<configuration> <property> <name>fs.defaultFS</name> <value>hdfs://{NAMENODE}:9000/</value> </property> </configuration> -
将以下配置添加到
{HADOOP_HOME}/etc/hadoop目录下的{HADOOP_HOME}/etc/hadoop/hdfs-site.xml文件中。 在添加配置之前,请将{HADOOP_DATA_DIR}替换为您在第一步中创建的目录。 将我们在步骤 4 和 5 中修改的core-site.xml和hdfs-site.xml文件复制到所有节点。<configuration> <property> <name>dfs.namenode.name.dir</name> <!-- Path to store namespace and transaction logs --> <value>{HADOOP_DATA_DIR}/name</value> </property> <property> <name>dfs.datanode.data.dir</name> <!-- Path to store data blocks in datanode --> <value>{HADOOP_DATA_DIR}/data</value> </property> </configuration> -
From the NameNode, run the following command to format a new filesystem:
$ $HADOOP_HOME/bin/hdfs namenode –format成功完成上一个命令后,您将在输出中看到以下行:
… 13/04/09 08:44:51 INFO common.Storage: Storage directory /…/dfs/name has been successfully formatted. …. -
Start the HDFS using the following command:
$ $HADOOP_HOME/sbin/start-dfs.sh此命令将首先在主节点中启动 NameNode。 然后,它将在
slaves文件中提到的计算机中启动 DataNode 服务。 最后,它将启动辅助 NameNode。 -
HDFS 附带一个监控 Web 控制台,用于验证安装和监控 HDFS 群集。 它还允许用户浏览 HDFS 文件系统的内容。 可以从
http://{NAMENODE}:50070/访问 HDFS 监控控制台。 访问监控控制台,确认是否可以看到 HDFS 启动页面。 在这里,将{NAMENODE}替换为运行 HDFS NameNode 的节点的 IP 地址。 -
或者,您可以使用以下命令获取有关 HDFS 状态的报告:
$ $HADOOP_HOME/bin/hadoop dfsadmin -report -
最后,使用以下命令关闭 HDFS 集群:
```scala
$ $HADOOP_HOME/sbin/stop-dfs.sh
```
另请参阅
- 在HDFS 命令行文件操作配方中,我们将探索如何使用 HDFS 存储和管理文件。
- HDFS 设置只是 Hadoop 安装的一部分。 使用 Hadoop v2在分布式集群环境中设置 Hadoop Yarn 食谱介绍了如何设置 Hadoop 的其余部分。
- 使用 Hadoop 发行版在分布式集群环境中设置 Hadoop 生态系统食谱探索了如何使用打包的 Hadoop 发行版在集群中安装 Hadoop 生态系统。
使用 Hadoop v2 在分布式群集环境中设置 Hadoop Yarn
Hadoop v2 Yarn 部署包括在主节点上部署 ResourceManager 服务和在从节点上部署 NodeManager 服务。 Yar ResourceManager 是对集群的所有资源进行仲裁的服务,NodeManager 是管理单个节点中的资源的服务。
Hadoop MapReduce 应用可以在 Yarn 上运行,使用一个 Yarn ApplicationMaster 来协调每个作业和一组资源容器来运行 Map 和 Reduce 任务。
提示
建议使用本食谱中提到的 Hadoop 版本构件直接安装 Hadoop,仅用于开发测试和高级用例。 对于常规生产集群,我们建议使用打包的 Hadoop 发行版,如使用 Hadoop 发行版配方在分布式集群环境中设置 Hadoop 生态系统中所述。 打包的 Hadoop 发行版使安装、配置、维护和更新 Hadoop 生态系统的组件变得更加容易。
做好准备
您可以使用台机器作为伪分布式安装,也可以使用多台机器集群来遵循这个配方。 如果您使用多台计算机,则应该选择一台计算机作为运行 HDFS NameNode 和 Yar ResourceManager 的主节点。 如果您使用的是单台计算机,请同时将其用作主节点和从节点。
按照设置 HDFS配方设置 HDFS。
怎么做……
让我们通过设置 Yarn 资源管理器和节点管理器来设置 Hadoop Yarn。
-
在每台机器上,创建一个名为 local inside
{HADOOP_DATA_DIR}, which的目录,该目录是您在设置 HDFS配方中创建的。 将目录权限更改为755。 -
将以下内容添加到
{HADOOP_HOME}/etc/hadoop/mapred-site.xml模板中,并将其另存为{HADOOP_HOME}/etc/hadoop/mapred-site.xml:<property> <name>fs.default.name</name> <value>hdfs://localhost:9000</value> </property> -
将以下内容添加到
{HADOOP_HOME}/etc/hadoop/yarn-site.xml文件:<property> <name>yarn.nodemanager.aux-services</name> <value>mapreduce_shuffle</value> </property> <property> <name>yarn.nodemanager.aux-services.mapreduce_shuffle.class</name> <value>org.apache.hadoop.mapred.ShuffleHandler</value> </property> -
使用以下命令启动 HDFS:
$ $HADOOP_HOME/sbin/start-dfs.sh -
运行以下命令以启动 Yarn 服务:
$ $HADOOP_HOME/sbin/start-yarn.sh starting yarn daemons starting resourcemanager, logging to ……… xxx.xx.xxx.xxx: starting nodemanager, logging to ……… -
运行以下命令以启动 MapReduce JobHistoryServer。 这将启用用于 MapReduce 作业历史记录的 Web 控制台:
$ $HADOOP_HOME/sbin/mr-jobhistory-daemon.sh start historyserver -
通过
jps命令列出进程来验证安装。 主节点将列出 NameNode、ResourceManager 和 JobHistoryServer 服务。 从节点将列出 DataNode 和 NodeManager 服务:$ jps 27084 NameNode 2073 JobHistoryServer 2106 Jps 2588 1536 ResourceManager -
请访问
http://{MASTER_NODE}:8088/上提供的 ResourceManager 的基于 Web 的监控页面。
它是如何工作的.
如本章简介中所述,Hadoopv2 安装由 HDFS 节点、Yanth ResourceManager 和 Worker 节点组成。 当我们启动 NameNode 时,它通过HADOOP_HOME/slaves文件查找从节点,并在启动时使用 SSH 启动远程服务器中的 DataNode。 此外,当我们启动 ResourceManager 时,它会通过HADOOP_HOME/slaves文件查找从属对象并启动 NodeManagers。
另请参阅
使用 Hadoop 发行版在分布式集群环境中设置 Hadoop 生态系统食谱探索了如何使用打包的 Hadoop 发行版在集群中安装 Hadoop 生态系统。
使用 Hadoop 发行版在分布式群集环境中设置 Hadoop 生态系统
HadoopYarn 生态系统现在包含许多有用的组件,为存储在 HDFS 中的数据提供广泛的数据处理、存储和查询功能。 然而,使用单独的版本构件手动安装和配置所有这些组件以正确地协同工作是一项相当具有挑战性的任务。 这种方法的其他挑战包括监控和维护集群和多个 Hadoop 组件。
幸运的是,有几家商业软件供应商提供了集成良好的打包 Hadoop 发行版,使得在我们的集群中配置和维护 Hadoop Yarn 生态系统变得更加容易。 这些发行版通常带有简单的基于 GUI 的安装程序,可以引导您完成整个安装过程,并允许您选择和安装 Hadoop 集群中所需的组件。 它们还提供工具来轻松监控群集和执行维护操作。 对于常规生产集群,我们建议使用知名供应商提供的打包 Hadoop 发行版,使您的 Hadoop 之旅更加轻松。 其中一些商业 Hadoop 发行版(或发行版)拥有许可,允许我们通过可选的付费支持协议免费使用它们。
Hortonworks Data Platform(HDP)就是这样一种免费提供的众所周知的 Hadoop Yarn 分布。 HDP 的所有组件都是免费的开源软件。 您可以从hortonworks.com/hdp/downloa…下载 hdp。 有关安装说明,请参阅下载页面中提供的安装指南。
Cloudera CDH是另一个著名的 Hadoop Yarn 分布。 专用宿主机速成版免费提供。 Cloudera 发行版的一些组件是专有的,只对付费客户可用。 您可以从www.cloudera.com/content/clo…下载 Cloudera Express。 有关安装说明,请参阅下载页面上提供的安装指南。
Hortonworks HDP、Cloudera CDH 和其他一些供应商提供完全配置的快速入门虚拟机映像,您可以使用虚拟化软件产品下载这些映像并在本地计算机上运行。 在决定集群的 Hadoop 发行版之前,这些虚拟机是学习和尝试不同 Hadoop 组件以及进行评估的极佳资源。
Apachebigtop 是一个开源项目,旨在为各种 Hadoop 生态系统组件提供打包和集成/互操作性测试。 Bigtop 还提供了厂商中立的打包 Hadoop 发行版。 虽然它不像商业发行版那么复杂,但 Bigtop 比使用每个 Hadoop 组件的二进制发行版更容易安装和维护。 在本食谱中,我们提供了使用 Apache bigtop 在本地计算机上安装 Hadoop 生态系统的步骤。
前面提到的任何发行版本(包括 bigtop)都适用于遵循本书中提供的食谱和执行示例的目的。 但是,如果可能,我们建议使用 Hortonworks HDP、Cloudera CDH 或其他商业 Hadoop 发行版。
做好准备
本食谱提供了 CENT OS 和 Red Hat 操作系统的说明。 停止您在前面的食谱中启动的所有 Hadoop 服务。
怎么做……
以下步骤将指导您完成使用 Apache bigtop for Cent OS 和 Red Hat 操作系统的 Hadoop 集群的安装过程。 请将这些命令相应地修改为适用于其他基于 Linux 的操作系统。
-
安装 Bigtop 存储库:
$ sudo wget -O \ /etc/yum.repos.d/bigtop.repo \ http://www.apache.org/dist/bigtop/stable/repos/centos6/bigtop.repo -
搜索 Hadoop:
$ yum search hadoop -
使用 YUM 安装 Hadoop v2。 这将安装 Hadoopv2 组件(MapReduce、HDFS 和 YAR)以及 ZooKeeper 依赖项。
$ sudo yum install hadoop\* -
使用您喜欢的编辑器将以下行添加到
/etc/default/bigtop-utils文件。 建议将JAVA_HOME指向 JDK 1.6 或更高版本的安装(首选 Oracle JDK 1.7 或更高版本)。export JAVA_HOME=/usr/java/default/ -
初始化并格式化 NameNode:
$ sudo /etc/init.d/hadoop-hdfs-namenode init -
启动 Hadoop NameNode 服务:
$ sudo service hadoop-hdfs-namenode start -
启动 Hadoop DataNode 服务:
$ sudo service hadoop-hdfs-datanode start -
运行以下脚本以在 HDFS 中创建必要的目录:
$ sudo /usr/lib/hadoop/libexec/init-hdfs.sh -
在 HDFS 中创建您的主目录并应用必要的权限:
$ sudo su -s /bin/bash hdfs \ -c "/usr/bin/hdfs dfs -mkdir /user/${USER}" $ sudo su -s /bin/bash hdfs \ -c "/usr/bin/hdfs dfs -chmod -R 755 /user/${USER}" $ sudo su -s /bin/bash hdfs \ -c "/usr/bin/hdfs dfs -chown ${USER} /user/${USER}" -
启动 Yarn 资源管理器和节点管理器:
```scala
$ sudo service hadoop-yarn-resourcemanager start
$ sudo service hadoop-yarn-nodemanager start
$ sudo service hadoop-mapreduce-historyserver start
```
11. 尝试使用以下命令验证安装:
```scala
$ hadoop fs -ls /
$ hadoop jar \
/usr/lib/hadoop-mapreduce/hadoop-mapreduce-examples.jar \
pi 10 1000
```
12. 您还可以使用http://<namenode_ip>:50070上提供的监控控制台监控 HDFS 的状态。
13. 使用 Bigtop 安装配置单元、HBase、Mahout 和 Pig,如下所示:
```scala
$ sudo yum install hive\*, hbase\*, mahout\*, pig\*
```
还有更多...
- 您可以按照cwiki.apache.org/confluence/…中给出的步骤使用基于傀儡的 Bigtop 集群安装
- 您还可以在云环境中设置 Hadoop v2 群集,我们将在下一章中讨论
HDFS 命令行文件操作
HDFS 是分布式文件系统,就像任何其他文件系统一样,它允许用户使用 shell 命令操作文件系统。 本食谱介绍了其中一些命令,并展示了如何使用 HDFS shell 命令。
值得注意的是,一些 HDFS 命令与最常用的 Unix 命令具有一一对应关系。 例如,考虑以下命令:
$ bin/hdfs dfs –cat /user/joe/foo.txt
该命令读取/user/joe/foo.txt文件并将其打印到屏幕上,就像 Unix 系统中的cat命令一样。
做好准备
按照设置 HDFS食谱或使用 Hadoop 分发版食谱在分布式集群环境中设置 Hadoop 生态系统来启动 HDFS 服务器。
怎么做……
-
运行以下命令以列出 HDFS 主目录的内容。 如果您的 HDFS 主目录不存在,请按照中的步骤 9 使用 Hadoop 分发版在分布式群集环境中设置 Hadoop 生态系统来创建 HDFS 主目录。
$ hdfs dfs -ls -
运行以下命令,在 HDFS 的主目录中创建名为
test的新目录:$ hdfs dfs -mkdir test -
HDFS 文件系统以
/作为根目录。 运行以下命令以列出 HDFS 中新创建的目录的内容:$ hdfs dfs -ls test -
运行以下命令将本地自述文件复制到
test:$ hdfs dfs -copyFromLocal README.txt test -
运行以下命令以列出
test目录:$ hdfs dfs -ls test Found 1 items -rw-r--r-- 1 joesupergroup1366 2013-12-05 07:06 /user/joe/test/README.txt -
运行以下命令将
/test/README.txt文件复制回本地目录:$ hdfs dfs –copyToLocal \ test/README.txt README-NEW.txt
它是如何工作的.
当命令发出时,HDFS 客户端将代表我们与 HDFS NameNode 对话并执行操作。 客户端将从HADOOP_HOME/etc/hadoop/conf目录中的配置中获取 NameNode。
但是,如果需要,我们可以使用完全限定路径强制客户端与特定的 NameNode 对话。 例如,hdfs://bar.foo.com:9000/data将要求客户端在端口9000处与在bar.foo.com上运行的 NameNode 对话。
还有更多...
HDFS 支持大多数 Unix 命令,如cp、mv和chown,它们遵循与前面讨论的命令相同的模式。 以下命令会列出所有可用的 HDFS shell 命令:
$ hdfs dfs -help
将特定命令与help一起使用将显示该命令的用法。
$ hdfs dfs –help du
在分布式集群环境中运行 wordcount 程序
本配方描述了如何在分布式 Hadoopv2 集群中运行 MapReduce 计算。
做好准备
按照设置 HDFS食谱或使用 Hadoop 分发版食谱在分布式集群环境中设置 Hadoop 生态系统来启动 Hadoop 群集。
怎么做……
现在,让我们在分布式 Hadoop v2 设置中运行 wordcount 示例:
-
将源存储库中的
wc-input目录上载到 HDFS 文件系统。 或者,您也可以上传任何其他文本文档集。$ hdfs dfs -copyFromLocal wc-input . -
执行
HADOOP_HOME目录中的 WordCount 示例:$ hadoop jar hcb-c1-samples.jar \ chapter1.WordCount \ wc-input wc-output -
运行以下命令以列出输出目录,然后查看结果:
$hdfs dfs -ls wc-output Found 3 items -rw-r--r-- 1 joesupergroup0 2013-11-09 09:04 /data/output1/_SUCCESS drwxr-xr-x - joesupergroup0 2013-11-09 09:04 /data/output1/_logs -rw-r--r-- 1 joesupergroup1306 2013-11-09 09:04 /data/output1/part-r-00000 $ hdfs dfs -cat wc-output/part*
它是如何工作的.
当我们提交作业时,Yar 会安排一个 MapReduce ApplicationMaster 来协调和执行计算。 ApplicationMaster 从 ResourceManager 请求必要的资源,并使用从资源请求接收的容器执行 MapReduce 计算。
还有更多...
您还可以通过 HDFS 监控 UI 访问http://NAMANODE:50070来查看 WordCount 应用的结果。
使用 DFSIO 对 HDFS 进行基准测试
Hadoop 包含几个基准测试,您可以使用它们来验证 HDFS 集群是否设置正确并按预期执行。 DFSIO 是 Hadoop 附带的基准测试,可用于分析 HDFS 集群的 I/O 性能。 本食谱展示了如何使用 DFSIO 对 HDFS 群集的读/写性能进行基准测试。
做好准备
在运行这些基准测试之前,您必须设置和部署 HDFS 和 Hadoop v2 Yarn MapReduce。 在 Hadoop 安装中找到hadoop-mapreduce-client-jobclient-*-tests.jar文件。
怎么做……
以下步骤将向您展示如何运行写入和读取 DFSIO 性能基准:
-
执行以下命令以运行 HDFS 写入性能基准。
–nrFiles参数指定基准要写入的文件数。 使用一个足够大的数字来饱和群集中的任务槽。-fileSize参数指定每个文件的文件大小(以 MB 为单位)。 根据您的 Hadoop 安装,在以下命令中更改hadoop-mapreduce-client-jobclient-*-tests.jar文件的位置。$ hadoop jar \ $HADOOP_HOME/share/hadoop/mapreduce/hadoop-mapreduce-client-jobclient-*-tests.jar \ TestDFSIO -write -nrFiles 32 –fileSize 1000 -
写入基准测试将结果写入控制台,并将其附加到名为
TestDFSIO_results.log的文件中。 您可以使用–resFile参数提供您自己的结果文件名。 -
以下步骤将向您展示如何运行 HDFS 读取性能基准测试。 读性能基准使用第一步中写基准写入的文件,因此在运行读基准之前应该先执行写基准,并且写基准写入的文件必须在 HDFS 中存在,读基准才能正常工作。 基准测试将结果写入控制台,并将结果附加到日志文件,这与写入基准测试类似。
$hadoop jar \ $HADOOP_HOME/share/Hadoop/mapreduce/hadoop-mapreduce-client-jobclient-*-tests.jar \ TestDFSIO -read \ -nrFiles 32 –fileSize 1000 -
可以使用以下命令清理由上述基准测试生成的文件:
$hadoop jar \ $HADOOP_HOME/share/Hadoop/mapreduce/hadoop-mapreduce-client-jobclient-*-tests.jar \ TestDFSIO -clean
它是如何工作的.
DFSIO 执行 MapReduce 作业,其中 Map 任务并行写入和读取文件,而 Reduce 任务用于收集和汇总性能数字。 您可以将此基准测试的吞吐量和 IO 速率结果与磁盘总数及其原始速度进行比较,以验证您是否从群集获得了预期的性能。 验证写入性能结果时,请注意复制因素。 由于某些原因,这些测试中的高标准偏差可能暗示有一个或多个表现不佳的节点。
还有更多...
将这些测试与监控系统一起运行可以帮助您轻松识别 Hadoop 集群的瓶颈。
使用 TeraSort 对 Hadoop MapReduce 进行基准测试
HadoopTeraSort 是一个众所周知的基准测试,旨在使用 Hadoop MapReduce 尽可能快地对 1TB 数据进行排序。 TeraSort 基准测试强调了 Hadoop MapReduce 框架的几乎每个部分以及 HDFS 文件系统,这使得它成为微调 Hadoop 集群配置的理想选择。
最初的 TeraSort 基准对 1000 万条 100 字节的记录进行排序,总数据大小为 1TB。 但是,我们可以指定记录的数量,从而可以配置数据的总大小。
做好准备
在运行这些基准测试之前,您必须设置和部署 HDFS 和 Hadoop v2 Yarn MapReduce,并在 Hadoop 安装中找到hadoop-mapreduce-examples-*.jar文件。
怎么做……
以下步骤将向您展示如何在 Hadoop 群集上运行 TeraSort 基准测试:
-
The first step of the TeraSort benchmark is the data generation. You can use the
teragencommand to generate the input data for the TeraSort benchmark. The first parameter ofteragenis the number of records and the second parameter is the HDFS directory to generate the data. The following command generates 1 GB of data consisting of 10 million records to thetera-indirectory in HDFS. Change the location of thehadoop-mapreduce-examples-*.jarfile in the following commands according to your Hadoop installation:$ hadoop jar \ $HADOOP_HOME/share/Hadoop/mapreduce/hadoop-mapreduce-examples-*.jar \ teragen 10000000 tera-in提示
为
teragen计算指定 Map 任务的数量是一个好主意,以加快数据生成速度。 这可以通过指定–Dmapred.map.tasks参数来实现。此外,您还可以增加生成数据的 HDFS 块大小,以便 TeraSort 计算的 Map 任务的粒度更粗(Hadoop 计算的 Map 任务的数量通常等于输入数据块的数量)。 这可以通过指定
–Ddfs.block.size参数来实现。$ hadoop jar $HADOOP_HOME/share/hadoop/mapreduce/hadoop-mapreduce-examples-*.jar \ teragen –Ddfs.block.size=536870912 \ –Dmapred.map.tasks=256 10000000 tera-in -
The second step of the TeraSort benchmark is the execution of the TeraSort MapReduce computation on the data generated in step 1 using the following command. The first parameter of the
terasortcommand is the input of HDFS data directory, and the second part of theterasortcommand is the output of the HDFS data directory.$ hadoop jar \ $HADOOP_HOME/share/hadoop/mapreduce/hadoop-mapreduce-examples-*.jar \ terasort tera-in tera-out提示
最好为 TeraSort 计算指定 Reduce 任务的数量,以加快计算的 Reducer 部分。 这可以通过指定
–Dmapred.reduce.tasks参数来实现,如下所示:$ hadoop jar $HADOOP_HOME/share/hadoop/mapreduce/hadoop-mapreduce-examples-*.jar terasort –Dmapred.reduce.tasks=32 tera-in tera-out -
TeraSort 基准测试的最后一步是验证结果。 这可以通过使用
teravalidate应用来完成,如下所示。 第一个参数是包含排序数据的目录,第二个参数是存储包含结果的报告的目录。$ hadoop jar \ $HADOOP_HOME/share/hadoop/mapreduce/hadoop-mapreduce-examples-*.jar \ teravalidate tera-out tera-validate
它是如何工作的.
TeraSort 使用 MapReduce 框架的排序功能和自定义范围分割器在 Reduce 任务之间划分 Map 输出,以确保全局排序顺序。*
二、云部署——在云环境中使用 Hadoop Yarn
在本章中,我们将介绍以下食谱:
- 使用 Amazon Elastic MapReduce 运行 Hadoop MapReduce v2 计算
- 使用 Amazon EC2 Spot 实例执行 EMR 作业流节省资金
- 使用 EMR 执行 Pig 脚本
- 使用 EMR 执行配置单元脚本
- 使用 AWS 命令行界面创建 Amazon EMR 作业流
- 使用 EMR 在 Amazon EC2 上部署 Apache HBase 群集
- 使用 EMR 引导操作为 Amazon EMR 作业配置虚拟机
- 使用 Apache Whirr 在 EC2 环境中部署 Apache Hadoop 群集
简介
在本章中,我们将探索在云环境中部署和执行 Hadoop MapReduce v2 和其他 Hadoop 相关计算的几种机制。
像 Amazon EC2 和 Microsoft Azure 这样的云计算环境通过 Web 以服务的形式提供按需计算和存储资源。 这些云计算环境使我们能够在不需要前期资本投资的情况下执行偶尔的大规模 Hadoop 计算,并且只需要为实际的使用付费。 使用云环境的另一个优势是能够以最小的额外成本水平扩展计算资源的数量,从而提高 Hadoop 计算的吞吐量。 例如,使用 10 个云实例 100 小时的成本相当于使用 100 个云实例 10 小时的成本。 除了存储、计算和托管 MapReduce 服务之外,这些云环境还提供许多其他分布式计算服务,在实现整个应用体系结构时,您可能会发现这些服务很有用。
虽然云环境比传统的同类环境具有许多优势,但由于基础设施的虚拟化、多租户特性,它们也带来了几个独特的可靠性和性能挑战。 对于数据密集型 Hadoop 计算,主要挑战之一将是将大型数据集传入和传出云环境。 我们还需要确保使用永久存储介质来存储您需要保存的任何数据。 云实例的临时实例存储中存储的任何数据都将在这些实例终止时丢失。
与 Microsoft Azure 云等其他商业云产品相比,由于 Linux 实例支持的成熟度和托管 Hadoop 服务的成熟度,我们将主要使用 Amazon AWS 云作为本章的食谱。
本章将指导您使用托管 Hadoop 基础设施 AmazonElastic MapReduce(EMR)在 Amazon EC2 基础设施上执行传统的 MapReduce 计算以及 PIG 和 Hive 计算。 本章还介绍了如何使用 Amazon EMR 调配 HBase 群集,以及如何备份和恢复 EMR HBase 群集的数据。 我们还将使用 Apache Whirr,一个用于在云环境中部署服务的云中立库,在云环境中配置 Apache Hadoop 和 Apache HBase 集群。
提示
示例代码
本书的示例代码文件位于github.com/thilg/hcb-v…存储库中。 代码库的chapter2文件夹包含本章的示例源代码文件。
使用 Amazon Elastic MapReduce 运行 Hadoop MapReduce v2 计算
Amazon Elastic MapReduce(EMR)在 Amazon Web Services(AWS)云中提供按需管理的 Hadoop 群集来执行 Hadoop MapReduce 计算。 EMR 使用 AmazonElastic Compute Cloud(EC2)实例作为计算资源。 EMR 支持从 AmazonSimple Storage Service(S3)读取输入数据,并将输出数据存储在 Amazon S3 中。 EMR 负责云实例的配置、Hadoop 集群的配置以及 MapReduce 计算流的执行。
在本配方中,我们将使用 Amazon Elastic MapReduce 服务在 Amazon EC2 中执行 wordcount MapReduce 示例(编写 Wordcount MapReduce 应用,将其捆绑,并使用第 1 章,Hadoop v2中的 Hadoop 本地模式配方运行)。
做好准备
通过运行示例代码存储库的chapter1文件夹中的 Gradle 构建来构建hcb-c1-samples.jar文件。
怎么做……
以下是在 Amazon Elastic MapReduce 上执行 Wordcount MapReduce 应用的步骤:
-
通过访问aws.amazon.com注册。
-
在console.aws.amazon.com/s3打开 Amazon S3 监控控制台并登录。
-
通过单击创建存储桶,创建一个S3 存储桶以上传输入数据。 为您的存储桶提供唯一的名称。 让我们假设存储桶的名称是
wc-input-data。 您可以在docs.amazonwebservices.com/AmazonS3/la…找到有关创建 S3 存储桶的更多信息。 亚马逊 S3 还存在多个第三方桌面客户端。 您也可以使用其中一个客户端来管理 S3 中的数据。 -
Upload your input data to the bucket we just created by selecting the bucket and clicking on Upload. The input data for the WordCount sample should be one or more text files:
-
创建一个 S3 存储桶来上传我们的 MapReduce 计算所需的 JAR 文件。 让我们假设存储桶的名称为
sample-jars。 将hcb-c1-samples.jar上传到新创建的存储桶中。 -
Create an S3 bucket to store the output data of the computation. Let's assume the name of this bucket as
wc-output-data. Create another S3 bucket to store the logs of the computation. Let's assume the name of this bucket ishcb-c2-logs.备注
请注意,所有 S3 用户共享 S3 存储桶命名空间。 因此,使用本食谱中给出的示例存储桶名称可能对您不起作用。 在这种情况下,您应该为存储桶指定您自己的自定义名称,并在本食谱的后续步骤中替换这些名称。
-
在console.aws.amazon.com/elasticmapr…打开亚马逊电子邮件记录控制台。 单击Create Cluster按钮创建新的电子病历群集。 为您的群集提供名称。
-
In the Log folder S3 location textbox, enter the path of the S3 bucket you created earlier to store the logs. Select the Enabled radio button for Debugging.
-
在软件配置部分中选择 Hadoop 发行版和版本。 选择带有 Amazon Hadoop 发行版的 AMI 版本 3.0.3 或更高版本以部署 Hadoop v2 群集。 保留要安装的应用部分中的默认选定应用(Hive、PIG 和色调)。
-
Select the EC2 instance types, instance counts, and the availability zone in the Hardware Configuration section. The default options use two EC2 m1.large instances for the Hadoop slave nodes and one EC2 m1.large instance for the Hadoop Master node.

- 保留Security and Access和Bootstrap Actions部分中的默认选项。
- Select the Custom Jar option under the Add Step dropdown of the Steps section. Click on Configure and add to configure the JAR file for our computation. Specify the S3 location of
hcb-c1-samples.jarin the Jar S3 location textbox. You should specify the location of the JAR in the formats3n://bucket_name/jar_name. In the Arguments textbox, typechapter1.WordCountfollowed by the bucket location where you uploaded the input data in step 4 and the output data bucket you created in step 6. The output path should not exist and we use a directory (for example,wc-output-data/out1) inside the output bucket you created in step 6 as the output path. You should specify the locations using the format,s3n://bucket_name/path.

- Click on Create Cluster to launch the EMR Hadoop cluster and run the WordCount application.
### 备注
在第 13 步中单击**创建群集**时,Amazon 将为您使用的计算和存储资源收费。请参阅*使用 Amazon EC2 Spot 实例执行 EMR 作业流*食谱,了解如何通过使用 Amazon EC2 Spot 实例来节省资金。
请注意,AWS 按小时向您收费,任何部分使用都将按小时计费。 实例的每次启动和停止都将按小时计费,即使只需要几分钟。 为进行测试而频繁重新启动群集时,请注意相关费用。
14. Monitor the progress of your MapReduce cluster deployment and the computation in the Cluster List | Cluster Details page of the Elastic MapReduce console. Expand the Steps section of the page to see the status of the individual steps of the cluster setup and the application execution. Select a step and click on View logs to view the logs and to debug the computation. Since EMR uploads the logfiles periodically, you might have to wait and refresh to access the logfiles. Check the output of the computation in the output data bucket using the AWS S3 console.

15. 终止您的集群以避免为剩余实例计费。 但是,您可以让集群继续运行,以尝试本章中的其他食谱。
另请参阅
- 编写字数计数 MapReduce 应用,将其捆绑在一起,并使用第 1 章,《Hadoop v2 入门》中的 Hadoop 本地模式配方运行它
- 在分布式群集环境中运行 wordcount 程序的Hadoop v2快速入门中的章,中的秘诀
使用 Amazon EC2 Spot 实例执行 EMR 作业流可节省资金
AmazonEC2 Spot 实例允许我们以的大幅折扣购买未充分利用的 EC2 计算资源。 Spot 实例的价格根据需求而变化。 我们可以为 Spot 实例提交投标,如果我们的出价超过当前 Spot 实例价格,我们将收到所请求的计算实例。 亚马逊根据 Spot 实例的实际价格向这些实例收费,该价格可能低于您的出价。 如果 Spot 实例价格超过您的出价,亚马逊将终止您的实例。 但是,如果亚马逊终止您的实例,亚马逊不会按部分 Spot 实例小时数收费。 您可以在aws.amazon.com/ec2/spot-in…上找到有关 AmazonEC2 Spot 实例的更多信息。
Amazon EMR 支持将 Spot 实例用作主实例和辅助计算实例。 Spot 实例是执行批处理作业等非时间关键型计算的理想选择。
怎么做……
以下步骤说明如何将 Amazon EC2 Spot 实例与 Amazon Elastic MapReduce 配合使用,以执行 Wordcount MapReduce 应用:
-
按照使用 Amazon Elastic MapReduce 配方运行 Hadoop MapReduce v2 计算的中的步骤 1 到 9 操作。
-
在硬件配置部分中配置 EMR 群集以使用 Spot 实例。 (请参阅使用 Amazon Elastic MapReduce配方运行 Hadoop MapReduce v2 计算的步骤 10)。 在Hardware Configuration部分中,选中实例类型旁边的Request Spot复选框。
-
Specify your bid price in the Bid price textboxes. You can find the Spot Instance pricing history in the Spot Requests window of the Amazon EC2 console (console.aws.amazon.com/ec2).
-
按照使用 Amazon Elastic MapReduce 配方运行 Hadoop MapReduce v2 计算的步骤 11 到 16 进行操作。
还有更多...
您还可以在传统 EC2 按需实例和 EC2 Spot 实例的组合上运行 EMR 计算,从而安全地保护您的计算免受 Spot 实例可能终止的影响。
由于 Amazon 使用当前 Spot 价格对 Spot 实例进行计费,而不考虑您的出价,因此最好不要将 Spot 实例价格设置得太低,以避免频繁终止的风险。
另请参阅
运行 Hadoop MapReduce v2 计算的使用 Amazon Elastic MapReduce配方。
使用 EMR 执行 Pig 脚本
AmazonEMR 支持对存储在 S3 中的数据执行 Apache Pig 脚本。 有关使用 Apache Pig 进行数据分析的更多详细信息,请参阅第 7 章、Hadoop 生态系统 II 中的Pig 相关食谱-Pig、HBase、Mahout 和 Sqoop*。*
*在本食谱中,我们将使用 Amazon EMR 执行一个简单的 Pig 脚本。 此示例将使用人类发展报告数据(hdr.undp.org/en/statisti…)打印按 GNI 排序的人均国民总收入大于 2,000 美元的国家名称。
怎么做……
以下步骤向您展示了如何将 Pig 脚本与 Amazon Elastic MapReduce 一起使用来处理存储在 Amazon S3 上的数据集:
-
使用 Amazon S3 控制台在 S3 中创建一个存储桶来上传输入数据。 将本章源存储库中的
resources/hdi-data.csv文件上传到新创建的存储桶中。 您还可以使用现有存储桶或存储桶内的目录。 我们假设上载文件的 S3 路径为hcb-c2-data/hdi-data.csv。 -
查看本章源代码存储库的
resources/countryFilter-EMR.pig文件中提供的 Pig 脚本。 此脚本使用STORE命令将结果保存在文件系统中。 此外,我们通过添加$INPUT作为输入文件来参数化 Pig 脚本的LOAD命令,并通过添加$OUTPUT作为输出目录来参数化 store 命令。 这两个参数将替换为我们在步骤 5 中指定的 S3 输入和输出位置。A = LOAD '$INPUT' using PigStorage(',') AS (id:int, country:chararray, hdi:float, lifeex:int, mysch:int, eysch:int, gni:int); B = FILTER A BY gni > 2000; C = ORDER B BY gni; STORE C into '$OUTPUT'; -
使用 Amazon S3 控制台在 S3 中创建存储桶以上传 Pig 脚本。 将
resources/countryFilter-EMR.pig脚本上传到新创建的存储桶中。 您还可以使用现有存储桶或存储桶内的目录。 我们假设上载文件的 S3 路径为hcb-c2-resources/countryFilter-EMR.pig。 -
Open the Amazon EMR console at console.aws.amazon.com/elasticmapr…. Click on the Create Cluster button to create a new EMR cluster. Provide a name for your cluster. Follow steps 8 to 11 of the Running Hadoop MapReduce v2 computations using Amazon Elastic MapReduce recipe to configure your cluster.
备注
您可以使用 Amazon Elastic MapReduce 配方重用在运行 Hadoop MapReduce v2 计算的中创建的 EMR 集群,以遵循本配方的步骤。 为此,请使用正在运行的集群的Cluster Details页面中的Add Step选项来执行步骤 5 中提到的操作。
-
Select the Pig Program option under the Add Step dropdown of the Steps section. Click on Configure and add to configure the Pig script, input, and output data for our computation. Specify the S3 location of the Pig script we uploaded in step 3, in the Script S3 location textbox. You should specify the location of the script in the format
s3://bucket_name/script_filename. Specify the S3 location of the uploaded input data file in the Input S3 Location textbox. In the Output S3 Location textbox, specify an S3 location to store the output. The output path should not exist; we use a non-existing directory (for example,hcb-c2-out/pig) inside the output bucket as the output path. You should specify the locations using the formats3://bucket_name/path. Click on Add. -
Click on Create Cluster to launch the EMR Hadoop cluster and to run the configured Pig script.
备注
Amazon 将在第 8 步中单击Create Job Flow,对您使用的计算和存储资源收费。请参阅我们之前讨论的使用 EC2 Spot 实例执行 EMR 作业流食谱,了解如何通过使用 Amazon EC2 Spot 实例来节省资金。
-
在 Elastic MapReduce 控制台的群集列表|群集详细信息页面中监视 MapReduce 群集部署和计算的进度。 展开并刷新页面的步骤部分,查看集群设置和应用执行的各个步骤的状态。 选择一个步骤并单击查看日志以查看日志并调试计算。 使用 AWS S3 控制台检查输出数据桶中的计算输出。
还有更多...
Amazon EMR 还允许我们在交互模式下使用 Apache Pig。
启动 PIG 互动会话
-
在console.aws.amazon.com/elasticmapr…打开亚马逊电子邮件记录控制台。 单击Create Cluster按钮创建新的电子病历群集。 为您的群集提供名称。
-
您必须从安全和访问部分的Amazon EC2 密钥对下拉列表中选择密钥对。 如果您没有可用的 Amazon EC2 密钥对访问私钥,请登录 Amazon EC2 控制台并创建新的密钥对。
-
在不指定任何步骤的情况下,单击创建集群。 确保在步骤部分下的自动终止选项中选择了否。
-
Monitor the progress of your MapReduce cluster deployment and the computation in the Cluster Details page under Cluster List of the Elastic MapReduce console. Retrieve Master Public DNS from the cluster details in this page.
-
使用步骤 2 中指定的 Amazon EC2 密钥对的主公共 DNS 名称和私钥文件通过 SSH 连接到集群的主节点:
$ ssh -i <path-to-the-key-file> hadoop@<master-public-DNS> -
在主节点中启动 Pig 交互式 Grunt shell 并发出您的 Pig 命令:
$ pig ......... grunt>
使用 EMR 执行配置单元脚本
HIVE 利用其下的 Hadoop MapReduce 为 HDFS 中存储的数据提供了类似 SQL 的查询层。 Amazon EMR 支持对存储在 S3 中的数据执行配置单元查询。 有关使用配置单元进行大规模数据分析的更多信息,请参阅章、Hadoop 生态系统-Apache 配置单元中的 Apache Have 配方。
在这个配方中,我们将执行一个配置单元脚本,以执行前面使用 EMR 配方在Executing a Pig 脚本中执行的计算。 我们将使用“人类发展报告”数据(hdr.undp.org/en/statisti…)打印按国民总收入排序的国民总收入大于人均国民总收入 2,000 美元的国家的名称。
怎么做……
以下步骤显示如何将配置单元脚本与 Amazon Elastic MapReduce 配合使用,以查询存储在 Amazon S3 上的数据集:
-
使用 Amazon S3 控制台在 S3 中创建一个存储桶来上传输入数据。 在存储桶内创建一个目录。 将本章源包中的
resources/hdi-data.csv文件上传到存储桶内新创建的目录中。 您还可以使用现有存储桶或存储桶内的目录。 我们假设上载文件的 S3 路径为hcb-c2-data/data/hdi-data.csv。 -
查看本章来源资料库的
resources/countryFilter-EMR.hql文件中提供的配置单元脚本。 该脚本首先创建输入数据到配置单元表的映射。 然后,我们创建一个配置单元表来存储查询结果。 最后,我们发出一个查询以选择国民总收入大于 2000 美元的国家/地区列表。 我们使用$INPUT和$OUTPUT变量来指定输入数据的位置和存储输出表数据的位置。CREATE EXTERNAL TABLE hdi( id INT, country STRING, hdi FLOAT, lifeex INT, mysch INT, eysch INT, gni INT) ROW FORMAT DELIMITED FIELDS TERMINATED BY ',' STORED AS TEXTFILE LOCATION '${INPUT}'; CREATE EXTERNAL TABLE output_countries( country STRING, gni INT) ROW FORMAT DELIMITED FIELDS TERMINATED BY ',' STORED AS TEXTFILE LOCATION '${OUTPUT}'; INSERT OVERWRITE TABLE output_countries SELECT country, gni FROM hdi WHERE gni > 2000; -
使用 Amazon S3 控制台在 S3 中创建存储桶以上传配置单元脚本。 将
resources/countryFilter-EMR.hql脚本上传到新创建的存储桶中。 您还可以使用现有存储桶或存储桶内的目录。 我们假设上载文件的 S3 路径为hcb-resources/countryFilter-EMR.hql。 -
Open the Amazon EMR console at console.aws.amazon.com/elasticmapr…. Click on the Create Cluster button to create a new EMR cluster. Provide a name for your cluster. Follow steps 8 to 11 of the Running Hadoop MapReduce v2 computations using Amazon Elastic MapReduce recipe to configure your cluster.
备注
您可以重用为前面的某个食谱创建的 EMR 集群,以遵循本食谱的步骤。 为此,请使用正在运行的集群的Cluster Details页面中的Add Step选项来执行步骤 5 中提到的操作。
-
Select the Hive Program option under the Add Step dropdown of the Steps section. Click on Configure and add to configure the Hive script, and input and output data for our computation. Specify the S3 location of the Hive script we uploaded in step 3 in the Script S3 location textbox. You should specify the location of the script in the format
s3://bucket_name/script_filename. Specify the S3 location of the uploaded input data directory in the Input S3 Location textbox. In the Output S3 Location textbox, specify an S3 location to store the output. The output path should not exist and we use a nonexisting directory (for example,hcb-c2-out/hive) inside the output bucket as the output path. You should specify the locations using the formats3://bucket_name/path. Click on Add. -
Click on Create Cluster to launch the EMR Hadoop cluster and to run the configured Hive script.
备注
Amazon 将在第 8 步中单击Create Job Flow,对您使用的计算和存储资源收费。请参阅前面讨论的使用 Amazon EC2 Spot 实例执行 EMR 作业流来执行 EMR 作业流食谱,了解如何通过使用 Amazon EC2 Spot 实例来节省资金。
-
在 Elastic MapReduce 控制台的群集列表下的群集详细信息页面中监视 MapReduce 群集部署和计算的进度。 展开并刷新页面的步骤部分,查看集群设置和应用执行的各个步骤的状态。 选择一个步骤并单击查看日志以查看日志并调试计算。 使用 AWS S3 控制台检查输出数据桶中的计算输出。
还有更多...
Amazon EMR 还允许我们在交互模式下使用 Hive 外壳。
启动配置单元互动会话
按照前面的中的启动 Pig 交互式会话部分中的步骤 1 到 5,使用 EMR配方执行 Pig 脚本,创建一个集群并使用 SSH 登录到该集群。
在主节点中启动配置单元外壳,并发出您的配置单元查询:
$ hive
hive >
.........
另请参阅
第 6 章,Hadoop 生态系统的章,的简单 SQL 样式的数据查询使用 Apache Have配方-Apache Have。**
使用 AWS 命令行界面创建 Amazon EMR 作业流
AWS命令行界面(CLI)是一个允许我们从命令行管理我们的 AWS 服务的工具。 在本配方中,我们使用 AWS CLI 来管理 Amazon EMR 服务。
此配方使用 AWS CLI 创建一个 EMR 作业流,以执行本章使用 Amazon Elastic MapReduce 配方运行 Hadoop MapReduce 计算的中的 WordCount 示例。
做好准备
以下是开始使用本食谱的前提条件:
- Python 2.6.3 或更高版本
- PIP-Python 包管理系统
怎么做……
以下步骤显示了如何使用 EMR 命令行界面创建 EMR 作业流:
-
Install AWS CLI in your machine using the pip installer:
$ sudo pip install awscli备注
有关安装 AWS CLI 的更多信息,请参阅docs.aws.amazon.com/cli/latest/…。 本指南提供了在不使用
sudo的情况下安装 AWS CLI 的说明,以及使用其他方法安装 AWS CLI 的说明。 -
通过登录 AWS IAM 控制台(console.aws.amazon.com/iam)创建访问密钥 ID 和秘密访问密钥。 下载密钥文件并将其保存在安全位置。
-
Use the
aws configureutility to configure your AWS account to the AWC CLI. Provide the access key ID and the secret access key you obtained in the previous step. This information would get stored in the.aws/configand.aws/credentialsfiles in your home directory.$ aws configure AWS Access Key ID [None]: AKIA…. AWS Secret Access Key [None]: GC… Default region name [None]: us-east-1a Default output format [None]:提示
如果您已完成本章中使用 Amazon Elastic MapReduce 进行 Hadoop MapReduce 计算的运行 Hadoop MapReduce 计算中的步骤 2 至 6,则可以跳到步骤 7。
-
在 AmazonS3 监控控制台(console.aws.amazon.com/s3)中单击create Bucket,创建一个存储桶来上传输入数据。 为您的存储桶提供一个唯一的名称。 通过选择存储桶并单击Upload将输入数据上传到新创建的存储桶。 WordCount 示例的输入数据应该是一个或多个文本文件。
-
创建一个 S3 存储桶来上传我们的 MapReduce 计算所需的 JAR 文件。 上传
hcb-c1-samples.jar到新创建的存储桶中。 -
创建一个 S3 存储桶来存储计算的输出数据。 创建另一个 S3 存储桶来存储计算日志。 让我们假设这个存储桶的名称是
hcb-c2-logs。 -
通过执行以下命令创建 EMR 集群。 此命令将输出创建的 EMR 群集的群集 ID:
$ aws emr create-cluster --ami-version 3.1.0 \ --log-uri s3://hcb-c2-logs \ --instance-groups \ InstanceGroupType=MASTER,InstanceCount=1,\ InstanceType=m3.xlarge \ InstanceGroupType=CORE,InstanceCount=2,\ InstanceType=m3.xlarge { “ClusterId”: “j-2X9TDN6T041ZZ” } -
您可以使用
list-clusters命令检查创建的 EMR 群集的状态:$ aws emr list-clusters { “Clusters”: [ { “Status”: { “Timeline”: { “ReadyDateTime”: 1421128629.1830001, “CreationDateTime”: 1421128354.4130001 }, “State”: “WAITING”, “StateChangeReason”: { “Message”: “Waiting after step completed” } }, “NormalizedInstanceHours”: 24, “Id”: “j-2X9TDN6T041ZZ”, “Name”: “Development Cluster” } ] } -
通过执行以下命令将作业步骤添加到此 EMR 集群。 将 JAR 文件的路径、输入数据位置和输出数据位置替换为步骤 5、6 和 7 中使用的位置。将
cluster-id替换为新创建的 EMR 集群的集群 ID。$ aws emr add-steps \ --cluster-id j-2X9TDN6T041ZZ \ --steps Type=CUSTOM_JAR,Name=CustomJAR,ActionOnFailure=CONTINUE,\ Jar=s3n://[S3 jar file bucket]/hcb-c1-samples.jar,\ Args=chapter1.WordCount,\ s3n://[S3 input data path]/*,\ s3n://[S3 output data path]/wc-out { “StepIds”: [ “s-1SEEPDZ99H3Y2” ] } -
使用
describe-step命令检查提交的作业步骤的状态,如下所示。 您还可以使用 Amazon EMR 控制台(console.aws.amazon.com/elasticmapr…)检查状态并调试作业流。
```scala
$ aws emr describe-step \
–cluster-id j-2X9TDN6T041ZZ \
–step-id s-1SEEPDZ99H3Y2
```
11. 作业流完成后,使用 S3 控制台在输出数据位置检查计算结果。
12. 使用terminate-clusters命令终止群集:
```scala
$ aws emr terminate-clusters --cluster-ids j-2X9TDN6T041ZZ
```
还有更多...
您可以将 EC2 Spot 实例与 EMR 集群配合使用,以降低计算成本。 通过将--BidPrice参数添加到您的create-cluster命令的实例组,将投标价格添加到您的请求中:
$ aws emr create-cluster --ami-version 3.1.0 \
--log-uri s3://hcb-c2-logs \
--instance-groups \
InstanceGroupType=MASTER,InstanceCount=1,\
InstanceType=m3.xlarge,BidPrice=0.10 \
InstanceGroupType=CORE,InstanceCount=2,\
InstanceType=m3.xlarge,BidPrice=0.10
有关 Amazon Spot 实例的更多详细信息,请参阅本章中的使用 Amazon EC2 Spot 实例执行 EMR 作业流食谱。
另请参阅
- 本章的使用 Amazon Elastic MapReduce配方运行 Hadoop MapReduce 计算
- 您可以在docs.aws.amazon.com/cli/latest/…找到 AWS CLI 电子病历部分的参考文档
使用 EMR 在 Amazon EC2 上部署 Apache HBase 群集
我们可以使用 Amazon Elastic MapReduce 在 Amazon 基础设施上启动 Apache HBase 集群,以便在面向列的数据存储中存储大量数据。 我们还可以将存储在 Amazon EMR HBase 集群上的数据用作 EMR MapReduce 计算的输入和输出。 我们可以将存储在 Amazon EMR HBase 群集中的数据增量备份到 Amazon S3 以实现数据持久性。 我们还可以通过从以前的 S3 备份恢复数据来启动 EMR HBase 群集。
在本食谱中,我们使用 Amazon EMR 在 Amazon EC2 上启动 Apache HBase 群集;在新创建的 HBase 群集上执行几个简单操作,并在关闭群集之前将 HBase 数据备份到 Amazon S3。 然后,我们启动一个新的 HBase 集群,从原来的 HBase 集群恢复 HBase 数据备份。
做好准备
您应该安装 AWS CLI 并将其配置为手动备份 HBase 数据。 有关安装和配置 AWS CLI 的详细信息,请参阅本章中的使用 AWS 命令行界面配方创建 Amazon EMR 作业流。
怎么做……
以下步骤显示如何使用 Amazon EMR 在 Amazon EC2 上部署 Apache HBase 群集:
-
创建一个 S3 存储桶来存储 HBase 备份。 我们假设 HBase 数据备份的 S3 存储桶为
hcb-c2-data。 -
在console.aws.amazon.com/elasticmapr…打开 Amazon EMR 控制台。 单击Create Cluster按钮创建新的电子病历群集。 为您的群集提供名称。
-
在日志文件夹 S3 位置中提供路径,并选择具有 Hadoop v2 的AMI 版本(例如,具有 Hadoop 2.4.0 的 AMI 版本 3.1.0)。
-
从要安装的应用部分下的其他应用下拉框中选择HBase。 单击配置并添加。
-
Make sure the Restore from backup radio button is not selected. Select the Schedule regular backups and Consistent Backup radio buttons. Specify a Backup frequency for automatic scheduled incremental data backups and provide a path inside the Blob we created in step 1 as the backup location. Click on Continue.
-
在硬件配置部分配置 EC2 实例。
-
Select a key pair in the Amazon EC2 Key Pair drop-down box. Make sure you have the private key for the selected EC2 key pair downloaded on your computer.
备注
如果没有可用的密钥对,请转到 EC2 控制台(console.aws.amazon.com/ec2)创建密钥对。 要创建密钥对,请登录 EC2 仪表板,选择一个区域,然后单击网络和安全菜单下的密钥对。 单击密钥对窗口中的创建密钥对按钮,并提供新密钥对的名称。 下载私钥文件(PEM 格式)并将其保存在安全位置。
-
Click on the Create Cluster button to deploy the EMR HBase cluster.
备注
Amazon 将通过单击上一步中的Create Cluster向您收取您使用的计算和存储资源的费用。 请参考前面讨论的使用 Amazon EC2 Spot 实例执行 EMR 工作流食谱,了解如何通过使用 Amazon EC2 Spot 实例来节省资金。
以下步骤将向您展示如何连接到已部署的 HBase 集群的主节点以启动 HBase shell:
-
转到 Amazon EMR 控制台(console.aws.amazon.com/elasticmapr…)。 选择 HBase 群集的群集详细信息以查看有关该群集的更多信息。 从信息窗格中检索主公共 DNS 名称。
-
使用主公共 DNS 名称和基于 EC2 PEM 的密钥(在步骤 4 中选择)连接到 HBase 群集的主节点:
$ ssh -i ec2.pem hadoop@ec2-184-72-138-2.compute-1.amazonaws.com -
Start the HBase shell using the
hbase shellcommand. Create a table named'test'in your HBase installation and insert a sample entry to the table using theputcommand. Use thescancommand to view the contents of the table.$ hbase shell ......... hbase(main):001:0> create 'test','cf' 0 row(s) in 2.5800 seconds hbase(main):002:0> put 'test','row1','cf:a','value1' 0 row(s) in 0.1570 seconds hbase(main):003:0> scan 'test' ROW COLUMN+CELL row1 column=cf:a, timestamp=1347261400477, value=value1 1 row(s) in 0.0440 seconds hbase(main):004:0> quit下面的步将备份存储在 Amazon EMR HBase 群集中的数据。
-
使用 AWS CLI 执行以下命令,计划对 EMR HBase 集群中存储的数据进行定期备份。 从 EMR 控制台检索群集 ID(例如,
j-FDMXCBZP9P85)。 使用检索到的作业流名称替换<cluster_id>。 根据您的备份数据 Blob 更改备份目录路径(s3://hcb-c2-data/hbase-backup)。 等待几分钟以执行备份。$ aws emr schedule-hbase-backup --cluster-id <cluster_id> \ --type full –dir s3://hcb-c2-data/hbase-backup \ --interval 1 --unit hours -
Go to the Cluster Details page in the EMR console and click on Terminate.
现在,我们将通过从备份恢复数据来启动新的 Amazon EMR HBase 群集:
-
通过单击 EMR 控制台中的Create Clusters按钮创建新的作业流。 为您的群集提供名称。 在Log Folder S3 位置中提供路径,并选择具有 Hadoop v2 的 AMI 版本(例如,具有 Hadoop 2.4.0 的 AMI 版本 3.1.0)。
-
从要安装的应用部分下的其他应用下拉框中选择HBase。 单击配置并添加。
-
配置 EMR HBase 群集以从以前的数据备份恢复数据。 选择从备份还原选项,并在备份位置文本框中提供您在步骤 9 中使用的备份目录路径。 您可以将备份版本文本框留空,电子病历将还原最新的备份。 单击继续。
-
重复步骤 4、5、6 和 7。
-
登录到?启动 HBase shell。 新 HBase 群集的主节点。 使用
list命令列出 HBase 中的集合表格,使用scan 'test'命令查看'test'表格的内容。
```scala
$ hbase shell
.........
hbase(main):001:0> list
TABLE
test
1 row(s) in 1.4870 seconds
hbase(main):002:0> scan 'test'
ROW COLUMN+CELL
row1 column=cf:a, timestamp=1347318118294, value=value1
1 row(s) in 0.2030 seconds
```
11. 通过转到Cluster Details页面并单击Terminate按钮,使用 EMR 控制台终止您的群集。
另请参阅
第 7 章、Hadoop 生态系统 II 中与 HBase 相关的配方--Pig、HBase、Mahout 和 Sqoop。
使用 EMR 引导操作为 Amazon EMR 作业配置虚拟机
EMR 引导操作为我们提供了一种在运行 MapReduce 计算之前配置 EC2 实例的机制。 引导操作的示例包括为 Hadoop 提供自定义配置、安装任何相关软件、分发公共数据集等。 Amazon 提供了一组预定义的引导操作,并允许我们编写自己的自定义引导操作。 EMR 在启动 Hadoop 群集服务之前在每个实例中运行引导操作。
在本食谱中,我们将使用停用词列表从单词计数示例中筛选出常用单词。 我们使用自定义引导操作将停止单词列表下载到工人。
怎么做……
以下步骤显示如何使用引导脚本将文件下载到 EMR 计算的所有 EC2 实例:
-
将以下脚本保存到名为
download-stopwords.sh的文件中。 将文件上传到 Amazon S3 中的 Blob 容器。 此自定义引导文件将停用词列表下载到每个实例,并将其复制到实例内的预先指定的目录中。#!/bin/bash set -e wget http://www.textfixer.com/resources/common-english-words-with-contractions.txt mkdir –p /home/hadoop/stopwords mv common-english-words-with-contractions.txt /home/hadoop/stopwords -
完成本章中使用 Amazon Elastic MapReduce 配方运行 Hadoop MapReduce 计算的步骤 1 至 10。
-
Select the Add Bootstrap Actions option in the Bootstrap Actions tab. Select Custom Action in the Add Bootstrap Actions drop-down box. Click on Configure and add. Give a name to your action in the Name textbox and provide the S3 path of the location where you uploaded the
download-stopwords.shfile in the S3 location textbox. Click on Add. -
如果需要,添加步骤。
-
单击创建集群按钮启动实例并部署 MapReduce 集群。
-
单击 EMR 控制台中的刷新,然后转到群集详细信息页面以查看群集的详细信息。
还有更多...
Amazon 为我们提供了以下预定义的引导操作:
configure-daemons:这允许我们为 Hadoop 守护进程设置Java 虚拟机(JVM)选项,比如堆大小和垃圾收集行为。configure-hadoop:这允许我们修改 Hadoop 配置设置。 我们可以上传 Hadoop 配置 XML,也可以将各个配置选项指定为键-值对。memory-intensive:此允许我们为内存密集型工作负载配置 Hadoop 集群。run-if:这允许我们基于实例的属性运行引导操作。 当我们只想在 Hadoop 主节点中运行命令时,可以使用此操作。
您还可以通过将脚本写入实例中的指定目录来创建关机操作。 SHUTDOWN 操作在作业流终止后执行。
有关详细信息,请参阅docs.amazonwebservices.com/ElasticMapR…。
使用 Apache Whirr 在云环境中部署 Apache Hadoop 群集
Apache Whirr 提供了一组与云供应商无关的库,用于在云资源上提供服务。 Apache Whirr 支持在几个云环境中配置、安装和配置 Hadoop 集群。 除了 Hadoop,Apache Whirr 还支持在云环境中提供 Apache Cassandra、Apache ZooKeeper、Apache HBase、Voldemort(键值存储)和 Apache Hama 集群。
备注
几个商业 Hadoop 发行版(如 Hortonworks HDP 和 Cloudera CDH)的安装程序现在支持在 Amazon EC2 实例上安装和配置这些发行版。 与使用 Apache Whirr 相比,这些基于商业分发的安装将在云上为您提供功能更丰富的 Hadoop 集群。
在本菜谱中,我们将使用 Apache Whirr 在 Amazon EC2 上启动 Hadoop 集群,并在该集群上运行 wordcount MapReduce 示例(编写 Wordcount MapReduce 应用,将其捆绑,并使用第 1 章,《Hadoop v2 入门》中的 Hadoop 本地模式菜谱运行)。
怎么做……
以下是使用 Apache Whirr 在 Amazon EC2 上部署 Hadoop 群集以及在部署的群集上执行 Wordcount MapReduce 示例的步骤:
-
从whirr.apache.org/下载并解压缩 Apache Whirr 二进制发行版。 您也可以通过 Hadoop 发行版安装 Whirr。
-
从解压的目录运行以下命令以验证您的 Whirr 安装:
$ whirr version Apache Whirr 0.8.2 jclouds 1.5.8 -
将您的 AWS 访问密钥导出到
AWS_ACCESS_KEY_ID和AWS_SECRET_ACCESS_KEY环境参数:$ export AWS_ACCESS_KEY_ID=AKIA… $ export AWS_SECRET_ACCESS_KEY=… -
使用下面的 the 命令生成rsa 密钥对。 此密钥对与您的 AWS 密钥对不同。
$ssh-keygen -t rsa -P '' -
在 Apache Whirr 安装中找到名为
recipes/hadoop-yarn-ec2.properties的文件。 将其复制到您的工作目录。 更改whirr.hadoop.version属性以匹配 Apache Hadoop 下载页面中提供的当前 Hadoop 版本(例如,2.5.2)。 -
If you provided a custom name for your key-pair in the previous step, change the
whirr.private-key-fileand thewhirr.public-key-fileproperty values in thehadoop-yarn-ec2.propertiesfile to the paths of the private key and the public key you generated.提示
whirr.aws-ec2-spot-price属性是一个可选属性,它允许我们使用更便宜的 EC2 Spot 实例。 您可以删除该属性以使用 EC2 传统按需实例。 -
执行以下命令,指向您的
hadoop-yarn-ec2.properties文件,在 EC2 上启动您的 Hadoop 集群。 成功创建集群后,此命令将输出一个 SSH 命令,我们可以使用该命令登录 EC2Hadoop 集群。$bin/whirr launch-cluster --config hadoop-yarn-ec2.properties -
从外部到调配的 EC2 Hadoop 群集的流量通过主节点路由。 Whirr 在
~/.whirr目录中以 Hadoop 集群命名的子目录下生成一个脚本,我们可以使用该脚本启动该代理。 在一个新的终端上运行这个。 Whirr 启动集群并生成此脚本需要几分钟时间。$cd ~/.whirr/Hadoop-yarn/ $hadoop-proxy.sh -
您可以通过在 Web 浏览器中配置此代理,在本地计算机中打开基于 Hadoop Web 的监控控制台。
-
Whirr 在
~/.whirr/<your cluster name>目录中为您的集群生成一个hadoop-site.xml文件。 您可以使用它从本地计算机向 EC2 上的 Hadoop 集群发出 Hadoop 命令。 将生成的hadoop-site.xml的路径导出到名为HADOOP_CONF_DIR的环境变量。 将此目录中的hadoop-site.xml文件复制到名为core-site.xml的另一个文件中。 要执行 Hadoop 命令,您应该在您的机器上安装 Hadoopv2 二进制文件。
```scala
$ cp ~/.whirr/hadoop-yarn/hadoop-site.xml ~/.whirr/hadoop-yarn/core-site.xml
$ export HADOOP_CONF_DIR=~/.whirr/hadoop-yarn/
$ hdfs dfs -ls /
```
11. 在 HDFS 中创建名为wc-input-data的目录,并将文本数据集上传到该目录。 根据 Whirr 的版本,您可能需要首先创建您的主目录。
```scala
$ hdfs dfs –mkdir /user/<user_name>
$ hdfs dfs -mkdir wc-input-data
$ hdfs dfs -put sample.txt wc-input-data
```
12. 在本步骤中,我们在 Amazon EC2 中启动的 Hadoop 集群中运行 Hadoop wordcount 示例:
```scala
$ hadoop jar hcb-c1-samples.jar chapter1.WordCount \
wc-input-data wc-out
```
13. 通过执行以下命令查看字数计算结果:
```scala
$hadoop fs -ls wc-out
Found 3 items
-rw-r--r-- 3 thilina supergroup 0 2012-09-05 15:40 /user/thilina/wc-out/_SUCCESS
drwxrwxrwx - thilina supergroup 0 2012-09-05 15:39 /user/thilina/wc-out/_logs
-rw-r--r-- 3 thilina supergroup 19908 2012-09-05 15:40 /user/thilina/wc-out/part-r-00000
$ hadoop fs -cat wc-out/part-* | more
```
14. 发出以下命令关闭 Hadoop 集群。 请确保在关闭群集之前下载所有重要数据,因为关闭群集后数据将永久丢失。
```scala
$bin/whirr destroy-cluster --config hadoop.properties
```
它是如何工作的.
以下是我们在hadoop.properties文件中使用的属性的说明。
whirr.cluster-name=Hadoop-yarn
前面的属性提供了群集的名称。 群集的实例将使用此名称进行标记。
whirr.instance-templates=1 hadoop-namenode+yarn-resource-manager+mapreduce-historyserver, 1 hadoop-datanode+yarn-nodemanager
此属性指定要用于每组角色的实例数以及实例的角色类型。
whirr.provider=aws-ec2
我们使用 Whirr Amazon EC2 提供程序来配置我们的群集。
whirr.private-key-file=${sys:user.home}/.ssh/id_rsa
whirr.public-key-file=${sys:user.home}/.ssh/id_rsa.pub
前面提到的属性都指向您为集群提供的私钥和公钥的路径。
whirr.hadoop.version=2.5.2
我们使用前面的属性指定自定义 Hadoop 版本。
whirr.aws-ec2-spot-price=0.15
此属性指定 Amazon EC2 Spot 实例的投标价格。 指定此属性将触发 Whirr 对簇使用 EC2 Spot 实例。 如果没有达到投标价格,Apache Whirr Spot 实例会在 20 分钟后请求超时。 有关更多详细信息,请参阅使用 Amazon EC2 Spot 实例执行 EMR 工作流食谱。
有关 Whirr 配置的更多详细信息,请参见whirr.apache.org/docs/0.8.1/…。
另请参阅
使用 Amazon EC2 Spot 实例执行 EMR 作业流节省资金秘诀。*
三、Hadoop 基础知识——配置、单元测试和其他 API
在本章中,我们将介绍:
- 针对群集部署优化 Hadoop Yarn 和 MapReduce 配置
- 共享用户 Hadoop 群集-使用公平和容量调度器
- 将类路径优先级设置为用户提供的 JAR
- 推测性地执行分散的任务
- 使用 MRUnit 对 Hadoop MapReduce 应用进行单元测试
- 使用 MiniYarnCluster 集成测试 Hadoop MapReduce 应用
- 添加新的 DataNode
- 停用数据节点
- 使用多个磁盘/卷并限制 HDFS 磁盘使用
- 设置 HDFS 块大小
- 设置文件复制系数
- 使用 HDFS Java API
简介
本章介绍如何在 Hadoop 群集中执行高级管理步骤,如何为 Hadoop MapReduce 程序开发单元和集成测试,以及如何使用 HDFS 的 Java API。 本章假设您已经阅读了第一章,并且已经在集群或伪分布式安装中安装了 Hadoop。
备注
示例代码和数据
本书的示例代码文件可以在 giHub 的github.com/thilg/hcb-v…中找到。 代码库的chapter3文件夹包含本章的示例源代码文件。
可以通过在代码库的chapter3文件夹中发出gradle build命令来编译和构建示例代码。 Eclipse IDE 的项目文件可以通过在代码库的主文件夹中运行gradle eclipse命令来生成。 IntelliJ IDEA IDE 的项目文件可以通过在代码存储库的主文件夹中运行gradle idea命令来生成。
针对群集部署优化 Hadoop Yarn 和 MapReduce 配置
在本食谱中,我们探索了 Hadoop Yarn 和 Hadoop MapReduce 的一些重要配置选项。 商业 Hadoop 发行版通常提供基于 GUI 的方法来指定 Hadoop 配置。
Yarn 根据应用发出的资源请求和集群的可用资源容量为应用分配资源容器。 应用的资源请求将由所需容器的数量和每个容器的资源要求组成。 目前,大多数容器资源需求都是使用内存量指定的。 因此,我们在本配方中的重点将主要放在配置 Yarn 集群的内存分配上。
做好准备
按照第一章中的食谱设置 Hadoop 集群。
怎么做……
以下说明将向您展示如何在 Yarn 集群中配置内存分配。 每个节点的任务数是使用以下配置得出的:
-
以下属性指定辅助节点中 Yarn 容器可以使用的内存量(RAM)。 建议将其设置为略小于节点中存在的物理 RAM 的大小,从而为操作系统和其他非 Hadoop 进程留出一些内存。 在
yarn-site.xml文件中添加或修改以下行:<property> <name>yarn.nodemanager.resource.memory-mb</name> <value>100240</value> </property> -
The following property specifies the minimum amount of memory (RAM) that can be allocated to a YARN container in a worker node. Add or modify the following lines in the
yarn-site.xmlfile to configure this property.如果我们假设所有 Yarn 资源请求请求容器只具有最小内存量,则在一个节点中可以执行的最大并发资源容器数等于*(步骤 1 中指定的每个节点的 Yarn 内存)/(下面配置的 Yarn 最小分配)*。 基于此关系,我们可以使用以下属性的值来实现每个节点所需的资源容器数量。
每个节点的资源容器数量建议小于或等于*(2个 CPU 核)或(2磁盘数量)*中的最小值。
<property> <name>yarn.scheduler.minimum-allocation-mb</name> <value>3072</value> </property> -
通过运行
HADOOP_HOME目录中的sbin/stop-yarn.sh和sbin/start-yarn.sh来重新启动 SPAINE ResourceManager 和 NodeManager 服务。
以下说明将向您展示如何配置 MapReduce 应用的内存要求。
-
以下属性定义了每个 Map 和 Reduce 任务可用的最大内存量(RAM)。 当 MapReduce 应用为 Map 和 Reduce 任务容器从 YAR 请求资源时,将使用这些内存值。 将以下行添加到
mapred-site.xml文件:<property> <name>mapreduce.map.memory.mb</name> <value>3072</value> </property> <property> <name>mapreduce.reduce.memory.mb</name> <value>6144</value> </property> -
以下属性分别定义了 Map 和 Reduce 任务的 JVM 堆大小。 将这些值设置为略小于步骤 4 中的对应值,以便它们不会超过 Yarn 容器的资源限制。 将以下行添加到
mapred-site.xml文件:<property> <name>mapreduce.map.java.opts</name> <value>-Xmx2560m</value> </property> <property> <name>mapreduce.reduce.java.opts</name> <value>-Xmx5120m</value> </property>
它是如何工作的.
我们可以通过以下四个配置文件控制 Hadoop 配置。 Hadoop 在群集重新启动后从以下配置文件重新加载配置:
core-site.xml:包含整个 Hadoop 发行版通用的配置hdfs-site.xml:包含 HDFS 的配置mapred-site.xml:包含 MapReduce 的配置yarn-site.xml:包含 Yarn 资源管理器和节点管理器进程的配置
每个配置文件都有以 XML 格式表示的名称-值对,定义了 Hadoop 的不同方面的配置。 下面是配置文件中的属性示例。 <configuration>标记是顶级父 XML 容器,定义各个属性的<property>标记被指定为<configuration>标记内的子标记:
<configuration>
<property>
<name>mapreduce.reduce.shuffle.parallelcopies</name>
<value>20</value>
</property>
...
</configuration>
某些配置可以使用 Hadoop MapReduce 作业驱动程序代码中的job.getConfiguration().set(name, value)方法按作业进行配置。
还有更多...
在 Hadoop 中定义了许多类似的重要配置属性。 以下是其中一些建议:
|conf/core-site.xml
|
| --- |
| 名称 | 默认值 | 说明 |
| fs.inmemory.size.mb | 200 | 分配给内存中文件系统的内存量,用于合并减少器上的映射输出(MB |
| io.file.buffer.size | 131072 | 序列文件使用的读/写缓冲区的大小 |
conf/mapred-site.xml
|
| --- |
| 名称 | 默认值 | 说明 |
| mapreduce.reduce.shuffle.parallelcopies | 20 | Reduce 步骤将执行的从多个并行作业获取输出的最大并行副本数 |
| mapreduce.task.io.sort.factor | 50 | 排序文件时合并的最大流数 |
| mapreduce.task.io.sort.mb | 200 | 以 MB 为单位对数据进行排序时的内存限制 |
conf/hdfs-site.xml
| | --- | |
名称
|
默认值
|
说明
|
| --- | --- | --- |
| dfs.blocksize | 134217728 | HDFS 数据块大小 |
| dfs.namenode.handler.count | 200 | 在 NameNode 中处理 RPC 调用的服务器线程数 |
备注
您可以在hadoop.apache.org/docs/curren…中找到最新版本的 Hadoop 中不推荐使用的属性列表以及它们的新替换属性。
以下文档提供了属性列表、它们的默认值以及前面提到的每个配置文件的说明:
- 通用****配置:hadoop.apache.org/docs/curren…
- hdfs****配置:hadoop.apache.org/docs/curren…
- Yarn****配置:hadoop.apache.org/docs/curren…
- MapReduce****配置:hadoop.apache.org/docs/stable…
共享用户 Hadoop 群集-使用公平和容量调度器
HadoopYarn 调度程序负责将资源分配给用户提交的应用。 在 Hadoop Yarn 中,除了 MapReduce 应用之外,这些应用还可以是任何 Yarn 应用。 目前默认的 Yarn 资源分配是基于应用的内存需求,也可以额外配置基于 CPU 等其他资源的资源分配。
Hadoop Yarn 支持可插拔调度框架,其中集群管理员可以选择为集群选择合适的调度器。 默认情况下,YAINE 支持先进先出(FIFO)调度器,该调度器使用作业队列以与作业到达时相同的顺序执行作业。 但是,FIFO 调度可能不是大型多用户 Hadoop 部署的最佳选择,在这种部署中,群集资源必须在不同的用户和不同的应用之间共享,以确保最大限度地提高群集的工作效率。 请注意,商业 Hadoop 版本可能使用不同的调度器,如公平调度器(例如 Cloudera CDH)或容量调度器(例如 Hortonworks HDP)作为默认 Yarn 调度器。
在中,除了默认的 FIFO 调度器之外,Yarn 还包含以下两个调度器(如果需要,您也可以编写自己的调度器):
- 公平调度器:公平调度器允许所有作业接收相等份额的资源。 当资源可用时,会将资源分配给新提交的作业,直到所有提交和运行的作业都具有相同的资源量。 公平调度程序可确保短作业以实际速度完成,同时不会使长时间运行的较大作业处于饥饿状态。 使用公平调度器,还可以定义多个队列和队列层次结构,并保证每个队列的最小资源,其中特定队列中的作业平等地共享资源。 分配给任何空队列的资源在具有活动作业的队列之间分配。 公平调度程序还允许我们设置作业优先级,用于计算队列中的资源分配比例。
- 容量调度器:容量调度器允许在个组织实体之间共享大型集群,同时确保每个实体的有保证的容量,并且没有单个用户或作业占用所有资源。 这使组织可以通过维护在不同实体之间共享的集中式 Hadoop 群集来实现规模经济。 为了实现这一点,容量调度器定义队列和队列层次结构,每个队列具有保证的容量。 容量调度程序允许作业使用其他队列中的多余资源(如果有的话)。
怎么做……
本食谱介绍如何在 Hadoop 中更改调度程序:
-
关闭 Hadoop 群集。
-
将以下内容添加到
yarn-site.xml file:<property> <name>yarn.resourcemanager.scheduler.class</name> <value>org.apache.hadoop.yarn.server.resourcemanager.scheduler.fair.FairScheduler</value> </property> -
重新启动 Hadoop 群集。
-
转到安装中的
http://<master-noe>:8088/cluster/scheduler,验证是否已应用新的调度程序。
它是如何工作的.
执行上述步骤后,Hadoop 将在启动时加载新的调度程序设置。 公平调度程序在用户之间共享等量的资源,除非另有配置。
我们可以提供 XML 格式的分配文件,使用yarn-site.xml文件中的yarn.scheduler.fair.allocation.file属性为公平调度器定义队列。
有关公平调度器及其配置的更多详细信息,请参阅hadoop.apache.org/docs/curren…。
还有更多...
您可以通过将以下内容添加到yarn-site.xml file并重新启动群集来启用容量计划程序:
<property>
<name>yarn.resourcemanager.scheduler.class</name>
<value>org.apache.hadoop.yarn.server.resourcemanager.scheduler.capacity.CapacityScheduler</value>
</property>
可以使用 ResourceManager 节点的 Hadoop 配置目录中的capacity-scheduler.xml文件配置容量调度器。 在 Yar ResourceManager 节点中发出以下命令以加载配置并刷新队列:
$ yarn rmadmin -refreshQueues
有关容量调度器及其配置的更多详细信息,请参阅hadoop.apache.org/docs/curren…。
将类路径优先级设置为用户提供的 JAR
在开发 Hadoop MapReduce 应用时,您可能会遇到 MapReduce 应用需要 Hadoop 中已包含的较新版本的辅助库的情况。 默认情况下,Hadoop 将类路径优先于 Hadoop 包含的库,这可能会导致与您的应用提供的库的版本冲突。 本食谱向您展示了如何配置 Hadoop,以便为用户提供的库提供类路径优先级。
怎么做……
以下步骤向您展示了如何将外部库添加到 Hadoop 任务类路径,以及如何为用户提供的 JAR 提供优先级:
-
在 MapReduce 计算的驱动程序中设置以下属性:
job.getConfiguration().set("mapreduce.job.user.classpath.first","true"); -
使用 hadoop 命令中的
–libjars选项提供您的库,如下所示:$hadoop jar hcb-c3-samples.jar \ chapter3.WordCountWithTools \ –libjars guava-15.0.jar \ InDir OutDir …
它是如何工作的.
Hadoop 将把–libjars指定的 JAR 复制到 HadoopDistributedCache中,并且它们将可用于属于该特定作业的所有任务的类路径。 设置mapreduce.user.classpath.first时,用户提供的 JAR 将附加到类路径中的默认 Hadoop JAR 和 Hadoop 依赖项之前。
推测性地执行分散的任务
使用 Hadoop MapReduce 的主要优势之一是框架管理的容错。 在执行大规模分布式计算时,部分计算可能会由于网络故障、磁盘故障和节点故障等外部原因而失败。 当 Hadoop 检测到无响应的任务或失败的任务时,Hadoop 将在新节点中重新执行这些任务。
Hadoop 群集可能由异构节点组成,因此可能会有速度很慢的节点,也可能会有速度很快的节点。 一些速度较慢的节点和在这些节点上执行的任务可能会控制计算的执行时间。 Hadoop 引入了推测性的执行优化,以避免这些运行缓慢的任务,这些任务被称为落后者。
当计算的大部分 Map(或 Reduce)任务完成时,Hadoop 推测性执行功能将在可用的备用节点中调度剩余缓慢任务的重复执行。 任务的缓慢程度取决于相同计算的其他任务所花费的运行时间。 Hadoop 将从一组重复任务中选择第一个已完成任务的结果,并终止该任务的任何其他重复执行。
怎么做……
默认情况下,Hadoop 中为 Map 和 Reduce 任务启用了推测性执行。 如果由于某种原因,您的计算不需要这样的重复执行,您可以禁用(或启用)推测性执行,如下所示:
-
运行将以下选项作为参数传递的 wordcount 示例:
$ hadoop jar hcb-c32-samples.jar chapter3.WordCountWithTools \ –Dmapreduce.map.speculative=false \ –Dmapreduce.reduce.speculative=false \ /data/input1 /data/output1 -
但是,仅当作业实现
org.apache.hadoop.util.Tools接口时,上述命令才有效。 否则,请使用以下方法在 MapReduce 驱动程序中设置这些属性:- 对于整个作业,使用
job.setSpeculativeExecution(boolean specExec) - 对于地图任务,使用
job.setMapSpeculativeExecution(boolean specExec) - 对于 Reduce 任务,使用
Job.setReduceSpeculativeExecution(boolean specExec)
- 对于整个作业,使用
还有更多...
您可以使用属性mapreduce.map.maxattempts和mapreduce.reduce.maxattempts分别为 Map 和 Reduce 任务配置任务的最大重试次数。 Hadoop 在任务超过给定的重试次数后将其声明为失败。 您还可以使用JobConf.setMaxMapAttempts()和JobConf.setMaxReduceAttempts()函数来配置这些属性。 这些属性的默认值为4。
使用 MRUnit 单元测试 Hadoop MapReduce 应用
MRUnit是一个基于 JUnit 的 Java 库,允许用户对 Hadoop MapReduce 程序进行单元测试。 这使得开发和维护 Hadoop MapReduce 代码库变得容易。 MRUnit 支持单独测试Mappers and Reducers以及整体测试 MapReduce 计算。 在本食谱中,我们将探索所有三个测试场景。 本食谱中使用的测试程序的源代码位于 Git 存储库的chapter3\test\chapter3\WordCountWithToolsTest.java文件中。
做好准备
我们使用 Gradle 作为示例代码库的构建工具。 如果您还没有安装 Gradle,请按照章,Hadoopv2入门介绍部分中的说明安装 Gradle。
怎么做……
以下步骤说明如何使用 MRUnit 执行映射器的单元测试:
-
在测试类的
setUp方法中,使用要测试的 Mapper 类初始化 MRUnitMapDriver实例。 在本例中,我们将测试我们在前面的食谱中讨论的 Wordcount MapReduce 应用的映射器:public class WordCountWithToolsTest { MapDriver<Object, Text, Text, IntWritable> mapDriver; @Before public void setUp() { WordCountWithTools.TokenizerMapper mapper = new WordCountWithTools.TokenizerMapper(); mapDriver = MapDriver.newMapDriver(mapper); } …… } -
Write a test function to test the Mapper logic. Provide the test input to the Mapper using the
MapDriver.withInputmethod. Then, provide the expected result of the Mapper execution using theMapDriver.withOutputmethod. Now, invoke the test using theMapDriver.runTestmethod. TheMapDriver.withAllandMapDriver.withAllOutputmethods allow us to provide a list of test inputs and a list of expected outputs, rather than adding them individually.@Test public void testWordCountMapper() throws IOException { IntWritable inKey = new IntWritable(0); mapDriver.withInput(inKey, new Text("Test Quick")); …. mapDriver.withOutput(new Text("Test"),new IntWritable(1)); mapDriver.withOutput(new Text("Quick"),new IntWritable(1)); … mapDriver.runTest(); }以下步骤将向您展示如何使用 MRUnit 执行 Reducer 的单元测试。
-
Similar to step 1 and 2, initialize a
ReduceDriverby providing the Reducer class under test and then configure theReduceDriverwith the test input and the expected output. The input to thereducefunction should conform to a key with a list of values. Also, in this test, we use theReduceDriver.withAllOutputmethod to provide a list of expected outputs.public class WordCountWithToolsTest { ReduceDriver<Text,IntWritable,Text,IntWritable> reduceDriver; @Before public void setUp() { WordCountWithTools.IntSumReducer reducer = new WordCountWithTools.IntSumReducer(); reduceDriver = ReduceDriver.newReduceDriver(reducer); } @Test public void testWordCountReduce() throws IOException { ArrayList<IntWritable> reduceInList = new ArrayList<IntWritable>(); reduceInList.add(new IntWritable(1)); reduceInList.add(new IntWritable(2)); reduceDriver.withInput(new Text("Quick"), reduceInList); ... ArrayList<Pair<Text, IntWritable>> reduceOutList = new ArrayList<Pair<Text,IntWritable>>(); reduceOutList.add(new Pair<Text, IntWritable> (new Text("Quick"),new IntWritable(3))); ... reduceDriver.withAllOutput(reduceOutList); reduceDriver.runTest(); } }以下步骤向您展示了如何使用 MRUnit 对整个 MapReduce 计算执行单元测试。
-
在此步骤中,通过提供要测试的 MapReduce 程序的 Mapper 类和 Reducer 类来初始化 a
MapReduceDriver。 然后,使用测试输入数据和预期输出数据配置MapReduceDriver。 执行时,此测试将执行从 Map 输入阶段到 Reduce 输出阶段的 MapReduce 执行流。 也可以为该测试提供组合器实现。public class WordCountWithToolsTest { …… MapReduceDriver<Object, Text, Text, IntWritable, Text, IntWritable> mapReduceDriver; @Before public void setUp() { .... mapReduceDriver = MapReduceDriver.newMapReduceDriver(mapper, reducer); } @Test public void testWordCountMapReduce() throws IOException { IntWritable inKey = new IntWritable(0); mapReduceDriver.withInput(inKey, new Text("Test Quick")); …… ArrayList<Pair<Text, IntWritable>> reduceOutList = new ArrayList<Pair<Text,IntWritable>>(); reduceOutList.add(new Pair<Text, IntWritable>(new Text("Quick"),new IntWritable(2))); …… mapReduceDriver.withAllOutput(reduceOutList); mapReduceDriver.runTest(); } } -
Gradle Build 脚本(或任何其他 Java 构建机制)可以配置为对每个构建执行这些单元测试。 我们可以将 MRUnit 依赖项添加到 Gradle 构建(
chapter3/build.gradle)文件,如下所示:dependencies { testCompile group: 'org.apache.mrunit', name: 'mrunit', version: '1.1.+',classifier: 'hadoop2' …… } -
使用以下 Gradle 命令仅执行
WordCountWithToolsTest单元测试。 此命令执行与模式**/WordCountWith*.class:$ gradle –Dtest.single=WordCountWith test :chapter3:compileJava UP-TO-DATE :chapter3:processResources UP-TO-DATE :chapter3:classes UP-TO-DATE :chapter3:compileTestJava UP-TO-DATE :chapter3:processTestResources UP-TO-DATE :chapter3:testClasses UP-TO-DATE :chapter3:test BUILD SUCCESSFUL Total time: 27.193 secs匹配的任何测试类
-
您还可以在 IDE 中执行基于 MRUnit 的单元测试。 您可以使用
gradle eclipse或gradle idea命令分别为 Eclipse 和 IDEA IDE 生成项目文件。
另请参阅
- 本章中的使用 MiniYarnCluster配方集成测试 Hadoop MapReduce 应用
- 有关使用 MRUnit 的更多信息,请访问cwiki.apache.org/confluence/…
使用 MiniYarnCluster 集成测试 Hadoop MapReduce 应用
虽然使用 MRUnit 的单元测试非常有用,但是可能有某些集成测试场景需要在集群环境中进行测试。 Hadoop Yarn 的 MiniYARNCluster 是一个集群模拟器,我们可以使用它来为这样的集成测试创建测试环境。 在本食谱中,我们将使用 MiniYARNCluster 执行 WordCountWithTools MapReduce 应用的集成测试。
本食谱中使用的测试程序的源代码位于 Git 存储库的chapter3\test\chapter3\minicluster\WordCountMiniClusterTest.java文件中。
做好准备
我们使用 Gradle 作为示例代码库的构建工具。 如果您还没有安装 Gradle,请按照章,Hadoopv2入门介绍部分中的说明安装 Gradle。 导出指向 JDK 安装的JAVA_HOME环境变量。
怎么做……
以下步骤显示如何使用MiniYarnCluster环境执行 MapReduce 应用的集成测试:
-
在 JUnit 测试的
setup方法中,使用MiniMRClientClusterFactory创建MiniYarnCluster的实例,如下所示。MiniMRClientCluster是MiniMRYarnCluster的包装器接口,用于使用 Hadoop 1.x 集群提供支持测试。public class WordCountMiniClusterTest { private static MiniMRClientCluster mrCluster; private class InternalClass { } @BeforeClass public static void setup() throws IOException { // create the mini cluster to be used for the tests mrCluster = MiniMRClientClusterFactory.create(InternalClass.class, 1,new Configuration()); } } -
确保停止测试的
setup方法内的集群:@AfterClass public static void cleanup() throws IOException { // stopping the mini cluster mrCluster.stop(); } -
在您的测试方法中,使用我们刚刚创建的
MiniYARNCluster的 Configuration 对象准备 MapReduce 计算。 提交作业并等待其完成。 然后测试作业是否成功。@Test public void testWordCountIntegration() throws Exception{ …… Job job = (new WordCountWithTools()).prepareJob(testInput,outDirString, mrCluster.getConfig()); // Make sure the job completes successfully assertTrue(job.waitForCompletion(true)); validateCounters(job.getCounters(), 12, 367, 201, 201); } -
在本例中,我们将使用计数器来验证 MapReduce 计算的预期结果。 您还可以实现逻辑,将计算的输出数据与预期的计算输出进行比较。 但是,必须小心处理由于存在多个 Reduce 任务而可能有多个输出文件的情况。
private void validateCounters(Counters counters, long mapInputRecords,…) { assertEquals("MapInputRecords", mapInputRecords, counters.findCounter("org.apache.hadoop.mapred.Task$Counter", "MAP_INPUT_RECORDS").getValue()); ……… } -
使用以下 Gradle 命令仅执行
WordCountMiniClusterTestJUnit 测试。 该命令执行与模式**/WordCountMini*.class匹配的任何测试类。$ gradle -Dtest.single=WordCountMini test :chapter3:compileJava UP-TO-DATE :chapter3:processResources UP-TO-DATE :chapter3:classes UP-TO-DATE :chapter3:compileTestJava UP-TO-DATE :chapter3:processTestResources UP-TO-DATE :chapter3:testClasses UP-TO-DATE :chapter3:test UP-TO-DATE BUILD SUCCESSFUL -
您还可以在 IDE 中执行基于
MiniYarnCluster的单元测试。 您可以使用gradle eclipse或gradle idea命令分别为 Eclipse 和 IDEA IDE 生成项目文件。
另请参阅
- 本章中的单元测试 Hadoop MapReduce 应用使用 MRUnit菜谱
- 第 4 章,《开发复杂 Hadoop MapReduce 应用》中用于报告自定义指标的Hadoop 计数器配方
添加新的 DataNode
此配方向您展示了如何在不重新启动整个集群的情况下向现有 HDFS 集群添加新节点,以及如何在添加新节点后强制 HDFS 重新平衡。 商业 Hadoop 发行版通常提供基于 GUI 的方法来添加和删除 DataNode。
做好准备
-
在新节点上安装 Hadoop 并复制现有 Hadoop 群集的配置文件。 您可以使用
rsync从另一个节点复制 Hadoop 配置;例如:$ rsync -a <master_node_ip>:$HADOOP_HOME/etc/hadoop/ $HADOOP_HOME/etc/hadoop -
确保 Hadoop/HDFS 集群的主节点可以对新节点执行无密码 SSH。 如果您不打算从主节点使用
bin/*.sh脚本启动/停止群集,则无密码 SSH 设置是可选的。
怎么做……
以下步骤将向您展示如何向现有 HDFS 集群添加新的 DataNode:
-
将新节点的 IP 或 DNS 添加到主节点的
$HADOOP_HOME/etc/hadoop/slaves文件中。 -
Start the DataNode on the newly added slave node by using the following command:
$ $HADOOP_HOME/sbin/hadoop-deamons.sh start datanode提示
您还可以从主节点使用
$HADOOP_HOME/sbin/start-dfs.sh脚本在新添加的节点中启动 DataNode 守护进程。 如果要向集群添加多个新的 DataNode,这将非常有用。 -
检查新从节点中的
$HADOOP_HOME/logs/hadoop-*-datanode-*.log是否有任何错误。
这些步骤既适用于添加新节点,也适用于重新加入已崩溃并重新启动的节点。
还有更多...
同样,您也可以向 Hadoop Yarn 集群添加新节点:
-
使用以下命令在新节点中启动 NodeManager:
> $HADOOP_HOME/sbin/yarn-deamons.sh start nodemanager -
检查新从节点中的
$HADOOP_HOME/logs/yarn-*-nodemanager-*.log是否有任何错误。
重新平衡 HDFS
当您添加新节点时,HDFS 不会自动重新平衡。 但是,HDFS 提供了可以手动调用的重新平衡器工具。 此工具将跨群集平衡数据块,最高可达可选的阈值百分比。 如果您在其他现有节点中遇到空间问题,重新平衡将非常有用。
-
Execute the following command:
> $HADOOP_HOME/sbin/start-balancer.sh –threshold 15(可选)
–threshold参数指定在标识节点未充分利用或过度利用时要考虑的磁盘容量回旋余地百分比。 未充分利用的数据节点是其利用率小于*(平均利用率阈值)*的节点。 过度利用的 DataNode 是利用率大于(平均利用率+阈值)的节点。 较小的阈值将实现更均匀的节点平衡,但重新平衡将需要更多时间。 默认阈值为 10%。 -
通过执行
sbin/stop-balancer.sh命令可以停止重新平衡。 -
$HADOOP_HOME/logs/hadoop-*-balancer*.out文件中提供了重新平衡的摘要。
另请参阅
本章中的取消数据节点配方。
停用数据节点
可能有种情况,您希望从 HDFS 群集中停用一个或多个 DataNode。 本食谱展示了如何优雅地使 DataNode 退役,而不会导致数据丢失。
怎么做……
以下步骤向您展示了如何正常停用 DataNode:
-
如果您的集群没有
exclude文件,请向集群添加一个exclude文件。 在 NameNode 中创建一个空文件,并通过添加以下属性从$HADOOP_HOME/etc/hadoop/hdfs-site.xml文件指向该文件。 重新启动 NameNode:<property> <name>dfs.hosts.exclude</name> <value>FULL_PATH_TO_THE_EXCLUDE_FILE</value> <description>Names a file that contains a list of hosts that are not permitted to connect to the namenode. The full pathname of the file must be specified. If the value is empty, no hosts are excluded.</description> </property> -
将要停用的节点的主机名添加到
exclude文件。 -
Run the following command to reload the NameNode configuration:
$ hdfs dfsadmin –refreshNodes这将启动退役过程。 此过程可能需要大量时间,因为它需要复制数据块,而不会使群集的其他任务不堪重负。
-
停用过程的进度显示在停用节点页面下的 HDFS UI 中。 也可以使用以下命令监视进度。 在停用完成之前不要关闭节点。
$ hdfs dfsadmin -report ..... ..... Name: myhost:50010 Decommission Status : Decommission in progress Configured Capacity: .... ..... -
当您想要将节点重新添加到集群中时,可以从
exclude文件中删除节点并执行hdfs dfsadmin –refreshNodes命令。 -
可以通过从
exclude文件中删除节点名称,然后执行hdfs dfsadmin –refreshNodes命令来停止停用过程。
它是如何工作的.
当某个节点处于停用过程中时,HDFS 会将该节点中的数据块复制到群集中的其他节点。 停用可能是一个缓慢的过程,因为 HDFS 故意缓慢地停用,以避免使群集不堪重负。 在不停用的情况下关闭节点可能会导致数据丢失。
停用完成后,排除文件中提到的节点不允许与 NameNode 通信。
另请参阅
本章中添加新的 DataNode配方的重新平衡 HDFS部分。
使用多个磁盘/卷并限制 HDFS 磁盘使用
Hadoop 支持为 DataNode 数据目录指定多个目录。 此功能允许我们利用多个磁盘/卷在 DataNode 中存储数据块。 Hadoop 尝试在每个目录中存储等量的数据。 它还支持限制 HDFS 使用的磁盘空间量。
怎么做……
以下步骤将向您展示如何添加多个磁盘卷:
-
在每个卷中创建 HDFS 数据存储目录。
-
找到
hdfs-site.xml配置文件。 在dfs.datanode.data.dir属性下提供与每个卷中的数据存储位置相对应的以逗号分隔的目录列表,如下所示:<property> <name>dfs.datanode.data.dir</name> <value>/u1/hadoop/data, /u2/hadoop/data</value> </property> -
为了限制磁盘使用,请将以下属性添加到
hdfs-site.xml文件中,以便为非 DFS 使用保留空间。 该值指定 HDFS 不能在每个卷上使用的字节数:<property> <name>dfs.datanode.du.reserved</name> <value>6000000000</value> <description>Reserved space in bytes per volume. Always leave this much space free for non dfs use. </description> </property>
设置 HDFS 块大小
HDFS 通过将文件分解成粗粒度、固定大小的块来跨群集中存储文件。 默认 HDFS 数据块大小为 64 MB。 数据产品的数据块大小可能会影响文件系统操作的性能,在存储和处理非常大的文件时,较大的数据块大小会更有效。 数据产品的块大小也会影响 MapReduce 计算的性能,因为 Hadoop 的默认行为是为输入文件的每个数据块创建一个 Map 任务。
怎么做……
以下步骤显示如何使用 NameNode 配置文件设置 HDFS 块大小:
-
在
$HADOOP_HOME/etc/hadoop/hdfs-site.xml文件中添加或修改以下代码。 块大小是使用字节数提供的。 此更改不会更改 HDFS 中已有文件的块大小。 只有更改后复制的文件才具有新的块大小。<property> <name>dfs.blocksize</name> <value>134217728</value> </property> -
您还可以为特定文件路径指定不同的 HDFS 块大小。 还可以在从命令行将文件上载到 HDFS 时指定块大小,如下所示:
$ hdfs dfs \ -Ddfs.blocksize=134217728 \ -put data.in foo/test
还有更多...
您还可以在使用 HDFS Java API 创建文件时指定块大小,方法如下:
public FSDataOutputStream create(Path f,boolean overwrite, int bufferSize, short replication,long blockSize)
您可以使用fsck命令查找 HDFS 中特定文件路径的块大小和块位置。 您也可以通过从 HDFS 监控控制台浏览文件系统来查找此信息。
> $HADOOP_HOME/bin/hdfs fsck \
/user/foo/data.in \
-blocks -files -locations
......
/user/foo/data.in 215227246 bytes, 2 block(s): ....
0\. blk_6981535920477261584_1059 len=134217728 repl=1 [hostname:50010]
1\. blk_-8238102374790373371_1059 len=81009518 repl=1 [hostname:50010]
......
另请参阅
本章中的设置文件复制因子配方。
设置文件复制系数
HDFS 通过将文件分解成粗粒度、固定大小的块来跨群集中存储文件。 这些粗粒度的数据块被复制到不同的 DataNode,主要是出于容错目的。 数据块复制还能够增加 MapReduce 计算的数据局部性,并增加总数据访问带宽。 降低复制系数有助于节省 HDFS 中的存储空间。
HDFS 复制因子是可以按文件设置的文件级属性。 本食谱向您展示如何更改 HDFS 部署的默认复制系数(影响随后将创建的新文件),如何在 HDFS 中创建文件时指定自定义复制系数,以及如何更改 HDFS 中现有文件的复制系数。
怎么做……
按照以下说明使用 NameNode 配置设置文件复制因子:
-
在
$HADOOP_HOME/etc/hadoop/hdfs-site.xml中添加或修改dfs.replication属性。 此更改不会更改 HDFS 中已有文件的复制系数。 只有更改后复制的文件才具有新的复制因子。 请注意,降低复制系数会降低存储文件的可靠性,在处理该数据时还可能导致性能下降。<property> <name>dfs.replication</name> <value>2</value> </property> -
上传文件时设置文件复制因子。 您可以在从命令行上传文件时指定复制因子,如下所示:
$ hdfs dfs \ -Ddfs.replication=1 \ -copyFromLocal \ non-critical-file.txt /user/foo -
更改现有文件路径的文件复制系数。
setrep命令可用于通过以下方式更改 HDFS 中已存在的文件或文件路径的复制因子:$ hdfs dfs \ -setrep 2 non-critical-file.txt Replication 2 set: hdfs://myhost:9000/user/foo/non-critical-file.txt
它是如何工作的.
看一下下面的命令:
hdfs dfs -setrep [-R] <path>
setrep命令的<path>参数指定必须更改复制因子的 HDFS 路径。 –R选项递归地设置目录中文件和目录的复制因子。
还有更多...
使用ls命令列出文件时,会显示文件的复制系数:
$ hdfs fs -ls
Found 1 item
-rw-r--r-- 2 foo supergroup ... /user/foo/non-critical-file.txt
文件的复制系数也会显示在监控 UI 的 HDFS 中。
另请参阅
本章中的设置 HDFS 块大小配方。
使用 HDFS Java API
HDFS Java API可用于从任何 Java 程序与 HDFS 交互。 此 API 使我们能够从其他 Java 程序利用存储在 HDFS 中的数据,并使用其他非 Hadoop 计算框架处理这些数据。 有时,您可能还会遇到希望从 MapReduce 应用中直接访问 HDFS 的用例。 但是,如果您直接从 Map 或 Reduce 任务在 HDFS 中写入或修改文件,请注意您违反了 MapReduce 的无副作用特性,这可能会导致基于您的使用案例的数据一致性问题。
怎么做……
以下步骤显示了如何使用 HDFS Java API 通过 Java 程序在 HDFS 安装上执行文件系统操作:
-
下面的示例程序在 HDFS 中创建一个新文件,在新创建的文件中写入一些文本,然后从 HDFS 读回该文件:
import java.io.IOException; import org.apache.hadoop.conf.Configuration; import org.apache.hadoop.fs.FSDataInputStream; import org.apache.hadoop.fs.FSDataOutputStream; import org.apache.hadoop.fs.FileSystem; import org.apache.hadoop.fs.Path; public class HDFSJavaAPIDemo { public static void main(String[] args) throws IOException { Configuration conf = new Configuration(); FileSystem fs = FileSystem.get(conf); System.out.println(fs.getUri()); Path file = new Path("demo.txt"); if (fs.exists(file)) { System.out.println("File exists."); } else { // Writing to file FSDataOutputStream outStream = fs.create(file); outStream.writeUTF("Welcome to HDFS Java API!!!"); outStream.close(); } // Reading from file FSDataInputStream inStream = fs.open(file); String data = inStream.readUTF(); System.out.println(data); inStream.close(); fs.close(); } -
在源库的
chapter3文件夹中发出gradle build命令,编译并打包前面的程序。 将在build/libs文件夹中创建hcb-c3-samples.jar文件。 -
您可以使用以下命令执行前面的示例。 使用
hadoop脚本运行此示例可确保它使用当前配置的 HDFS 和 Hadoop类路径中的必要依赖项。$ hadoop jar \ hcb-c3-samples.jar \ chapter3.hdfs.javaapi.HDFSJavaAPIDemo hdfs://yourhost:9000 Welcome to HDFS Java API!!! -
使用
ls命令列出新创建的文件,如下图所示:$ hdfs dfs -ls Found 1 items -rw-r--r-- 3 foo supergroup 20 2012-04-27 16:57 /user/foo/demo.txt
它是如何工作的.
为了以编程方式与 HDFS 交互,我们首先需要获取当前配置的文件系统的句柄。 为此,我们实例化一个Configuration对象并获得一个FileSystem句柄,它将指向我们运行该程序的 Hadoop 环境的 HDFS NameNode。 本章的配置文件系统对象一节讨论了配置FileSystem对象的几种替代方法:
Configuration conf = new Configuration();
FileSystem fs = FileSystem.get(conf);
FileSystem.create(filePath) 方法在给定的路径中创建一个新文件,并为新创建的文件提供一个FSDataOutputStream对象。 FSDataOutputStream包装java.io.DataOutputStream并允许程序将原始 Java 数据类型写入文件。 如果文件存在,则FileSystem.Create()方法重写。 在本例中,该文件将相对于 HDFS 主目录创建,这将产生类似于/user/<user_name>/demo.txt的路径。 您的 HDFS 主目录必须事先创建。
Path file = new Path("demo.txt");
FSDataOutputStream outStream = fs.create(file);
outStream.writeUTF("Welcome to HDFS Java API!!!");
outStream.close();
FileSystem.open(filepath)打开给定文件的FSDataInputStream。 FSDataInputStream包装java.io.DataInputStream并允许程序从文件中读取原始 Java 数据类型。
FSDataInputStream inStream = fs.open(file);
String data = inStream.readUTF();
System.out.println(data);
inStream.close();
还有更多...
HDFS Java API 支持的文件系统操作比我们在前面的示例中使用的多得多。 完整的接口文档可以在hadoop.apache.org/docs/curren…找到。
配置文件系统对象
我们也可以从 Hadoop 环境外部使用 HDFS Java API。 在执行此操作时,我们必须显式配置 HDFS NameNode 和端口。 以下是执行该配置的几种方法:
-
您可以在检索
FileSystem对象之前将配置文件加载到configuration对象,如下所示。 确保将所有 Hadoop 和依赖库添加到类路径中。Configuration conf = new Configuration(); conf.addResource(new Path("/etc/hadoop/core-site.xml")); conf.addResource(new Path("/etc/hadoop/conf/hdfs-site.xml")); FileSystem fileSystem = FileSystem.get(conf); -
您还可以按如下方式指定 NameNode 和端口。 将
NAMENODE_HOSTNAME和PORT替换为 HDFS 安装的 NameNode 的主机名和端口。Configuration conf = new Configuration(); conf.set("fs.defaultFS, "hdfs://NAMENODE_HOSTNAME:PORT"); FileSystem fileSystem = FileSystem.get(conf);
HDFS 文件系统 API 是支持多个文件系统的抽象。 如果前面的程序没有找到有效的 HDFS 配置,它将指向本地文件系统,而不是 HDFS。 您可以使用getUri()函数标识fileSystem对象的当前文件系统,如下所示。 如果它使用的是正确配置的 HDFS,则会产生hdfs://your_namenode:port,如果使用的是本地文件系统,则会产生file:///。
fileSystem.getUri();
检索文件的数据块列表
the fileSystem对象的getFileBlockLocations()函数允许您检索 HDFS 中存储的文件的数据块列表,以及存储这些块的主机名和块偏移量。 如果您计划在上使用除 Hadoop MapReduce 之外的框架对文件数据执行任何本地操作,此信息将非常有用。
FileStatus fileStatus = fs.getFileStatus(file);
BlockLocation[] blocks = fs.getFileBlockLocations(
fileStatus, 0, fileStatus.getLen());