R 和 Hadoop 大数据分析(一)

原文:annas-archive.org/md5/b7f3a14803c1b4d929732471e0b28932

译者:飞龙

协议:CC BY-NC-SA 4.0

前言

企业每天获取的数据量呈指数增长。现在可以将这些海量信息存储在像 Hadoop 这样的低成本平台上。

这些组织目前面临的难题是如何处理这些数据,以及如何从中提取关键见解。因此,R 就成为了关键工具。R 是一个非常强大的工具,它使得在数据上运行高级统计模型变得轻而易举,将得到的模型转换为多彩的图表和可视化,并且执行更多与数据科学相关的功能。

然而,R 的一个主要缺点是它的可扩展性较差。核心的 R 引擎只能处理有限数量的数据。由于 Hadoop 在大数据处理方面非常流行,将 R 与 Hadoop 结合以实现可扩展性成为下一步的合理选择。

本书专门讲解 R 和 Hadoop 以及如何利用 Hadoop 平台使 R 的数据分析操作具备可扩展性。

本书将面向广泛的受众,包括数据科学家、统计学家、数据架构师和工程师,帮助他们使用 R 和 Hadoop 处理和分析大量信息。

使用 R 与 Hadoop 结合,将提供一个弹性的 数据分析平台,能够根据待分析数据集的大小进行扩展。经验丰富的程序员可以在 R 中编写 Map/Reduce 模块,并通过 Hadoop 的并行处理 Map/Reduce 机制运行这些模块,从而识别数据集中的模式。

介绍 R

R 是一个开源软件包,用于对数据进行统计分析。R 是一种编程语言,数据科学家、统计学家和其他需要进行数据统计分析并通过回归、聚类、分类、文本分析等机制从数据中提取关键信息的人群都会使用。R 在 GNU通用公共许可证)下注册。它由新西兰奥克兰大学的 Ross Ihaka 和 Robert Gentleman 开发,目前由 R 开发核心团队管理。它可以被视为 S 语言的另一种实现,S 是由 Johan Chambers 在贝尔实验室开发的。尽管存在一些重要的差异,但用 S 编写的大多数代码可以通过 R 解释器引擎无缝运行。

R 提供了多种统计、机器学习(线性与非线性建模、经典统计检验、时间序列分析、分类、聚类)和图形技术,并且具有高度的扩展性。R 拥有多种内建及扩展功能,适用于统计、机器学习和可视化任务,包括:

  • 数据提取

  • 数据清洗

  • 数据加载

  • 数据转换

  • 统计分析

  • 预测建模

  • 数据可视化

这是目前市场上最流行的开源统计分析包之一。它跨平台,拥有非常广泛的社区支持,以及一个庞大且不断壮大的用户社区,每天都在新增包。随着包列表的增长,R 现在可以连接到其他数据存储,如 MySQL、SQLite、MongoDB 和 Hadoop 进行数据存储活动。

了解 R 的特性

让我们来看一下 R 的不同有用功能:

  • 有效的编程语言

  • 关系型数据库支持

  • 数据分析

  • 数据可视化

  • 通过丰富的 R 包库进行扩展

研究 R 语言的流行度

KD 提供的图表显示,R 是进行数据分析和挖掘的最流行语言:

https://github.com/OpenDocCN/freelearn-ds-pt5-zh/raw/master/docs/bgdt-anal-r-hdp/img/3282OS_Preface_01.jpg

以下图表提供了从 2005 年到 2013 年,R 用户发布的 R 包的总数。这就是我们探索 R 用户的方式。2012 年的增长呈指数级,2013 年似乎也有望超过这一增长。

R 允许通过各种统计和机器学习操作执行数据分析,具体如下:

  • 回归

  • 分类

  • 聚类

  • 推荐

  • 文本挖掘

https://github.com/OpenDocCN/freelearn-ds-pt5-zh/raw/master/docs/bgdt-anal-r-hdp/img/3282OS_Preface_02.jpg

介绍大数据

大数据需要处理大量且复杂的数据集,这些数据集可以是结构化的、半结构化的或非结构化的,并且通常无法完全加载到内存中进行处理。它们必须就地处理,这意味着计算必须在数据所在的地方进行。当我们与开发人员交谈时,这些实际构建大数据系统和应用程序的人,我们对他们所说的 3V 有了更清晰的了解。他们通常会提到大数据的 3V 模型,即速度(velocity)、体量(volume)和多样性(variety)。

速度指的是应用分析所需的低延迟、实时速度。一个典型的例子是对来自社交网络网站或多个不同数据源的连续数据流进行分析。

体量指的是数据集的大小。根据生成或接收数据的应用程序类型,数据大小可能为 KB、MB、GB、TB 或 PB。

多样性指的是数据可能存在的各种类型,例如文本、音频、视频和图片。

大数据通常包括具有不同大小的数据集。这些系统在规定的时间内处理如此大量数据几乎是不可能的。大数据的体量是一个不断变化的目标,截至 2012 年,单一数据集的大小范围从几十个 TB 到多个 PB 不等。面对这一看似不可逾越的挑战,完全新的平台被称为大数据平台。

https://github.com/OpenDocCN/freelearn-ds-pt5-zh/raw/master/docs/bgdt-anal-r-hdp/img/3282OS_Preface_03.jpg

获取关于持有大数据的著名组织的信息

一些持有大数据的著名组织如下:

  • Facebook:它拥有 40 PB 的数据,每天捕获 100 TB 的数据

  • Yahoo!:它拥有 60 PB 的数据

  • Twitter:它每天捕获 8 TB 数据

  • eBay:它有 40 PB 的数据,每天捕获 50 TB 数据

被视为大数据的数据量因公司而异。虽然一个公司的大数据对于另一个公司来说可能是小数据,但有些共同点:无法完全装入内存或磁盘,数据流入迅速,需要处理,并且可以从分布式软件栈中受益。对于一些公司来说,10 TB 的数据会被视为大数据,而对其他公司来说,1 PB 的数据才是大数据。所以,只有你能确定数据是否真的是大数据。可以说,它通常会从低 TB 范围开始。

另一个值得问的问题是,既然你没有捕捉和保留足够的数据,你认为自己现在没有大数据问题吗?在某些情况下,企业会字面上丢弃数据,因为没有经济高效的方式来存储和处理它。通过像 Hadoop 这样的平台,可以开始捕获和存储所有这些数据。

介绍 Hadoop

Apache Hadoop 是一个开源的 Java 框架,用于在大规模的商品硬件集群上处理和查询大量数据。Hadoop 是一个顶级的 Apache 项目,由 Yahoo!和 Doug Cutting 发起并领导。它依赖来自世界各地的活跃社区贡献者的支持,才能取得成功。

在 Yahoo!的大力技术投资下,Apache Hadoop 已经成为企业级云计算技术。它正逐渐成为大数据处理的行业事实框架。

Hadoop 改变了大规模计算的经济学和动态。其影响可以归结为四个显著特点。Hadoop 实现了可扩展、具有成本效益、灵活且容错的解决方案。

探索 Hadoop 功能

Apache Hadoop 具有两个主要特点:

  • HDFS(Hadoop 分布式文件系统)

  • MapReduce

学习 Hadoop 组件

Hadoop 包括一个生态系统,其中包含在核心 HDFS 和 MapReduce 层之上构建的其他产品,用于支持平台上的各种操作。以下是一些流行的 Hadoop 组件:

  • Mahout:这是一个广泛的机器学习算法库。

  • Pig:Pig 是一种高级语言(如 PERL),用于分析大数据集,具有自己的语言语法来表达数据分析程序,并配备了评估这些程序的基础设施。

  • Hive:Hive 是一个为 Hadoop 设计的数据仓库系统,它简化了数据汇总、临时查询和对存储在 HDFS 中的大数据集的分析。它有自己的类似 SQL 的查询语言,称为 Hive 查询语言HQL),用于向 Hadoop 发出查询命令。

  • HBaseHBaseHadoop 数据库)是一个分布式、面向列的数据库。HBase 使用 HDFS 作为底层存储。它支持使用 MapReduce 进行批处理计算和原子查询(随机读取)。

  • Sqoop:Apache Sqoop 是一个工具,旨在高效地在 Hadoop 与结构化关系型数据库之间传输大规模数据。Sqoop是(SQ)L 到 Had(oop)的缩写。

  • ZooKeeper:ZooKeeper 是一个集中式服务,用于维护配置信息、命名、提供分布式同步和组服务,这些对于各种分布式系统非常有用。

  • Ambari:一个基于 Web 的工具,用于配置、管理和监控 Apache Hadoop 集群,支持 Hadoop HDFS、Hadoop MapReduce、Hive、HCatalog、HBase、ZooKeeper、Oozie、Pig 和 Sqoop。

理解为何要将 R 与 Hadoop 结合使用

我还想说,有时数据存储在 HDFS 中(以各种格式)。由于许多数据分析师在 R 中非常高效,因此使用 R 处理通过 Hadoop 相关工具存储的数据是非常自然的。

如前所述,R 的优势在于其能够通过丰富的包库进行数据分析,但在处理非常大的数据集时则显得力不从心。而 Hadoop 的优势则在于能够存储和处理 TB 甚至 PB 范围内的海量数据。如此庞大的数据集无法完全放入内存,因为每台机器的 RAM 无法容纳如此大的数据集。解决方法是对有限的数据块进行分析,也称为采样,或者将 R 的分析能力与 Hadoop 的存储和处理能力结合,最终得到理想的解决方案。这样的解决方案还可以通过云平台(如 Amazon EMR)实现。

本书内容介绍

第一章,准备使用 R 与 Hadoop,介绍了 R 与 Hadoop 的基本信息以及安装过程。

第二章,编写 Hadoop MapReduce 程序,涵盖了 Hadoop MapReduce 的基础知识以及使用 Hadoop 执行 MapReduce 的方法。

第三章,R 与 Hadoop 的集成,展示了通过各种数据处理过程部署和运行 RHadoop 和 RHIPE 的示例 MapReduce 程序。

第四章,使用 Hadoop Streaming 与 R,展示了如何在 R 中使用 Hadoop Streaming。

第五章,使用 R 与 Hadoop 学习数据分析,通过展示实际的数据分析问题来介绍数据分析项目的生命周期。

第六章,通过机器学习理解大数据分析,介绍了如何使用机器学习技术通过 RHadoop 进行大数据分析。

第七章,从各种数据库导入和导出数据,介绍了如何与流行的关系数据库接口,以便使用 R 进行数据的导入和导出操作。

附录,参考文献,描述了所有章节内容相关的额外资源链接。

本书所需内容

由于我们将使用 R 和 Hadoop 进行大数据分析,您应具备基本的 R 和 Hadoop 知识,并了解如何进行实际操作。此外,您需要安装并配置好 R 和 Hadoop。如果您已经拥有较大规模的数据和可以通过数据驱动技术(如 R 和 Hadoop 函数)解决的问题,那将是非常有帮助的。

本书的目标读者

本书非常适合那些希望利用 Hadoop 进行大数据分析的 R 开发者。他们希望掌握 R 与 Hadoop 的所有集成技巧,学习如何编写 Hadoop MapReduce,以及如何在 R 中开发和运行 Hadoop MapReduce 的教程。本书也适用于那些了解 Hadoop 并希望利用 R 包在大数据上构建智能应用程序的人。如果读者有基本的 R 知识将更有帮助。

约定

本书中有多种文本样式,用来区分不同类型的信息。以下是这些样式的一些示例及其含义的解释。

文本中的代码词、数据库表名、文件夹名、文件名、文件扩展名、路径名、虚拟网址、用户输入和 Twitter 用户名等会以如下形式显示:“准备Map()输入。”

代码块的格式如下:

<property>
<name>mapred.job.tracker</name>
<value>localhost:54311</value>
<description>The host and port that the MapReduce job tracker runs
at. If "local", then jobs are run in-process as a single map
and reduce task.
</description>
</property>

任何命令行输入或输出均按如下格式书写:

// Setting the environment variables for running Java and Hadoop commands
export HADOOP_HOME=/usr/local/hadoop
export JAVA_HOME=/usr/lib/jvm/java-6-sun

新术语重要词汇以粗体显示。您在屏幕上看到的单词,例如菜单或对话框中的单词,会以这种形式出现在文本中:“打开密码选项卡。”

注意

警告或重要注意事项会以框体的形式显示。

提示

提示和技巧会像这样展示。

读者反馈

我们始终欢迎读者的反馈。让我们知道您对这本书的看法——您喜欢的内容或者可能不喜欢的地方。读者的反馈对我们非常重要,它能帮助我们开发出您能从中获得最大价值的书籍。

若要向我们发送一般性反馈,请通过电子邮件 <feedback@packtpub.com> 与我们联系,并在邮件主题中提到书名。

如果您擅长某个主题,并且有兴趣编写或贡献一本书,请参阅我们在www.packtpub.com/authors上的作者指南。

客户支持

现在,您已经成为一本 Packt 书籍的骄傲拥有者,我们提供了多种帮助您最大化购买价值的资源。

下载示例代码

您可以从您的帐户下载所有 Packt 书籍的示例代码文件,网址为www.packtpub.com。如果您在其他地方购买了本书,可以访问www.packtpub.com/support,注册后我们将直接通过电子邮件发送文件给您。

勘误

虽然我们已尽一切努力确保内容的准确性,但错误确实会发生。如果您在我们的书籍中发现错误——可能是文本或代码中的错误——我们将不胜感激地请您向我们报告。通过这样做,您可以帮助其他读者避免沮丧,并帮助我们改进本书的后续版本。如果您发现任何勘误,请访问www.packtpub.com/submit-errata,选择您的书籍,点击勘误提交表格链接,并输入您的勘误细节。一旦确认您的勘误,您的提交将被接受,并将勘误上传到我们的网站上,或添加到任何现有勘误列表中,添加到该书籍的勘误部分。可以通过访问www.packtpub.com/support来查看任何现有的勘误。

海盗行为

互联网上侵犯版权材料的盗版问题是所有媒体都在不断面对的问题。在 Packt,我们非常重视我们版权和许可的保护。如果您在任何形式的互联网上发现我们作品的非法副本,请立即向我们提供位置地址或网站名称,以便我们采取措施。

请通过<copyright@packtpub.com>联系我们,并附上涉嫌侵权材料的链接。

我们感谢您帮助我们保护作者和为您提供有价值的内容的能力。

问题

如果您在阅读本书的过程中遇到任何问题,可以通过<questions@packtpub.com>与我们联系,我们将尽力解决。

第一章:开始使用 R 和 Hadoop

第一章已经包含了 R 和 Hadoop 基础的多个主题,如下所示:

  • R 安装、功能和数据建模

  • Hadoop 安装、功能和组件

在前言中,我们向你介绍了 R 和 Hadoop。本章将重点帮助你开始使用这两项技术。到目前为止,R 主要用于统计分析,但由于功能和包的不断增加,它在多个领域变得流行,例如机器学习、可视化和数据操作。R 不会将所有数据(大数据)加载到机器内存中,因此,可以选择 Hadoop 来加载数据作为大数据。并非所有算法都能在 Hadoop 上运行,而且这些算法通常不是 R 算法。尽管如此,使用 R 进行分析时,仍然存在与大数据相关的若干问题。为了分析数据集,R 会将其加载到内存中,而如果数据集很大,通常会因“无法分配大小为 x 的向量”等异常而失败。因此,为了处理大数据集,结合 R 与 Hadoop 集群的计算能力,可以大大增强 R 的处理能力。Hadoop 是一个非常流行的框架,提供了并行处理能力。因此,我们可以在 Hadoop 集群上使用 R 算法或分析处理来完成工作。

https://github.com/OpenDocCN/freelearn-ds-pt5-zh/raw/master/docs/bgdt-anal-r-hdp/img/3282OS_01_00.jpg

如果我们考虑将 R 和 Hadoop 结合使用,R 将负责数据分析操作,包括数据加载、探索、分析和可视化等初步功能,而 Hadoop 将负责并行数据存储及处理分布式数据的计算能力。

在可负担得起的大数据技术出现之前,分析通常是在单台计算机上的有限数据集上运行的。当应用到大数据集时,高级机器学习算法非常有效,而这仅能在数据可以通过分布式数据存储系统进行存储和处理的大型集群中实现。在接下来的章节中,我们将介绍如何在不同操作系统上安装 R 和 Hadoop,以及将 R 和 Hadoop 链接的可能方式。

安装 R

你可以访问 R 官方网站下载合适的版本。

这里提供了三种不同操作系统的步骤。我们已考虑了 Windows、Linux 和 Mac OS 来安装 R。下载最新版本的 R,因为它将包含所有最新的修补程序和解决过去 bug 的版本。

对于 Windows,按照以下步骤进行操作:

  1. 访问 www.r-project.org

  2. 点击 CRAN 部分,选择 CRAN 镜像,然后选择你的 Windows 操作系统(坚持使用 Linux;Hadoop 几乎总是在 Linux 环境中使用)。

  3. 从镜像站点下载最新的 R 版本。

  4. 执行下载的 .exe 文件以安装 R。

对于 Linux-Ubuntu,按照以下步骤进行操作:

  1. 访问 www.r-project.org

  2. 点击CRAN部分,选择CRAN 镜像,然后选择你的操作系统。

  3. /etc/apt/sources.list 文件中添加 CRAN <mirror> 条目。

  4. 使用 sudo apt-get update 命令从仓库下载并更新包列表。

  5. 使用 sudo apt-get install r-base 命令安装 R 系统。

对于 Linux-RHEL/CentOS,请按照以下步骤操作:

  1. 访问 www.r-project.org

  2. 点击CRAN,选择CRAN 镜像,然后选择 Red Hat 操作系统。

  3. 下载 R-*core-*.rpm 文件。

  4. 使用 rpm -ivh R-*core-*.rpm 命令安装 .rpm 包。

  5. 使用 sudo yum install R 命令安装 R 系统。

对于 Mac,请按照以下步骤操作:

  1. 访问 www.r-project.org

  2. 点击CRAN,选择CRAN 镜像,然后选择你的操作系统。

  3. 下载以下文件:pkggfortran-*.dmgtcltk-*.dmg

  4. 安装 R-*.pkg 文件。

  5. 然后,安装 gfortran-*.dmgtcltk-*.dmg 文件。

在安装基础 R 包后,建议安装 RStudio,这是一个功能强大且直观的集成开发环境IDE)用于 R 语言。

提示

我们可以使用 Revolution Analytics 提供的 R 发行版作为现代数据分析工具,进行统计计算和预测分析,该工具提供免费版和付费版。还支持 Hadoop 集成,可进行大数据分析。

安装 RStudio

要安装 RStudio,请执行以下步骤:

  1. 访问 www.rstudio.com/ide/download/desktop

  2. 下载适用于你的操作系统的最新版本 RStudio。

  3. 执行安装程序文件并安装 RStudio。

RStudio 组织和用户社区已经开发了许多用于图形和可视化的 R 包,如 ggplot2plyrShinyRpubsdevtools

理解 R 语言的特性

目前有超过 3,000 个 R 包,并且这个数量每天都在增长。试图在任何一本书中解释所有这些包将超出其范围。本书只关注 R 的关键特性以及最常用和最受欢迎的包。

使用 R 包

R 包是 R 功能的自包含单元,可以作为函数调用。一个很好的类比是 Java 中的 .jar 文件。R 包库庞大,涵盖了各种操作,从统计运算、机器学习到丰富的图形可视化和绘图。每个包将包含一个或多个 R 函数。R 包是一个可重用的实体,可以被他人共享和使用。R 用户可以安装包含所需功能的包并开始调用包中的函数。一个全面的包列表可以在 cran.r-project.org/ 中找到,称为综合 R 档案网络CRAN)。

执行数据操作

R 可以进行广泛的操作。统计操作,如均值、最小值、最大值、概率、分布和回归。机器学习操作,如线性回归、逻辑回归、分类和聚类。通用数据处理操作如下:

  • 数据清理:此选项用于清理大量数据集。

  • 数据探索:此选项用于探索数据集的所有可能值。

  • 数据分析:此选项用于对数据进行描述性和预测性分析数据可视化,即分析输出编程的可视化。

为了构建一个有效的分析应用程序,有时我们需要使用在线 应用程序编程接口API)来挖掘数据,通过便捷的服务进行分析,并通过第三方服务进行可视化。此外,要自动化数据分析过程,编程将是最有用的功能。

R 拥有自己的编程语言来处理数据。此外,可用的包可以帮助将 R 与其他编程功能集成。R 支持面向对象编程概念。它还能够与其他编程语言(如 Java、PHP、C 和 C++)进行集成。有多个包作为中间层编程功能,帮助进行数据分析,这些包类似于 sqldfhttrRMongoRgoogleMapsRGoogleAnalyticsgoogle-prediction-api-r-client

增强社区支持

随着 R 用户数量的增加,相关的 R 小组也在不断增多。因此,R 学习者或开发者可以轻松地与其他人连接,并借助多个 R 小组或社区解决他们的疑惑。

以下是一些可以找到有用的流行资源:

  • R 邮件列表:这是 R 项目所有者创建的官方 R 小组。

  • R 博客:R 拥有无数的博客作者,他们在多个 R 应用领域进行写作。最受欢迎的博客网站之一是 www.r-bloggers.com/,所有的博客作者都会在该网站贡献自己的博客。

  • Stack Overflow:这是一个很棒的技术知识分享平台,程序员可以在这里发布技术问题,热心的程序员会提供解决方案。欲了解更多信息,请访问 stats.stackexchange.com/

  • 小组:在 LinkedIn 和 Meetup 上还存在许多其他小组,全球的专业人士会聚集在一起讨论他们的问题和创新想法。

  • 书籍:关于 R 的书籍也有很多。其中一些受欢迎的书籍包括 《R 实战》,作者 Rob KabacoffManning 出版社《R 速查手册》,作者 Joseph AdlerO’Reilly Media《R 与数据挖掘》,作者 Yanchang ZhaoAcademic Press;以及 《R 图形 cookbook》,作者 Hrishi MittalPackt Publishing

在 R 中进行数据建模

数据建模是一种机器学习技术,用于从历史数据集中识别隐藏的模式,这些模式将有助于在相同数据上进行未来值预测。这些技术高度关注过去用户的行为并学习他们的偏好。许多流行的组织已经采纳了这些数据建模技术,以根据客户的过去交易来了解他们的行为。这些技术将分析数据并预测客户在寻找什么。Amazon、Google、Facebook、eBay、LinkedIn、Twitter 等众多组织正在使用数据挖掘来改变定义应用程序。

最常见的数据挖掘技术如下:

  • 回归:在统计学中,回归是一种经典技术,用于通过拟合变量值的状态线来识别两个或多个变量之间的标量关系。这种关系将帮助预测未来事件中变量的值。例如,任何变量 y 可以被建模为另一个变量 x 的线性函数,公式为y = mx+c。其中,x 是预测变量,y 是响应变量,m 是直线的斜率,c 是截距。产品或服务的销售预测以及股票价格预测可以通过这种回归方法实现。R 通过lm方法提供了这一回归功能,默认情况下,该方法已存在于 R 中。

  • 分类:这是一种机器学习技术,用于标记提供的训练示例集的观察结果。通过这种方法,我们可以将观察结果分类为一个或多个标签。销售可能性、在线欺诈检测和癌症分类(医学科学)是分类问题的常见应用。Google Mail 使用此技术将电子邮件分类为垃圾邮件或非垃圾邮件。在 R 中,glmglmnetksvmsvmrandomForest方法可以用于分类功能。

  • 聚类:这种技术的核心是将相似的项目从给定的集合中组织成组。用户细分和图像压缩是聚类技术的最常见应用。市场细分、社交网络分析、计算机集群组织以及天文数据分析都是聚类的应用。Google 新闻利用这些技术将相似的新闻项分组到同一类别中。在 R 中,可以通过knnkmeansdistpvclustMclust方法实现聚类。

  • 推荐:推荐算法用于推荐系统,而这些系统是当今最容易识别的机器学习技术。Web 内容推荐可能包括类似的网站、博客、视频或相关内容。此外,在线物品的推荐对于交叉销售和追加销售也非常有帮助。我们都见过在线购物门户,尝试根据用户的过去行为推荐书籍、手机或任何可以在网上销售的商品。Amazon 是一个知名的电子商务门户,通过推荐系统生成了 29% 的销售额。推荐系统可以通过 Recommender() 和 R 中的 recommenderlab 包来实现。

安装 Hadoop

现在,我们假设你已经了解了 R,它是什么,如何安装,主要特点是什么,以及为什么你可能想要使用它。接下来,我们需要了解 R 的局限性(这也是介绍 Hadoop 的一个更好的方式)。在处理数据之前,R 需要将数据加载到 随机存取存储器 (RAM) 中。因此,数据需要小于可用的机器内存。对于大于机器内存的数据,我们将其视为大数据(仅在我们的情况下,因为大数据有很多其他定义)。

为了避免大数据问题,我们需要扩展硬件配置;然而,这只是一个临时解决方案。要解决这个问题,我们需要一个能够存储数据并在大型计算机集群上执行并行计算的 Hadoop 集群。Hadoop 是最流行的解决方案。Hadoop 是一个开源的 Java 框架,是由 Apache 软件基金会处理的顶级项目。Hadoop 的灵感来自 Google 文件系统和 MapReduce,主要设计用于通过分布式处理操作大数据。

Hadoop 主要支持 Linux 操作系统。在 Windows 上运行 Hadoop,我们需要使用 VMware 在 Windows 操作系统中托管 Ubuntu。有许多使用和安装 Hadoop 的方法,但在这里我们将考虑最适合 R 的方式。在结合 R 和 Hadoop 之前,我们先来了解一下 Hadoop 是什么。

提示

机器学习包含所有数据建模技术,可以通过这个网页链接 en.wikipedia.org/wiki/Machine_learning 进行探索。

由 Michael Noll 撰写的 Hadoop 安装结构博客可以在 www.michael-noll.com/tutorials/running-hadoop-on-ubuntu-linux-single-node-cluster/ 上找到。

理解不同的 Hadoop 模式

Hadoop 有三种不同的模式:

  • 独立模式:在此模式下,您无需启动任何 Hadoop 守护进程。只需调用 ~/Hadoop-directory/bin/hadoop,它将作为单一 Java 进程执行 Hadoop 操作。此模式推荐用于测试。它是默认模式,您无需配置任何其他内容。所有守护进程,如 NameNode、DataNode、JobTracker 和 TaskTracker 都在一个 Java 进程中运行。

  • 伪模式:在此模式下,您为所有节点配置 Hadoop。为每个 Hadoop 组件或守护进程(如单主机上的迷你集群)启动单独的 Java 虚拟机JVM)。

  • 完全分布式模式:在此模式下,Hadoop 会分布到多台机器上。为 Hadoop 组件配置专用主机。因此,每个守护进程都有独立的 JVM 进程。

理解 Hadoop 安装步骤

Hadoop 可以通过多种方式安装;我们将考虑与 R 集成更好的方式。我们将选择 Ubuntu 操作系统,因为它易于安装和访问。

  1. 在 Linux 上安装 Hadoop,Ubuntu 版本(单节点和多节点集群)。

  2. 在 Ubuntu 上安装 Cloudera Hadoop。

在 Linux 上安装 Hadoop,Ubuntu 版本(单节点集群)

要在 Ubuntu 操作系统上以伪模式安装 Hadoop,我们需要满足以下先决条件:

  • Sun Java 6

  • 专用 Hadoop 系统用户

  • 配置 SSH

  • 禁用 IPv6

提示

提供的 Hadoop 安装将支持 Hadoop MRv1。

按照以下步骤安装 Hadoop:

  1. 从 Apache 软件基金会下载最新的 Hadoop 源代码。这里我们考虑的是 Apache Hadoop 1.0.3,而最新版本是 1.1.x。

    // Locate to Hadoop installation directory
    $ cd /usr/local
    
    // Extract the tar file of Hadoop distribution
    $ sudo tar xzf hadoop-1.0.3.tar.gz
    
    // To move Hadoop resources to hadoop folder 
    $ sudo mv hadoop-1.0.3 hadoop
    
    // Make user-hduser from group-hadoop as owner of hadoop directory
    $ sudo chown -R hduser:hadoop hadoop
    
    
  2. $JAVA_HOME$HADOOP_HOME 变量添加到 Hadoop 系统用户的 .bashrc 文件中,更新后的 .bashrc 文件如下所示:

    // Setting the environment variables for running Java and Hadoop commands
    export HADOOP_HOME=/usr/local/hadoop
    export JAVA_HOME=/usr/lib/jvm/java-6-sun
    
    // alias for Hadoop commands
    unalias fs &> /dev/null
    alias fs="hadoop fs"
    unalias hls &> /dev/null
    aliashls="fs -ls"
    
    // Defining the function for compressing the MapReduce job output by lzop command
    lzohead () {
    hadoopfs -cat $1 | lzop -dc | head -1000 | less
    }
    
    // Adding Hadoop_HoME variable to PATH 
    export PATH=$PATH:$HADOOP_HOME/bin
    
    
  3. 使用 conf/*-site.xml 格式更新 Hadoop 配置文件。

最终,三个文件将如下所示:

  • conf/core-site.xml

    <property>
    <name>hadoop.tmp.dir</name>
    <value>/app/hadoop/tmp</value>
    <description>A base for other temporary directories.</description>
    </property>
    <property>
    <name>fs.default.name</name>
    <value>hdfs://localhost:54310</value>
    <description>The name of the default filesystem. A URI whose
    scheme and authority determine the FileSystem implementation. The
    uri's scheme determines the config property (fs.SCHEME.impl) naming
    theFileSystem implementation class. The uri's authority is used to
    determine the host, port, etc. for a filesystem.</description>
    </property>
    
  • conf/mapred-site.xml

    <property>
    <name>mapred.job.tracker</name>
    <value>localhost:54311</value>
    <description>The host and port that the MapReduce job tracker runs
    at. If "local", then jobs are run in-process as a single map
    and reduce task.
    </description>
    </property>
    
  • conf/hdfs-site.xml

    <property>
    <name>dfs.replication</name>
    <value>1</value>
    <description>Default block replication.
      The actual number of replications can be specified when the file is created.
      The default is used if replication is not specified in create time.
    </description>
    

编辑完这些配置文件后,我们需要在 Hadoop 集群或节点之间设置分布式文件系统。

  • 通过以下命令格式化 Hadoop 分布式文件系统HDFS):

    hduser@ubuntu:~$ /usr/local/hadoop/bin/hadoopnamenode -format
    
    
  • 使用以下命令行启动您的单节点集群:

    hduser@ubuntu:~$ /usr/local/hadoop/bin/start-all.sh
    
    

提示

下载示例代码

您可以从您的账户在 www.packtpub.com 下载所有您购买的 Packt 图书的示例代码文件。如果您在其他地方购买了此书,您可以访问 www.packtpub.com/support 并注册,将文件直接通过电子邮件发送给您。

在 Linux 上安装 Hadoop,Ubuntu 版本(多节点集群)

我们已经学习了如何在单节点集群上安装 Hadoop。现在我们将看到如何在多节点集群上安装 Hadoop(完全分布式模式)。

为此,我们需要多个节点配置一个单节点 Hadoop 集群。要在多节点上安装 Hadoop,我们需要按照上一节中描述的方式先配置好单节点 Hadoop 集群。

在安装完单节点 Hadoop 集群后,我们需要执行以下步骤:

  1. 在网络配置阶段,我们将使用两个节点来设置完整的分布式 Hadoop 模式。为了彼此通信,这些节点需要在软件和硬件配置上处于同一网络中。

  2. 在这两个节点中,一个将被视为主节点,另一个将被视为从节点。因此,为了执行 Hadoop 操作,主节点需要连接到从节点。我们将在主机上输入 192.168.0.1,在从机上输入 192.168.0.2

  3. 更新两个节点中的/etc/hosts目录。它将显示为 192.168.0.1 master192.168.0.2 slave

    提示

    你可以像我们在单节点集群设置中做的那样进行安全外壳SSH)设置。欲了解更多详情,请访问 www.michael-noll.com

  4. 更新 conf/*-site.xml:我们必须在所有节点中更改这些配置文件。

    • conf/core-site.xmlconf/mapred-site.xml:在单节点设置中,我们已经更新了这些文件。所以现在我们只需要将值标签中的 localhost 替换为 master

    • conf/hdfs-site.xml:在单节点设置中,我们将 dfs.replication 的值设置为 1。现在我们需要将其更新为 2

  5. 在格式化 HDFS 阶段,在我们启动多节点集群之前,我们需要使用以下命令格式化 HDFS(从主节点执行):

    bin/hadoop namenode -format
    
    

现在,我们已经完成了安装多节点 Hadoop 集群的所有步骤。要启动 Hadoop 集群,我们需要遵循以下步骤:

  1. 启动 HDFS 守护进程:

    hduser@master:/usr/local/hadoop$ bin/start-dfs.sh
    
    
  2. 启动 MapReduce 守护进程:

    hduser@master:/usr/local/hadoop$ bin/start-mapred.sh
    
    
  3. 或者,我们可以通过一个命令启动所有守护进程:

    hduser@master:/usr/local/hadoop$ bin/start-all.sh
    
    
  4. 要停止所有这些守护进程,执行:

    hduser@master:/usr/local/hadoop$ bin/stop-all.sh
    
    

这些安装步骤是受启发于 Michael Noll 的博客(www.michael-noll.com)的,他是位于欧洲瑞士的研究员和软件工程师。他在 VeriSign 担任 Apache Hadoop 堆栈的大规模计算基础设施技术负责人。

现在,Hadoop 集群已经在你的机器上设置完成。要在单节点或多节点上安装相同的 Hadoop 集群并扩展 Hadoop 组件,可以尝试使用 Cloudera 工具。

在 Ubuntu 上安装 Cloudera Hadoop

Cloudera Hadoop (CDH) 是 Cloudera 的开源发行版,旨在面向企业级部署 Hadoop 技术。Cloudera 也是 Apache 软件基金会的赞助商。CDH 提供两个版本:CDH3 和 CDH4. 要安装其中之一,您必须使用带有 10.04 LTS 或 12.04 LTS 的 Ubuntu(此外,您还可以尝试 CentOS、Debian 和 Red Hat 系统)。如果您在多台计算机的集群上安装 Hadoop,Cloudera 管理器将使安装过程变得更加容易,它提供基于 GUI 的 Hadoop 和其组件的安装。强烈建议在大型集群中使用该工具。

我们需要满足以下先决条件:

  • 配置 SSH

  • 操作系统应符合以下标准:

    • Ubuntu 10.04 LTS 或 12.04 LTS(64 位)

    • Red Hat Enterprise Linux 5 或 6

    • CentOS 5 或 6

    • Oracle Enterprise Linux 5

    • SUSE Linux Enterprise Server 11(SP1 或 Lasso)

    • Debian 6.0

安装步骤如下:

  1. 下载并运行 Cloudera 管理器安装程序:要初始化 Cloudera 管理器安装过程,首先需要从 Cloudera 网站的下载区下载 cloudera-manager-installer.bin 文件。下载后,将其存储在集群中,以便所有节点都可以访问此文件。允许用户执行 cloudera-manager-installer.bin 文件。运行以下命令开始执行。

    $ sudo ./cloudera-manager-installer.bin
    
    
  2. 阅读 Cloudera 管理器 Readme 文件,然后点击 下一步

  3. 启动 Cloudera 管理器管理员控制台:Cloudera 管理器管理员控制台允许您使用 Cloudera 管理器在集群上安装、管理和监控 Hadoop。接受 Cloudera 服务提供商的许可后,您需要通过在地址栏中输入 http://localhost:7180 来转到本地网页浏览器。您还可以使用以下任何浏览器:

    • Firefox 11 或更高版本

    • Google Chrome

    • Internet Explorer

    • Safari

  4. 使用 admin 作为用户名和密码登录 Cloudera 管理器控制台。以后可以根据需要更改密码。

  5. 使用 Cloudera 管理器通过浏览器进行自动化的 CDH3 安装和配置:此步骤将从 Cloudera 向您的计算机安装大部分所需的 Cloudera Hadoop 包。步骤如下:

    1. 安装并验证您的 Cloudera 管理器许可证密钥文件(如果您选择了完整版本的软件)。

    2. 为 CDH 集群安装指定主机名或 IP 地址范围。

    3. 使用 SSH 连接到每个主机。

    4. 安装 Java 开发工具包 (JDK)(如果尚未安装),Cloudera 管理器代理,以及 CDH3 或 CDH4 在每个集群主机上。

    5. 在每个节点上配置 Hadoop 并启动 Hadoop 服务。

  6. 运行向导并使用 Cloudera 管理器后,您应该尽快更改默认管理员密码。更改管理员密码,请按照以下步骤操作:

    1. 点击带有齿轮标志的图标,显示管理页面。

    2. 打开 密码 标签。

    3. 输入新密码两次,然后单击Update

  7. 测试 Cloudera Hadoop 的安装:您可以通过登录 Cloudera 管理器管理控制台并单击Services选项卡来检查您集群上的 Cloudera 管理器安装。您应该看到类似下面这样的屏幕截图:https://github.com/OpenDocCN/freelearn-ds-pt5-zh/raw/master/docs/bgdt-anal-r-hdp/img/3282OS_01_01.jpg

    Cloudera 管理器管理控制台

  8. 您还可以单击每个服务以查看更详细的信息。例如,如果您单击hdfs1链接,您可能会看到类似下面这样的屏幕截图:https://github.com/OpenDocCN/freelearn-ds-pt5-zh/raw/master/docs/bgdt-anal-r-hdp/img/3282OS_01_02.jpg

    Cloudera 管理器管理控制台——HDFS 服务

    提示

    要避免这些安装步骤,请使用预配置的 Amazon Elastic MapReduce 和 MapReduce 实例。

    如果你想在 Windows 上使用 Hadoop,请尝试由 Hortonworks 提供的 HDP 工具。这是完全开源的、企业级的 Hadoop 发行版。你可以在hortonworks.com/download/下载 HDP 工具。

理解 Hadoop 的特性

Hadoop 专为两个核心概念而设计:HDFS 和 MapReduce。两者都与分布式计算相关。MapReduce 被认为是 Hadoop 的核心,它执行分布式数据上的并行处理。

让我们看看 Hadoop 的特性的更多细节:

  • HDFS

  • MapReduce

理解 HDFS

HDFS 是 Hadoop 自带的机架感知文件系统,是 Hadoop 的基于 UNIX 的数据存储层。HDFS 源自于 Google 文件系统的概念。Hadoop 的一个重要特性是数据和计算的分区跨多个(数千个)主机,并在靠近其数据的地方并行执行应用程序计算。在 HDFS 上,数据文件被复制为集群中的块序列。通过简单添加商品服务器,Hadoop 集群可以扩展计算能力、存储能力和 I/O 带宽。HDFS 可以通过多种不同的方式从应用程序访问。本地,HDFS 为应用程序提供了一个 Java API。

Yahoo!的 Hadoop 集群覆盖 40,000 台服务器,存储 40PB 的应用程序数据,其中最大的 Hadoop 集群为 4,000 台服务器。此外,全球还有 100 多个组织使用 Hadoop。

理解 HDFS 的特性

现在让我们来看看 HDFS 的特性:

  • 容错

  • 使用商品硬件运行

  • 能够处理大型数据集

  • 主从范式

  • 只有一次文件访问权限

理解 MapReduce

MapReduce 是一种用于处理分布在大型集群上的大型数据集的编程模型。MapReduce 是 Hadoop 的核心。其编程范式允许在配置有 Hadoop 集群的数千台服务器上执行大规模数据处理。这源自于 Google MapReduce。

Hadoop MapReduce 是一个软件框架,便于编写应用程序,能够在大型集群(数千个节点)的商品硬件上以可靠、容错的方式并行处理大量数据(多 TB 数据集)。该 MapReduce 范式分为两个阶段,Map 和 Reduce,主要处理数据的键值对。Map 和 Reduce 任务在集群中顺序执行;Map 阶段的输出成为 Reduce 阶段的输入。以下是这些阶段的解释:

  • Map 阶段:数据集一旦被划分,就会分配给任务跟踪器以执行 Map 阶段。数据操作将应用于数据,并将映射的键值对作为 Map 阶段的输出。

  • Reduce 阶段:然后,主节点收集所有子问题的答案,并以某种方式将它们组合成最终输出;即最初试图解决的问题的答案。

并行计算的五个常见步骤如下:

  1. 准备Map()输入:这将逐行读取输入数据,并为每行发出键值对,或者我们可以根据需求显式地进行更改。

    • 映射输入:list(k1,v1)
  2. 运行用户提供的Map()代码

    • Map 输出:list(k2,v2)
  3. 将 Map 输出数据混排到 Reduce 处理器中。同时,将相似的键混排(将其分组),并输入到同一个 reducer 中。

  4. 运行用户提供的Reduce()代码:该阶段将运行开发人员设计的自定义 reducer 代码,在混排的数据上运行并发出键值对。

    • 减少输入:(k2, list(v2))

    • 减少输出:(k3, v3)

  5. 产生最终输出:最终,主节点收集所有 reducer 输出,并将其组合后写入文本文件。

    提示

    有关 Google 文件系统的参考链接可以在research.google.com/archive/gfs.html找到,Google MapReduce 的链接可以在research.google.com/archive/mapreduce.html找到。

学习 HDFS 和 MapReduce 架构

由于 HDFS 和 MapReduce 被认为是 Hadoop 框架的两个主要特性,我们将重点关注这两者。因此,首先让我们从 HDFS 开始。

理解 HDFS 架构

HDFS 可以呈现为主/从架构。HDFS 的主节点被称为 NameNode,而从节点为 DataNode。NameNode 是一个服务器,管理文件系统的命名空间,并控制客户端对文件的访问(打开、关闭、重命名等)。它将输入数据分割成块,并公告哪个数据块将存储在哪个 DataNode 中。DataNode 是一个从节点,存储分区数据集的副本,并根据请求提供数据。它还执行数据块的创建和删除操作。

HDFS 的内部机制将文件分为一个或多个数据块,这些数据块存储在一组数据节点中。在正常情况下,复制因子为三时,HDFS 策略是将第一份副本放在本地节点上,第二份副本放在同一机架上的不同节点上,第三份副本放入不同机架的不同节点上。由于 HDFS 旨在支持大文件,HDFS 的块大小定义为 64 MB。如果需要,可以增加块大小。

了解 HDFS 组件

HDFS 通过主从架构进行管理,包含以下组件:

  • NameNode:这是 HDFS 系统的主节点。它维护目录、文件,并管理存储在 DataNode 上的数据块。

  • DataNode:这些是部署在每台机器上的从节点,提供实际的存储。它们负责为客户端提供读写数据请求的服务。

  • Secondary NameNode:负责执行定期的检查点。因此,如果 NameNode 发生故障,可以使用由 Secondary NameNode 检查点存储的快照图像进行替换。

了解 MapReduce 架构

MapReduce 也实现了主从架构。经典的 MapReduce 包含作业提交、作业初始化、任务分配、任务执行、进度和状态更新以及作业完成相关活动,这些活动主要由 JobTracker 节点管理,并由 TaskTracker 执行。客户端应用程序向 JobTracker 提交作业。然后,输入数据在集群中分配。JobTracker 计算需要处理的 map 和 reduce 的数量,命令 TaskTracker 开始执行作业。现在,TaskTracker 将资源复制到本地机器并启动 JVM 来执行 map 和 reduce 程序。与此同时,TaskTracker 定期向 JobTracker 发送更新,这可以看作是心跳信号,帮助更新 JobID、作业状态和资源使用情况。

了解 MapReduce 组件

MapReduce 通过主从架构进行管理,包含以下组件:

  • JobTracker:这是 MapReduce 系统的主节点,管理集群中的作业和资源(TaskTracker)。JobTracker 尝试将每个 map 任务调度到与正在处理数据的 TaskTracker 尽可能接近的位置,而 TaskTracker 又运行在与底层数据块相同的 DataNode 上。

  • TaskTracker:这些是部署在每台机器上的从节点,负责按照 JobTracker 的指示运行 map 和 reduce 任务。

通过图示理解 HDFS 和 MapReduce 架构

在此图中,包含了 HDFS 和 MapReduce 的主从组件,其中 NameNode 和 DataNode 来自 HDFS,而 JobTracker 和 TaskTracker 来自 MapReduce 范式。

这两种由主从候选者组成的范式各自有其特定的职责,用于处理 MapReduce 和 HDFS 操作。在下图中,图像分为两个部分:前一部分是 MapReduce 层,后一部分是 HDFS 层。

https://github.com/OpenDocCN/freelearn-ds-pt5-zh/raw/master/docs/bgdt-anal-r-hdp/img/3282OS_01_03.jpg

HDFS 和 MapReduce 架构

Hadoop 是一个顶级的 Apache 项目,是一个非常复杂的 Java 框架。为避免技术复杂性,Hadoop 社区开发了多个 Java 框架,这些框架为 Hadoop 的功能增添了额外的价值。它们被视为 Hadoop 的子项目。在这里,我们将讨论几个可以视为 HDFS 或 MapReduce 抽象的 Hadoop 组件。

理解 Hadoop 子项目

Mahout 是一个流行的数据挖掘库。它采用最流行的数据挖掘可扩展机器学习算法,执行聚类、分类、回归和统计建模,以准备智能应用程序。同时,它是一个可扩展的机器学习库。

Apache Mahout 是在商业友好的 Apache 软件许可下分发的。Apache Mahout 的目标是建立一个充满活力、响应迅速且多样化的社区,促进不仅是项目本身的讨论,还包括潜在的使用案例。

以下是一些使用 Mahout 的公司:

  • Amazon:这是一个购物门户网站,提供个性化推荐服务。

  • AOL:这是一个购物门户网站,用于购物推荐。

  • Drupal:这是一个 PHP 内容管理系统,使用 Mahout 提供开源基于内容的推荐服务。

  • iOffer:这是一个购物门户网站,使用 Mahout 的频繁模式集挖掘和协同过滤技术向用户推荐商品。

  • LucidWorks Big Data:这是一家流行的分析公司,使用 Mahout 进行聚类、重复文档检测、短语提取和分类。

  • Radoop:提供一个拖拽式界面,用于大数据分析,包括 Mahout 聚类和分类算法。

  • Twitter:这是一个社交网络网站,使用 Mahout 的 潜在狄利克雷分配LDA)实现进行用户兴趣建模,并在 GitHub 上维护 Mahout 的一个分支。

  • Yahoo!:这是全球最受欢迎的网页服务提供商,使用 Mahout 的频繁模式集挖掘技术用于 Yahoo! Mail。

    提示

    Hadoop 生态系统的参考链接可以在 www.revelytix.com/?q=content/hadoop-ecosystem 找到。

Apache HBase 是一个分布式大数据存储系统,适用于 Hadoop。它允许对大数据进行随机、实时的读写访问。该系统采用了受 Google BigTable 启发创新的列式数据存储模型。

以下是使用 HBase 的公司:

  • Yahoo!:这是全球知名的网页服务提供商,用于近重复文档检测。

  • Twitter:这是一个用于版本控制存储和检索的社交网络网站。

  • Mahalo:这是一个用于相似内容推荐的知识共享服务。

  • NING:这是一个用于实时分析和报告的社交网络服务提供商。

  • StumbleUpon:这是一个通用个性化推荐系统,实时数据存储和数据分析平台。

  • Veoh:这是一个在线多媒体内容共享平台,用于用户档案系统。

    提示

    对于 Google 大数据,结构化数据的分布式存储系统,请参考链接 research.google.com/archive/bigtable.html

Hive 是一个基于 Hadoop 的数据仓库框架,由 Facebook 开发。它允许用户使用类似 SQL 的语言(如 HiveQL)进行查询,这些查询会高度抽象为 Hadoop MapReduce。这使得没有 MapReduce 经验的 SQL 程序员也能使用该数据仓库,并使其更容易与商业智能和可视化工具进行集成,以便进行实时查询处理。

Pig 是一个基于 Hadoop 的开源平台,用于通过其自己的类似 SQL 的语言 Pig Latin 来分析大规模数据集。它为海量复杂的数据并行计算提供了简单的操作和编程接口。这也更容易开发,更优化且更具扩展性。Apache Pig 是由 Yahoo! 开发的。目前,Yahoo! 和 Twitter 是主要的 Pig 用户。

对于开发者而言,直接使用 Java API 可能既繁琐又容易出错,而且还限制了 Java 程序员在 Hadoop 编程中灵活性的发挥。因此,Hadoop 提供了两种解决方案,使得数据集管理和数据集分析的 Hadoop 编程变得更容易——这些解决方案是 Pig 和 Hive,这两者经常让人混淆。

Apache Sqoop 提供了一种 Hadoop 数据处理平台,可以快速以一种全新的方式将大量数据从关系型数据库、数据仓库和其他非关系型数据库传输到 Hadoop。Apache Sqoop 是一个用于将数据从关系型数据库导入 Hadoop HDFS,或将数据从 HDFS 导出到关系型数据库的互通数据工具。

它与大多数现代关系型数据库一起工作,如 MySQL、PostgreSQL、Oracle、Microsoft SQL Server 和 IBM DB2,以及企业数据仓库。Sqoop 扩展 API 提供了一种为数据库系统创建新连接器的方法。此外,Sqoop 源代码还提供了一些流行的数据库连接器。为了执行此操作,Sqoop 首先将数据转换为 Hadoop MapReduce,并通过一些数据库模式创建和转换的逻辑来进行处理。

Apache Zookeeper 也是一个 Hadoop 子项目,用于管理 Hadoop、Hive、Pig、HBase、Solr 和其他项目。Zookeeper 是一个开源的分布式应用程序协调服务,设计基于 Fast Paxos 算法的同步、配置和命名服务,如分布式应用程序的维护。在编程中,Zookeeper 的设计采用非常简单的数据模型风格,类似于系统目录树结构。

Zookeeper 分为两部分:服务器和客户端。对于 Zookeeper 服务器集群,只有一个服务器充当领导者,接受并协调所有权限。其余的服务器是主服务器的只读副本。如果领导者服务器宕机,任何其他服务器都可以开始处理所有请求。Zookeeper 客户端连接到 Zookeeper 服务中的服务器。客户端发送请求,接收响应,访问观察事件,并通过与服务器的 TCP 连接发送心跳。

对于分布式应用程序的高性能协调服务,Zookeeper 是一个集中式服务,用于维护配置信息、命名以及提供分布式同步和组服务。所有这些服务以某种形式被分布式应用程序使用。每次实现时,都需要大量的工作来修复不可避免的 bug 和竞态条件。这些服务在应用程序部署时导致管理复杂性。

Apache Solr 是一个开源企业级搜索平台,来自 Apache 许可项目。Apache Solr 具有高度可扩展性,支持分布式搜索和索引复制引擎。这使得构建具有强大文本搜索、分面搜索、实时索引、动态聚类、数据库集成和丰富文档处理的 Web 应用程序成为可能。

Apache Solr 用 Java 编写,作为独立服务器运行,通过类似 REST 的 HTTP/XML 和 JSON API 提供搜索结果。因此,这个 Solr 服务器可以很容易地与用其他编程语言编写的应用程序集成。由于这些特点,这个搜索服务器被 Netflix、AOL、CNET 和 Zappos 等公司使用。

Ambari 是非常特定于 Hortonworks 的。Apache Ambari 是一个基于 Web 的工具,支持 Apache Hadoop 集群的供应、管理和监控。Ambari 处理大部分 Hadoop 组件,包括 HDFS、MapReduce、Hive、Pig、HBase、Zookeeper、Sqoop 和 HCatlog,作为集中管理。

此外,Ambari 能够基于 Kerberos 身份验证协议在 Hadoop 集群上安装安全性。同时,它还为用户提供基于角色的用户身份验证、授权和审计功能,帮助用户管理集成的 LDAP 和 Active Directory。

总结

在本章中,我们学习了什么是 R、Hadoop 及其特点,并了解了如何安装它们,然后才能使用 R 和 Hadoop 进行数据集分析。在下一章中,我们将学习什么是 MapReduce,以及如何使用 Apache Hadoop 开发 MapReduce 程序。

第二章:编写 Hadoop MapReduce 程序

在上一章中,我们学习了如何设置 R 和 Hadoop 开发环境。由于我们有兴趣执行大数据分析,因此我们需要学习 Hadoop 以便使用 Hadoop MapReduce 执行操作。在本章中,我们将讨论什么是 MapReduce,为什么它是必要的,如何通过 Apache Hadoop 开发 MapReduce 程序,以及更多内容。

在本章中,我们将涵盖:

  • 理解 MapReduce 的基本概念

  • 介绍 Hadoop MapReduce

  • 理解 Hadoop MapReduce 基础

  • 编写一个 Hadoop MapReduce 示例

  • 理解多种可能的 MapReduce 定义,以解决业务问题

  • 学习在 R 中编写 Hadoop MapReduce 的不同方式

理解 MapReduce 基础

如果没有集群或使用消息传递接口MPI),理解 MapReduce 基础可能是一个长期的解决方案。然而,更现实的使用场景是当数据无法存储在一块磁盘上,但可以存储在分布式文件系统DFS)中,或者已经存储在 Hadoop 相关软件上。

此外,MapReduce 是一种分布式编程模型,但它并不是唯一一种支持分布式的编程模型。描述其他编程模型可能会有所启发,例如 MPI 和批量同步并行BSP)。使用 R 等工具和若干机器学习技术处理大数据需要高配置的机器,但这并不是永久解决方案。因此,分布式处理是处理这些数据的关键。这种分布式计算可以通过 MapReduce 编程模型来实现。

MapReduce 是解决大数据问题的答案。从逻辑上讲,要处理数据,我们需要并行处理,这意味着需要大规模计算;这种处理方式可以通过将计算机集群进行聚集或提高单机配置来实现。使用计算机集群是处理大规模数据的理想方式。

在我们深入讨论并行处理中的 MapReduce 之前,我们将讨论 Google MapReduce 研究以及Jeffrey DeanSanjay Ghemawat在 2004 年撰写的白皮书。它们将 MapReduce 介绍为一种简化的大规模集群数据处理软件。MapReduce 实现运行在由普通硬件组成的大型集群上。这种数据处理平台使得程序员可以更容易地执行各种操作。系统负责处理输入数据、将数据分配到计算机网络中、并行处理这些数据,最后将输出结果合并成一个文件,供之后聚合。这对于成本控制非常有帮助,而且也是一种节省时间的系统,适用于在集群上处理大型数据集。此外,它能高效地利用计算机资源来处理大量数据进行分析。Google 已获得 MapReduce 的专利。

对于 MapReduce,程序员只需要将应用程序设计/迁移为两个阶段:Map 和 Reduce。他们只需要设计 Map 函数,用于处理键值对并生成一组中间的键值对,然后设计 Reduce 函数,用于合并所有的中间键。Map 和 Reduce 函数共同维护 MapReduce 的工作流。Reduce 函数将在 Map 输出可用后开始执行代码。

它们的执行顺序如下所示:

https://github.com/OpenDocCN/freelearn-ds-pt5-zh/raw/master/docs/bgdt-anal-r-hdp/img/3282OS_02_00.jpg

MapReduce 假设 Map 是独立的,并且会并行执行它们。MapReduce 算法的关键是,如果每个 Map 和 Reduce 都与网络中其他正在进行的 Map 和 Reduce 独立,那么操作将在不同的键和数据列表上并行运行。

分布式文件系统将数据的多个副本分布到不同的机器上。这提供了可靠性和容错能力。如果一台机器上的文件副本崩溃,另一台复制的数据源将提供相同的数据。

MapReduce 守护进程的主节点将负责 MapReduce 作业的所有职责,如作业的执行、Mappers、Reducers、Combiners 和 Partitioners 的调度、监控个别作业任务的成功与失败,最后完成批处理作业。

Apache Hadoop 通过在存储在 Hadoop 分布式文件系统上的数据附近运行 Hadoop MapReduce 作业,以并行方式处理分布式数据。

使用 MapReduce 的公司包括:

  • Amazon:这是一个在线电子商务和云服务提供商,专注于大数据分析

  • eBay:这是一个电子商务门户网站,用于根据描述查找商品

  • Google:这是一个网页搜索引擎,用于查找与特定主题相关的页面

  • LinkedIn:这是一个专业的社交网站,用于大数据存储和生成个性化推荐

  • Trovit:这是一个垂直搜索引擎,用于查找与给定描述匹配的工作

  • Twitter:这是一个社交网站,用于查找消息

除了这些,还有许多其他品牌正在使用 Hadoop 进行大数据分析。

引入 Hadoop MapReduce

基本上,MapReduce 模型可以用多种语言实现,但除了这些,Hadoop MapReduce 是一个流行的 Java 框架,便于编写应用程序。它以可靠和容错的方式在大型集群(成千上万的节点)上的商品硬件上并行处理大量数据(多 TB 数据集)。这个 MapReduce 范式分为两个阶段:Map 和 Reduce,主要处理数据的键值对。Map 和 Reduce 任务在集群中顺序运行,Map 阶段的输出成为 Reduce 阶段的输入。

MapReduce 中的所有数据输入元素都无法更新。如果映射任务的输入 (key, value) 对发生更改,将不会反映在输入文件中。Mapper 输出将通过管道传输到适当的 Reducer,并按键属性分组作为输入。这个顺序的数据处理将通过 Hadoop MapReduce 算法和 Hadoop 集群以并行方式执行。

MapReduce 程序将以列表格式呈现的输入数据集转换为同样以列表格式呈现的输出数据。这一逻辑列表转换过程通常在 Map 阶段和 Reduce 阶段重复两次。我们还可以通过固定 Mapper 和 Reducer 的数量来处理这些重复。在接下来的部分中,将根据旧的 MapReduce API 描述 MapReduce 概念。

列出 Hadoop MapReduce 实体

以下是负责在大数据上执行分析的 Hadoop 组件:

  • Client:这是用来初始化任务的。

  • JobTracker:这是用来监控任务的。

  • TaskTracker:这是执行任务的。

  • HDFS:这是用来存储输入和输出数据的。

理解 Hadoop MapReduce 场景

Hadoop MapReduce 数据处理的四个主要阶段如下:

  • 将数据加载到 HDFS 中

  • 执行 Map 阶段

  • 洗牌和排序

  • 执行 Reduce 阶段

将数据加载到 HDFS 中

输入数据集需要上传到 Hadoop 目录,以便 MapReduce 节点可以使用它。然后,Hadoop 分布式文件系统HDFS)将把输入数据集分割成数据块,并将它们存储到集群中的 DataNodes,同时确保为容错设置复制因子。所有的数据块将由 TaskTracker 以并行方式处理 Map 和 Reduce 任务。

此外,还有一些替代方法可以通过 Hadoop 组件将数据集获取到 HDFS 中:

  • Sqoop:这是一个开源工具,旨在高效地在 Apache Hadoop 和结构化关系型数据库之间传输大量数据。假设你的应用已经配置了 MySQL 数据库,并且你想用相同的数据进行数据分析,建议使用 Sqoop 将数据集导入到 HDFS。此外,数据分析过程完成后,输出可以导出到 MySQL 数据库中。

  • Flume:这是一个分布式、可靠且可用的服务,用于高效地收集、汇总和传输大量日志数据到 HDFS。Flume 能够从大多数源读取数据,例如日志文件、系统日志和 Unix 进程的标准输出。

使用前面的数据收集和移动框架,可以让 MapReduce 应用程序的数据传输过程变得非常简单,便于数据分析。

执行 Map 阶段

执行客户端应用程序启动 Hadoop MapReduce 进程。然后 Map 阶段复制作业资源(未解压的类文件)并将其存储到 HDFS,并请求 JobTracker 执行作业。JobTracker 初始化作业,检索输入,拆分信息,并为每个作业创建一个 Map 任务。

JobTracker 将调用 TaskTracker 运行分配的输入数据子集的 Map 任务。Map 任务将此输入拆分数据作为输入 (key, value) 对提供给 Mapper 方法,然后生成中间 (key, value) 对。对于每个输入 (key, value) 对至少会有一个输出。

https://github.com/OpenDocCN/freelearn-ds-pt5-zh/raw/master/docs/bgdt-anal-r-hdp/img/3282OS_02_01.jpg

映射输入列表的各个元素

生成的 (key, value) 对列表是这样生成的,即键属性将被多次重复使用。因此,对于在 MapReduce 中聚合值的 Reducer,它的键属性将被重新使用。就格式而言,Mapper 输出格式的值和 Reducer 输入的值必须相同。

在完成此 Map 操作后,TaskTracker 将在其缓冲存储和本地磁盘空间中保留结果(如果输出数据大小超过阈值)。

例如,假设我们有一个将输入文本转换为小写的 Map 函数。这将把输入字符串列表转换为小写字符串列表。

提示

键和值:在 MapReduce 中,每个值都有其被视为键的标识符。由 Mapper 接收的键值对依赖于作业配置文件中指定的输入数据类型。

分组和排序

要优化 MapReduce 程序,这个中间阶段非常重要。

一旦 Mapper 阶段的 Map 输出可用,此中间阶段将自动调用。在 Map 阶段完成后,所有发出的中间 (key, value) 对将由 Mapper 侧的分区器进行分区,只要分区器存在。分区器的输出将根据 Mapper 侧的键属性进行排序。排序操作的输出存储在 Mapper 节点 TaskTracker 上可用的缓冲内存中。

Combiner 通常就是 Reducer 本身。因此,通过压缩,它不是 Gzip 或类似的压缩,而是 Map 输出数据的 Reducer 节点。由 Combiner 返回的数据然后被分组并发送到减少节点。为了加速 Mapper 输出到 TaskTracker 的 Reducer 插槽的数据传输,需要使用 Combiner 函数压缩该输出。默认情况下,Mapper 输出将存储到缓冲内存中,如果输出大小大于阈值,则会存储到本地磁盘。这些输出数据可通过 超文本传输协议 (HTTP) 访问。

减少阶段的执行

一旦 Mapper 输出可用,Reducer 节点上的 TaskTracker 将检索可用的分区 Map 输出数据,这些数据将被分组并合并成一个大文件,然后分配给一个包含 Reducer 方法的进程。最后,在数据提供给 Reducer 方法之前,会对其进行排序。

Reducer 方法接收来自输入 (key, list (value)) 的输入值列表,并根据自定义逻辑对它们进行聚合,生成输出 (key, value) 对。

https://github.com/OpenDocCN/freelearn-ds-pt5-zh/raw/master/docs/bgdt-anal-r-hdp/img/3282OS_02_02.jpg

将输入值减少为一个聚合值作为输出

Reduce 阶段的 Reducer 方法的输出将根据 MapReduce 作业配置类指定的格式直接写入 HDFS。

理解 MapReduce 的局限性

让我们看看 Hadoop MapReduce 的一些局限性:

  • MapReduce 框架对于非简单的转换逻辑(例如实时流处理、图处理和消息传递)来说,众所周知很难使用。

  • 在分布式、未索引的数据上进行数据查询比在使用已索引数据创建的数据库中要低效。然而,如果为数据生成了索引,在数据删除或添加时需要维护该索引。

  • 我们无法将 Reduce 任务并行化到 Map 任务上以减少整体处理时间,因为 Reduce 任务只有在 Map 任务的输出可用时才能开始。(Reducer 的输入完全依赖于 Mapper 的输出。)此外,我们无法控制 Map 和 Reduce 任务执行的顺序。但有时,根据应用逻辑,我们可以在 Map 任务完成后,数据收集开始时,配置一个 Reduce 任务的慢启动。

  • 长时间运行的 Reduce 任务无法完成,原因是资源利用率低,可能是因为 Reduce 任务花费太多时间导致失败,或者没有其他 Reduce 插槽可供重新调度(这可以通过 YARN 来解决)。

理解 Hadoop 解决问题的能力

由于本书面向分析师,因此提供一些分析示例可能是相关的;例如,如果读者遇到与之前描述的类似问题,Hadoop 可能会有所帮助。Hadoop 不是解决所有大数据问题的万能方案;它只是当需要将大量数据分割成小块并分布到服务器上进行并行处理时,使用的一种不错的技术。这可以节省时间和在大数据集上执行分析的成本。

如果我们能够为问题设计 Map 和 Reduce 阶段,那么就可以使用 MapReduce 来解决它。通常,Hadoop 提供计算能力来处理不适合机器内存的数据。(R 用户在处理大数据时,通常会遇到以下错误消息:无法分配大小为 2.5 GB 的向量。)

理解 Hadoop 编程中使用的不同 Java 概念

有一些经典的 Java 概念,使得 Hadoop 更具互动性。它们如下:

  • 远程过程调用:这是一种进程间通信方式,允许计算机程序在另一个地址空间(通常是在共享网络上的另一台计算机)执行子程序或过程,而不需要程序员明确编写远程交互的详细代码。也就是说,程序员编写的代码基本相同,无论子程序是本地执行的还是远程执行的。

  • 序列化/反序列化:通过序列化,Java 虚拟机JVM)可以将对象的状态写入某个流中,这样我们就可以基本上读取所有成员并将其状态写入流、磁盘等。默认机制采用二进制格式,因此它比文本格式更加紧凑。通过这种方式,计算机可以通过网络发送数据。反序列化则相反,用于接收网络中的数据对象。

  • Java 泛型:这使得类型或方法能够在不同类型的对象上操作,同时提供编译时类型安全,使得 Java 成为一种完全静态类型的语言。

  • Java 集合:该框架是一组用于处理各种类型数据集合的类和接口,能够使用单一的 Java 对象进行操作。

  • Java 并发:该设计用于支持并发编程,所有执行都发生在线程的上下文中。它主要用于将计算过程作为一组线程实现,在单个操作系统进程中执行。

  • 普通旧 Java 对象POJO):这些实际上是普通的 JavaBeans。POJO 被临时用来设置和获取数据对象的值。

理解 Hadoop MapReduce 基本原理

为了正确理解 Hadoop MapReduce 的基本原理,我们将:

  • 理解 MapReduce 对象

  • 学习如何决定 MapReduce 中的 Map 数量

  • 学习如何决定 MapReduce 中的 Reduce 数量

  • 理解 MapReduce 数据流

  • 更深入地了解 Hadoop MapReduce 的术语

理解 MapReduce 对象

正如我们所知,Hadoop 中的 MapReduce 操作主要由三个对象执行:Mapper、Reducer 和 Driver。

  • Mapper:这是为 MapReduce 的 Map 阶段设计的,它通过携带输入文件并将其拆分成若干块来启动 MapReduce 操作。对于每一块,它会生成一个键值对作为输出值。

  • Reducer:这是为 MapReduce 作业的 Reduce 阶段设计的;它接受来自 Mapper 输出的按键分组的数据,通过聚合逻辑进行处理,并输出该组数据的 (key, value) 键值对。

  • 驱动程序:这是驱动 MapReduce 过程的主文件。它在从客户端应用程序获取请求和参数后启动 MapReduce 任务的执行。驱动程序负责构建作业的配置并将其提交到 Hadoop 集群。驱动程序代码包含接受命令行参数的main()方法。此程序将接受 Hadoop MapReduce 作业的输入和输出目录。驱动程序是定义作业配置细节的主要文件,如作业名称、作业输入格式、作业输出格式以及 Mapper、Combiner、Partitioner 和 Reducer 类。通过调用驱动程序类的main()函数来初始化 MapReduce。

并非每个问题都可以用单个 Map 和单个 Reduce 程序解决,但更少的问题无法用单个 Map 和单个 Reduce 任务解决。有时,还需要设计具有多个 Map 和 Reduce 任务的 MapReduce 作业。当需要在单个作业中执行数据操作(如数据提取、数据清洗和数据合并)时,可以设计这种类型的作业。通过为单个作业编写多个 Mapper 和 Reducer 任务,可以解决许多问题。在多个 Map 和 Reduce 任务的情况下,将依次调用 Map1 后跟 Reduce1,Map2 后跟 Reduce2 等 MapReduce 步骤。

当我们需要编写具有多个 Map 和 Reduce 任务的 MapReduce 作业时,我们必须编写多个 MapReduce 应用程序驱动程序来依次运行它们。

在提交 MapReduce 作业时,我们可以提供一定数量的 Map 任务,根据 Mapper 输入和 Hadoop 集群容量创建一定数量的 Reducers。同时,注意设置 Mappers 和 Reducers 的数量并非强制要求。

决定 MapReduce 中的 Maps 数量

Map 数量通常由输入数据的大小和由 HDFS 文件/数据划分计算的数据块大小定义。因此,如果我们有一个 5 TB 的 HDFS 数据文件和 128 MB 的块大小,文件中将有 40,960 个 Map。但有时,由于推测执行,创建的 Mapper 数量将超过此计数。当输入是文件时,这是真实的,尽管它完全取决于InputFormat类。

在 Hadoop MapReduce 处理中,当分配的 Mapper 或 Reducer 需要较长时间完成时,作业结果会有延迟。如果要避免这种情况,在 Hadoop 中的推测执行可以在不同节点上运行同一 Map 或 Reduce 任务的多个副本,并可以使用首次完成节点的结果。通过 Hadoop API 的setNumMapTasks(int)方法,我们可以了解 Mapper 的数量。

决定 MapReduce 中 Reducers 的数量

Reducer 的数量是根据 Mapper 的输入创建的。然而,如果你在 MapReduce 中硬编码 Reducer 的数量,集群中有多少节点也无关紧要。它将按照配置中指定的方式执行。

此外,我们可以在运行时通过命令行 -D mapred.reduce.tasks 设置 Reducer 的数量,并指定需要的数量。程序上也可以通过 conf.setNumReduceTasks(int) 设置。

理解 MapReduce 数据流

现在我们已经了解了构成基本 MapReduce 作业所需的组件,我们将从更高层次区分每个部分如何协同工作。从下面的图示中,我们将理解 Hadoop 集群中多个节点的 MapReduce 数据流:

https://github.com/OpenDocCN/freelearn-ds-pt5-zh/raw/master/docs/bgdt-anal-r-hdp/img/3282OS_02_03.jpg

MapReduce 数据流

Hadoop MapReduce 可用的两种 API 是:新版本(Hadoop 1.x 和 2.x)和旧版本 Hadoop(0.20)。YARN 是下一代 Hadoop MapReduce,是为 Hadoop 资源管理发布的新 Apache Hadoop 子项目。

Hadoop 数据处理包括多个任务,帮助从输入数据集中获得最终输出。这些任务如下:

  1. 在 HDFS 中预加载数据。

  2. 通过调用 Driver 来运行 MapReduce。

  3. 由 Mappers 读取输入数据,这会导致数据的拆分,执行 Mapper 自定义逻辑,并生成中间的键值对。

  4. 执行 Combiner 和 shuffle 阶段,以优化整体 Hadoop MapReduce 过程。

  5. 对中间键值对进行排序,并将其提供给 Reduce 阶段。然后执行 Reduce 阶段。Reducers 根据 Reducer 逻辑聚合这些分区的键值对。

  6. 最终的输出数据存储在 HDFS 中。

在这里,可以为以下几种数据操作定义 Map 和 Reduce 任务:

  • 数据提取

  • 数据加载

  • 数据分割

  • 数据清洗

  • 数据转化

  • 数据集成

我们将在本章的下一部分更详细地探讨 MapReduce 任务。

更详细地了解 Hadoop MapReduce 术语

在本节中,我们将进一步了解 Hadoop MapReduce 数据流,并介绍多个 MapReduce 术语及其 Java 类细节。在前面一节的 MapReduce 数据流图中,多个节点通过网络连接进行分布式处理,基于 Hadoop 设置。Map 和 Reduce 阶段的随之属性在获取最终输出时起着重要作用。

Map 阶段的属性如下:

  • InputFiles 术语指的是已经创建/提取并存储在 HDFS 中,供业务分析使用的输入原始数据集。这些输入文件非常大,并且有多种类型。

  • InputFormat 是一个 Java 类,用于通过获取每行的偏移量和内容来处理输入文件。它定义了如何拆分和读取输入数据文件。我们可以设置多个输入类型,例如 TextInputFormatKeyValueInputFormatSequenceFileInputFormat,这些输入格式与 Map 和 Reduce 阶段相关。

  • InputSplits 类用于设置数据分割的大小。

  • RecordReader 是一个 Java 类,提供多个方法,通过迭代数据分割来检索键和值。它还包括其他方法,用于获取当前进度的状态。

  • 为 Map 阶段创建 Mapper 实例。Mapper 类接受输入的 (key, value) 对(由 RecordReader 生成),并通过在 Map() 方法中执行用户定义的代码生成一个中间的 (key, value) 对。Map() 方法主要接受两个输入参数:key 和 value;其余的参数是 OutputCollectorReporter。它们将提供中间的键值对,以供作业的 Reduce 阶段使用。Reporter 会定期向 JobTracker 提供当前作业的状态。JobTracker 会在作业结束时汇总这些状态,供后续检索。

Reduce 阶段的属性如下:

  • 在完成 Map 阶段后,生成的中间 (key, value) 对会根据 hash 函数中的键属性相似性进行分区。因此,每个 Map 任务可能会将 (key, value) 对发射到不同的分区;对于相同的键,所有值总是一起被 Reducer 处理,而不管它们来自哪个 Mapper。这个分区和洗牌操作将在 Map 阶段完成后由 MapReduce 作业自动执行,无需单独调用。此外,我们可以根据 MapReduce 作业的要求显式覆盖它们的逻辑代码。

  • 在完成分区和洗牌操作并在初始化 Reduce 任务之前,Hadoop MapReduce 作业会根据键属性值对中间 (key, value) 对进行排序。

  • 为 Reduce 阶段创建 Reduce 实例。它是一个用户提供的代码段,用于执行 Reduce 任务。Reducer 类的 Reduce() 方法主要接受两个参数,以及 OutputCollectorReporter,与 Map() 函数相同。它们是 OutputCollectorReporter 对象。Map 和 Reduce 中的 OutputCollector 功能相同,但在 Reduce 阶段,OutputCollector 将输出提供给下一个 Map 阶段(在多个 Map 和 Reduce 作业组合的情况下),或者根据需求将其报告为作业的最终输出。此外,Reporter 会定期向 JobTracker 报告当前任务的状态。

  • 最后,在OutputFormat中,生成的输出(键,值)对被提供给OutputCollector参数,然后写入OutputFiles,该过程由OutputFormat控制。它控制OutputFiles格式的设置,格式的选择由 MapReduce Driver 定义。格式将从TextOutputFormatSequenceFileOutputFileFormatNullOutputFormat中选择。

  • RecordWriterOutputFormat使用的工厂,用于以适当的格式写入输出数据。

  • 输出文件是RecordWriter在 MapReduce 作业完成后写入 HDFS 的输出数据。

为了高效地运行此 MapReduce 作业,我们需要了解一些 Hadoop Shell 命令以执行管理任务。请参考下表:

Shell 命令用法和代码示例

|

cat

| 将源路径复制到stdout

Hadoop fs -cat URI [URI …]

|

|

chmod

| 更改文件的权限:

Hadoop fs -chmod [-R] <MODE[,MODE]... &#124; OCTALMODE> URI [URI …]

|

|

copyFromLocal

| 将文件从本地存储复制到 HDFS:

Hadoop fs –copyFromLocal<localsrc> URI

|

|

copyToLocal

| 将文件从 HDFS 复制到本地存储:

Hadoop fs -copyToLocal [-ignorecrc] [-crc] URI <localdst>

|

|

cp

| 将文件从源路径复制到目标路径(HDFS):

Hadoop fs -cp URI [URI …] <dest>

|

|

du

| 显示文件的总长度:

Hadoop fs -du URI [URI …]

|

|

dus

| 显示文件长度的汇总信息:

Hadoop fs -dus<args>

|

|

get

| 将文件复制到本地文件系统:

Hadoop fs -get [-ignorecrc] [-crc] <src><localdst>

|

|

ls

| 在 HDFS 中列出当前目录的所有文件:

Hadoop fs –ls<args>

|

|

mkdir

| 在 HDFS 中创建目录:

Hadoop fs –mkdir<paths>

|

|

lv

| 将文件从源路径移动到目标路径:

Hadoop fs -mv URI [URI …] <dest>

|

|

rmr

| 从当前目录中删除文件:

Hadoop fs -rmr URI [URI …]

|

|

setrep

| 更改文件的副本因子:

Hadoop fs -setrep [-R] <path>

|

|

tail

| 将文件的最后一个千字节显示到stdout

Hadoop fs -tail [-f] URI

|

编写一个 Hadoop MapReduce 示例

现在,我们将通过学习一个非常常见且简单的单词计数示例来继续深入了解 MapReduce。此示例的目标是计算每个单词在提供的文档中出现的次数。这些文档可以视为 MapReduce 的输入文件。

在此示例中,我们已经有了一组文本文件——我们想要识别文件中所有唯一单词的出现频率。我们将通过设计 Hadoop MapReduce 阶段来实现这一点。

在本节中,我们将更多地了解使用 Hadoop MapReduce 的旧 API 进行编程。在这里,我们假设读者已经按照第一章中的说明设置好了 Hadoop 环境,准备使用 R 和 Hadoop。另外,请记住,我们在此不会使用 R 来计数单词;这里只使用 Hadoop。

基本上,Hadoop MapReduce 有三个主要对象:Mapper、Reducer 和 Driver。它们可以通过三个 Java 类进行开发;分别是Map类、Reduce类和Driver类,其中Map类表示 Map 阶段,Reducer类表示 Reduce 阶段,Driver类表示包含main()方法以初始化 Hadoop MapReduce 程序的类。

在前一节的 Hadoop MapReduce 基础中,我们已经讨论了什么是 Mapper、Reducer 和 Driver。现在,我们将学习如何在 Java 中定义它们并进行编程。在接下来的章节中,我们将学习如何将 R 和 Hadoop 结合使用做更多的事情。

提示

有许多语言和框架用于构建 MapReduce,但每种语言或框架都有其独特的优势。有多个因素可以通过修改来提高 MapReduce 的延迟。请参考 Cloudera 的文章 10 MapReduce Tips blog.cloudera.com/blog/2009/05/10-mapreduce-tips/

为了简化 MapReduce 开发,使用Eclipse并配置Maven,该工具支持旧版 MapReduce API。

了解运行 MapReduce 作业的步骤

让我们来看一下运行 MapReduce 作业的步骤:

  1. 在准备 Java 类的初始步骤中,我们需要您根据我们的业务问题定义开发一个 Hadoop MapReduce 程序。在这个示例中,我们考虑了一个词频统计问题。因此,我们开发了三个用于 MapReduce 程序的 Java 类,它们分别是 Map.javaReduce.javaWordCount.java,用于计算提供的文本文件中单词的频率。

    • Map.java:这是用于词频统计 Mapper 的 Map 类。

      // Defining package of the class
      package com.PACKT.chapter1;
      
      // Importing java libraries 
      import java.io.*;
      importjava.util.*;
      import org.apache.hadoop.io.*;
      import org.apache.hadoop.mapred.*;
      
      // Defining the Map class
      public class Map extends MapReduceBase implements
               Mapper<LongWritable, 
                      Text, 
                      Text, 
                      IntWritable>{
      
      //Defining the map method – for processing the data with // problem specific logic
      public void map(LongWritable key,
                      Text value,
                      OutputCollector<Text,
                      IntWritable> output,
                      Reporter reporter) 
                      throws IOException {
      
      // For breaking the string to tokens and convert them to lowercase
      StringTokenizer st = new StringTokenizer(value.toString().toLowerCase());
      
      // For every string tokens
      while(st.hasMoreTokens()) {
      
      // Emitting the (key,value) pair with value 1.
      output.collect(new Text(st.nextToken()), 
                     new IntWritable(1));
              }
      
          }
      
      }
      
    • Reduce.java:这是用于词频统计 Reducer 的 Reduce 类。

      // Defining package of the class
      package com.PACKT.chapter1;
      
      // Importing java libraries
      import java.io.*;
      importjava.util.*;
      import org.apache.hadoop.io.*;
      importorg.apache.hadoop.mapred.*;
      
      // Defining the Reduce class 
      public class Reduce extends MapReduceBase implements
                Reducer<Text,
                        IntWritable,
                        Text,
                        IntWritable> {
      
      // Defining the reduce method for aggregating the //generated output of Map phase
      public void reduce(Text key,
                         Iterator<IntWritable> values,
                         OutputCollector<Text,IntWritable>
                         output, 
                         Reporter reporter) throws IOException {
      
      // Setting initial counter value as 0
      int count = 0;
      
      // For every element with similar key attribute, increment its counter value by adding 1.
      while(values.hasNext()) {
      count += values.next().get();
              }
      
      // Emitting the (key,value) pair
      output.collect(key, new IntWritable(count));
          }
      }
      
    • WordCount.java:这是 Hadoop MapReduce Driver 主文件中的 Driver 任务。

      //Defining package of the class
      package com.PACKT.chapter1;
      
      // Importing java libraries
      import java.io.*;
      importorg.apache.hadoop.fs.*;
      import org.apache.hadoop.io.*;
      importorg.apache.hadoop.mapred.*;
      importorg.apache.hadoop.util.*;
      importorg.apache.hadoop.conf.*;
      
      //Defining wordcount class for job configuration 
        // information
      public class WordCount extends Configured implements Tool{
      
      publicint run(String[] args) throws IOException{
      JobConfconf = new JobConf(WordCount.class);
      conf.setJobName("wordcount");
      
      //For defining the output key format
      conf.setOutputKeyClass(Text.class);
      
      //For defining the output value format
      conf.setOutputValueClass(IntWritable.class);
      
      // For defining the Mapper class implementation
      conf.setMapperClass(Map.class);
      
      // For defining the Reducer class implementation
      conf.setReducerClass(Reduce.class);
      
      // For defining the type of input format 
      conf.setInputFormat(TextInputFormat.class);
      
      // For defining the type of output format
      conf.setOutputFormat(TextOutputFormat.class);
      
      // For defining the command line argument sequence for // input dataset path
      FileInputFormat.setInputPaths(conf, new Path(args[0]));
      
      // For defining the command line argument sequence for // output dataset path
      FileOutputFormat.setOutputPath(conf, new Path(args[1]));
      
      // For submitting the configuration object
      JobClient.runJob(conf);
      
      return 0;
          }
      
      // Defining the main() method to start the execution of // the MapReduce program
      public static void main(String[] args) throws Exception {
        intexitCode = ToolRunner.run(new WordCount(), args);
        System.exit(exitCode); } }
      
  2. 编译 Java 类。

    // create a folder for storing the compiled classes
    hduser@ubuntu:~/Desktop/PacktPub$ mkdir classes
    
    // compile the java class files with classpath
    hduser@ubuntu:~/Desktop/PacktPub$ javac -classpath /usr/local/hadoop/hadoop-core-1.1.0.jar:/usr/local/hadoop/lib/commons-cli-1.2.jar -d classes *.java
    
    
  3. 从编译后的类创建一个.jar文件。

    hduser@ubuntu:~/Desktop/PacktPub$ cd classes/
    
    // create jar of developed java classes
    hduser@ubuntu:~/Desktop/PacktPub/classes$ jar -cvf wordcount.jar com
    
    
  4. 启动 Hadoop 守护进程。

    // Go to Hadoop home Directory
    hduser@ubuntu:~$ cd $HADOOP_HOME
    
    // Start Hadoop Cluster
    hduser@ubuntu:/usr/local/hadoop$ bin/start-all.sh
    
    
  5. 检查所有正在运行的守护进程。

    // Ensure all daemons are running properly 
    hduser@ubuntu:/usr/local/hadoop$ jps
    
    
  6. 创建 HDFS 目录 /wordcount/input/

    // Create Hadoop directory for storing the input dataset
    hduser@ubuntu:/usr/local/hadoop$ bin/Hadoop fs -mkdir /wordcount/input
    
    
  7. 提取用于词频统计示例的输入数据集。由于我们需要有文本文件来供词频统计示例处理,因此我们将通过将 Hadoop 发行版中提供的文本文件(CHANGES.txtLICENSE.txtNOTICE.txtREADME.txt)复制到 Hadoop 目录来使用它们。我们也可以在这个 MapReduce 算法中使用来自互联网的其他文本数据集,而不是使用现成的文本文件。我们也可以从互联网上提取数据进行处理,但在这里我们使用的是现成的输入文件。

  8. 将所有文本文件复制到 HDFS。

    // To copying the text files from machine's local
     // directory in to Hadoop directory
    
    hduser@ubuntu:/usr/local/hadoop$ bin/hadoopfs -copyFromLocal $HADOOP_HOME/*.txt /wordcount/input/
    
    
  9. 使用以下命令运行 Hadoop MapReduce 作业:

    // Command for running the Hadoop job by specifying jar, main class, input directory and output directory.
    
    hduser@ubuntu:/usr/local/hadoop$ bin/hadoop jar wordcount.jar com.PACKT.chapter1.WordCount /wordcount/input/ /wordcount/output/
    
    
  10. 这就是最终输出的样子。

    // To read the generated output from HDFS directory
    
    hduser@ubuntu:/usr/local/hadoop$ bin/hadoopfs -cat /wordcount/output/part-00000
    
    

    提示

    在 MapReduce 阶段,您需要监控作业和节点。使用以下方法在网页浏览器中监控 MapReduce 作业:

    • localhost:50070:NameNode Web 界面(用于 HDFS)

    • localhost:50030:JobTracker Web 界面(用于 MapReduce 层)

    • localhost:50060:TaskTracker Web 界面(用于 MapReduce 层)

学习如何监控和调试 Hadoop MapReduce 作业

在本节中,我们将学习如何在没有命令的情况下监控和调试 Hadoop MapReduce 作业。

这是使用 Hadoop MapReduce 管理 UI 的最简单方式之一。我们可以通过浏览器访问 http://localhost:50030(JobTracker 守护进程的 web UI)。这将显示 Hadoop MapReduce 作业的日志信息,界面如下所示:

https://github.com/OpenDocCN/freelearn-ds-pt5-zh/raw/master/docs/bgdt-anal-r-hdp/img/3282OS_02_04.jpg

Map/Reduce 管理

在这里,我们可以查看正在运行的作业的信息和状态,作业的 Map 和 Reduce 任务状态,以及过去已完成的作业和失败的作业(包含失败的 Map 和 Reduce 任务)。此外,我们还可以通过点击失败作业中失败的 Map 或 Reduce 任务的超链接来调试 MapReduce 作业。这样会在作业运行时,在标准输出上显示错误信息。

浏览 HDFS 数据

在这一部分中,我们将看到如何在不运行任何 Bash 命令的情况下浏览 HDFS 目录。NameNode 守护进程的 web UI 提供了这样的功能。我们只需要在浏览器中访问 http://localhost:50070 即可。

https://github.com/OpenDocCN/freelearn-ds-pt5-zh/raw/master/docs/bgdt-anal-r-hdp/img/3282OS_02_05.jpg

NameNode 管理

这个 UI 使我们能够获取集群摘要(内存状态)、NameNode 日志以及集群中活跃和死节点的信息。此外,它还允许我们浏览为 Hadoop MapReduce 作业存储输入和输出数据的 Hadoop 目录。

理解几种可能的 MapReduce 定义,以解决商业问题

到目前为止,我们已经了解了什么是 MapReduce 以及如何编写 MapReduce 代码。接下来,我们将查看一些常见的 MapReduce 问题定义,这些问题定义通常用于商业分析。任何了解 MapReduce 和 Hadoop 的读者,都会通过修改用于单词计数的 MapReduce 示例,轻松编写代码并解决这些问题定义。主要的变化将在数据解析和数据操作逻辑上。主要的工作将集中在数据收集、数据清理和数据存储上。

  • 服务器 web 日志处理:通过这个 MapReduce 定义,我们可以进行 web 日志分析。web 服务器的日志提供了关于 web 请求的信息,比如请求的页面 URL、日期、时间和协议。从这些信息中,我们可以从 web 服务器日志中识别出我们网站的高峰负载时段,并根据网站的流量调整 web 服务器的配置。因此,识别出夜间没有流量的时间段将帮助我们通过缩减服务器规模来节省费用。此外,还有许多商业案例可以通过这种 web 日志服务器分析来解决。

  • 网站分析与网站统计:网站统计能够提供关于访客元数据的更详细信息,例如来源、广告活动、访客类型、访客位置、搜索关键词、请求的页面 URL、浏览器以及在页面上花费的总时间。Google Analytics 是其中一个流行且免费的服务提供商,通过分析所有这些信息,我们可以了解访客在网站上的行为。通过描述性分析,我们可以基于访客对页面的依赖性,识别网站页面或其他网页属性的重要性。对于电子商务网站,我们可以根据访客的访问总数、页面浏览量以及在页面上花费的时间来识别热门产品。此外,还可以在网站数据上实施预测分析,以预测业务趋势。

  • 搜索引擎:假设我们有大量的文档,并希望在这些文档中搜索特定的关键词,使用 Hadoop MapReduce 的倒排索引将帮助我们找到关键词,从而为大数据构建一个搜索引擎。

  • 股市分析:假设我们收集了长期的股市数据(大数据),现在希望识别其中的模式并预测下一时间段的走势。这需要对所有历史数据集进行训练。然后,我们可以使用多个机器学习库与 Hadoop MapReduce 计算股市在特定时间段内的变化频率。

此外,还有许多可以应用 MapReduce 的场景,帮助降低企业成本。

学习在 R 中编写 Hadoop MapReduce 的不同方法

我们知道,Hadoop 大数据处理与 MapReduce 对于统计学家、网站分析师和产品经理来说非常重要,尤其是对于那些曾经使用 R 工具进行分析的人,因为将分析迁移到 MapReduce 和 Hadoop 上需要额外的编程知识。同时,我们也知道 R 是一个持续增长受欢迎的工具;有许多开发中的包/库可以与 R 集成。因此,要开发一个结合 R 的日志和 Hadoop 的计算能力的 MapReduce 算法或程序,我们需要 R 和 Hadoop 之间的中间件。RHadoop、RHIPE 和 Hadoop streaming 是帮助在 R 中开发和执行 Hadoop MapReduce 的中间件。在最后一部分中,我们将介绍 RHadoop、RHIPE,并介绍 Hadoop streaming,从后面的章节开始,我们将仅使用这些包来开发 MapReduce。

学习 RHadoop

RHadoop 是一个出色的开源软件框架,用于通过 R 函数在 Hadoop 平台上执行数据分析。RHadoop 由Revolution Analytics开发,是基于开源 R 项目进行统计计算的领先商业软件和服务提供商。RHadoop 项目有三个不同的 R 包:rhdfsrmrrhbase。所有这些包都在 Cloudera 的 Hadoop 发行版 CDH3、CDH4 和 R 2.15.0 上实现和测试。此外,这些包还与 Revolution Analytics 的 R 版本 4.3、5.0 和 6.0 发行版进行了测试。

这三个不同的 R 包是基于 Hadoop 的两个主要特性 HDFS 和 MapReduce 设计的:

  • rhdfs:这是一个为 R 提供所有 Hadoop HDFS 访问的 R 包。所有分布式文件都可以通过 R 函数进行管理。

  • rmr:这是一个为 R 提供 Hadoop MapReduce 接口的 R 包。借助这个包,Mapper 和 Reducer 可以轻松开发。

  • rhbase:这是一个用于通过 R 处理 HBase 分布式数据库数据的 R 包。

学习 RHIPE

R 和 Hadoop 集成编程环境RHIPE)是一个自由和开源的项目。RHIPE 广泛用于通过D&R分析执行大数据分析。D&R 分析用于将庞大的数据划分、在分布式网络上并行处理以生成中间输出,最后将所有这些中间输出重新组合成一个集合。RHIPE 旨在通过 R 在 Hadoop 平台上进行复杂大数据的 D&R 分析。RHIPE 由Saptarshi Joy Guha(Mozilla 公司数据分析师)及其团队开发,作为她在普渡大学统计系的博士论文的一部分。

学习 Hadoop streaming

Hadoop streaming 是 Hadoop 发行版中提供的一个工具。该工具允许你使用任何可执行文件或脚本作为 Mapper 和/或 Reducer 创建并运行 MapReduce 作业。它支持 R、Python、Ruby、Bash、Perl 等语言。我们将使用 R 语言和 bash 脚本。

另外,还有一个名为HadoopStreaming的 R 包,它是为在 Hadoop 集群上通过 R 脚本执行数据分析而开发的,这是一个 R 与 Hadoop streaming 的接口。此外,它还允许在没有 Hadoop 的情况下运行 MapReduce 任务。该包由David Rosenberg(SenseNetworks 的首席科学家)开发,他在机器学习和统计建模方面具有专业知识。

总结

在本章中,我们已经了解了 Hadoop MapReduce 是什么,以及如何开发和运行它。在下一章中,我们将学习如何安装 RHIPE 和 RHadoop,并通过示例开发 MapReduce 及其可用的功能库。

第三章. R 与 Hadoop 的集成

从前两章我们获取了关于如何安装 R 与 Hadoop 工具的基本信息。同时,我们也了解了 Hadoop 的关键特性以及为什么它们与 R 集成,用于解决大数据业务问题。因此,借助 R 与 Hadoop 的集成,我们可以将数据分析提升到大数据分析的层面。这两个中间件仍在不断改进,以便彼此兼容使用。

在第二章,编写 Hadoop MapReduce 程序中,我们学习了如何在 Hadoop 中编写 MapReduce 程序。在本章中,我们将学习如何在 R 中开发在 Hadoop 集群上运行的 MapReduce 程序。本章将提供关于 R 和 Hadoop 以及 RHIPE 和 RHadoop 的开发教程。安装 R 和 Hadoop 后,我们将看到如何通过简单步骤将 R 与 Hadoop 进行集成。

在我们开始安装之前,先来看看 R 与 Hadoop 集成在组织中的优势。由于统计学家和数据分析师常常使用 R 工具进行数据探索和数据分析,Hadoop 集成为处理大规模数据提供了极大的便利。同样,使用 Hadoop 工具(如系统)来组织数据仓库的数据工程师,可以通过与 R 工具的集成,执行逻辑分析操作,从而获得可操作的有价值的洞见。

因此,这些基于数据的工具和技术的集成可以构建一个强大且可扩展的系统,具备两者的特性。

https://github.com/OpenDocCN/freelearn-ds-pt5-zh/raw/master/docs/bgdt-anal-r-hdp/img/3282OS_03_01.jpg

将 R 与 Hadoop 连接的三种方式如下:

  • RHIPE

  • RHadoop

  • Hadoop 流式处理

在本章中,我们将学习使用 RHIPE 和 RHadoop 进行集成与分析。Hadoop 流式处理将在第四章,使用 Hadoop 流式处理与 R中讲解。

介绍 RHIPE

RHIPE代表R 和 Hadoop 集成编程环境。正如在www.datadr.org/上所提到的,它在希腊语中意为“瞬间”,是 R 与 Hadoop 的结合体。它最初由Saptarshi Guha为其在普渡大学统计系的博士论文于 2012 年开发。现在由普渡大学统计系团队及其他活跃的 Google 讨论组进行维护。

RHIPE 包使用分割与重组合技术对大数据进行数据分析。在此技术中,数据被划分为子集,针对这些子集执行特定的 R 分析操作,最后将输出结果合并。RHIPE 主要旨在实现以下两个目标:

  • 让你能够对大数据和小数据进行深入分析。

  • 允许用户使用较低级语言在 R 中执行分析操作。RHIPE 设计有多个函数,可帮助在简单的 R 控制台中执行 Hadoop 分布式文件系统HDFS)以及 MapReduce 操作。

RHIPE 是与 HDFS 和 MapReduce 操作相比较的较低级接口。使用最新支持的 RHIPE 版本 0.73.1,文件名为 Rhipe_0.73.1-2.tar.gz

安装 RHIPE

由于 RHIPE 是 R 和 Hadoop 的连接器,我们需要按照以下顺序在我们的机器或集群中安装 Hadoop 和 R:

  1. 安装 Hadoop。

  2. 安装 R。

  3. 安装协议缓冲区。

  4. 设置环境变量。

  5. 安装 rJava。

  6. 安装 RHIPE。

让我们开始安装。

安装 Hadoop

由于我们在这里要将 R 和 Hadoop 与 RHIPE 包库集成,因此需要在我们的机器上安装 Hadoop。这将是一个单节点或多节点安装,具体取决于要分析的数据大小。

由于我们已经学会了如何在 Ubuntu 上安装 Hadoop,我们在此不再重复该过程。如果您尚未安装,请参阅 第一章,准备使用 R 和 Hadoop,以获取指导。

安装 R

如果我们使用多节点 Hadoop 架构,则有多个 TaskTracker 节点用于执行 MapReduce 作业。因此,我们需要在所有这些 TaskTracker 节点上安装 R。这些 TaskTracker 节点将根据键值对的考虑,使用开发的映射和减少逻辑启动数据子集的过程。

安装协议缓冲区

协议缓冲区只需将数据序列化,使其平台无关、中立和健壮(主要用于结构化数据)。Google 使用相同的协议进行数据交换。RHIPE 依赖于协议缓冲区 2.4.1 以进行网络上的数据序列化。

可以使用以下命令安装:

## For downloading the protocol buffer 2.4.1
wget http://protobuf.googlecode.com/files/protobuf-2.4.1.tar.gz

## To extracting the protocol buffer
tar -xzf protobuf-2.4.1.tar.gz

## To get in to the extracted protocol buffer directory
cd protobuf-2.4.1

## For making install the protocol buffer
./configure # --prefix=...
make
make install

环境变量

为了使 RHIPE 能够正确编译和工作,最好确保以下环境变量设置正确:

为了配置 Hadoop 库,我们需要将两个变量 PKG_CONFIG_PATHLD_LIBRARY_PATH 设置到 hduser(Hadoop 用户)的 ~./bashrc 文件中,以便在用户登录系统时自动设置。

这里,PKG_CONFIG_PATH 是一个环境变量,保存了系统中安装库的 pkg-config 脚本路径,而 LD_LIBRARY_PATH 是一个环境变量,保存了本地共享库的路径。

export PKG_CONFIG_PATH = /usr/local/lib
export LD_LIBRARY_PATH = /usr/local/lib

您还可以从 R 控制台设置所有这些变量,如下所示:

Sys.setenv(HADOOP_HOME="/usr/local/hadoop/")
Sys.setenv(HADOOP_BIN="/usr/local/hadoop/bin")
Sys.setenv(HADOOP_CONF_DIR="/usr/local/hadoop/conf")

其中 HADOOP_HOME 用于指定 Hadoop 目录的位置,HADOOP_BIN 用于指定 Hadoop 二进制文件的位置,HADOOP_CONF_DIR 用于指定 Hadoop 配置文件的位置。

设置变量是临时的,并且在特定的 R 会话期间有效。如果我们希望在每次 R 会话初始化时自动初始化这些变量,使其永久有效,我们需要将这些变量设置到 /etc/R/Renviron 文件中,就像在特定用户配置文件的 .bashrc 中设置环境变量一样。

rJava 包安装

由于 RHIPE 是一个 Java 包,它充当 R 和 Hadoop 之间的 Java 桥梁。RHIPE 将输入数据序列化为 Java 类型,这些数据需要在集群上序列化。它需要一个低级的 Java 接口,而这一接口由 rJava 提供。因此,我们将安装 rJava 以启用 RHIPE 的功能。

## For installing the rJava Package will be used for calling java libraries from R.
install.packages("rJava")

安装 RHIPE

现在,是时候从 RHIPE 的软件库安装 RHIPE 包了。

## Downloading RHIPE package from RHIPE repository
Wget http://ml.stat.purdue.edu/rhipebin/Rhipe_0.73.1-2.tar.gz

## Installing the RHIPE package in R via CMD command
R CMD INSTALL Rhipe_0.73.1.tar.gz

现在,我们已准备好一个 RHIPE 系统,可以使用 R 和 Hadoop 执行数据分析。

理解 RHIPE 的架构

让我们理解 RHIPE 库包的工作原理,RHIPE 被开发出来用于将 R 和 Hadoop 集成,以进行高效的大数据分析。

https://github.com/OpenDocCN/freelearn-ds-pt5-zh/raw/master/docs/bgdt-anal-r-hdp/img/3282OS_03_02.jpg

RHIPE 的组件

有许多 Hadoop 组件将用于与 R 和 Hadoop 的数据分析操作。

RHIPE 的组件如下:

  • RClient:RClient 是一个 R 应用程序,它调用 JobTracker 来执行作业,并指示多个 MapReduce 作业资源,如 Mapper、Reducer、输入格式、输出格式、输入文件、输出文件以及其他能处理 MapReduce 作业的参数。

  • JobTracker:JobTracker 是 Hadoop MapReduce 操作的主节点,负责初始化并监控 Hadoop 集群上的 MapReduce 作业。

  • TaskTracker:TaskTracker 是 Hadoop 集群中的一个从节点,负责根据 JobTracker 的指令执行 MapReduce 作业,获取输入数据块,并在其上运行 R 特定的 MapperReducer。最终,输出将被写入 HDFS 目录。

  • HDFS:HDFS 是一个分布式文件系统,部署在 Hadoop 集群上,包含多个数据节点。它为各种数据操作提供数据服务。

理解 RHIPE 示例

在本节中,我们将创建两个 RHIPE MapReduce 示例。这两个示例通过 RHIPE 包中的基本 Hadoop MapReduce 作业功能来定义。

RHIPE 示例程序(仅 Map 阶段)

MapReduce 问题定义:这个 MapReduce 示例程序的目标是通过在 Hadoop 环境中使用 minmax 函数对数值数据进行测试,以验证 RHIPE 的安装。由于这是一个示例程序,我们只包含了 Map 阶段,并将其输出存储在 HDFS 目录中。

要开始使用 RHIPE 开发,我们需要通过加载库并调用 rhinit() 方法来初始化 RHIPE 子系统。

## Loading the RHIPE library
library(Rhipe)

## initializing the RHIPE subsystem, which is used for everything. RHIPE will not work if rhinit is not called.
rhinit()

输入:我们插入一个数值,而不是使用文件作为输入。

Map 阶段:该 MapReduce 程序的 Map 阶段将调用 10 次不同的迭代,在每次迭代中,根据迭代次数生成 1 到 10 之间的随机数。之后,将计算这些生成的数值的最大值和最小值。

## Defining the Map phase

Map(function(k,v){

## for generating the random deviates
 X  runif(v)

## for emitting the key-value pairs with key – k and
## value – min and max of generated random deviates.
 rhcollect(k, c(Min=min(x),Max=max(x))
}

输出:最终,Map 阶段的输出将作为此 MapReduce 作业的输出,并将存储到 HDFS 中的/app/hadoop/RHIPE/路径下。

通过 RHIPE 包的rhwatch()方法定义 MapReduce 作业:

## Create and running a MapReduce job by following
job = rhwatch(map=map,input=10,reduce=0,
output="/app/Hadoop/RHIPE/test",jobname='test')

从 HDFS 读取 MapReduce 输出:

## Read the results of job from HDFS
result <- rhread(job)

要以更可读的表格格式显示结果,请使用以下代码:

## Displaying the result
outputdata  <- do.call('rbind', lapply(result, "[", 2))

输出:

https://github.com/OpenDocCN/freelearn-ds-pt5-zh/raw/master/docs/bgdt-anal-r-hdp/img/3282OS_03_05.jpg

理解 RHIPE 函数参考

RHIPE 特别设计为提供 Hadoop 的低级接口。因此,拥有 RHIPE 包的 R 用户可以轻松地对存储在 HDFS 上的大数据集执行 Hadoop 数据操作,就像在 R 中调用print()函数一样。

现在我们将看到 RHIPE 库中所有方法的所有可能功能用法。所有这些方法都分为三类:初始化、HDFS 和 MapReduce 操作。

初始化

我们使用以下命令进行初始化:

  • rhinit:用于初始化 Rhipe 子系统。

    rhinit(TRUE,TRUE)

HDFS

我们使用以下命令进行 HDFS 操作:

  • rhls:用于从 HDFS 检索所有目录。

    其语法为rhls(path)

    rhls("/")

    输出:

    https://github.com/OpenDocCN/freelearn-ds-pt5-zh/raw/master/docs/bgdt-anal-r-hdp/img/3282OS_03_06.jpg

  • hdfs.getwd:用于获取当前工作 HDFS 目录。其语法为 hdfs.getwd()

  • hdfs.setwd:用于设置当前工作 HDFS 目录。其语法为 hdfs.setwd("/RHIPE")

  • rhput:用于将文件从本地目录复制到 HDFS。其语法为 rhput(src,dest)rhput("/usr/local/hadoop/NOTICE.txt","/RHIPE/")

  • rhcp:用于将文件从一个 HDFS 位置复制到另一个 HDFS 位置。其语法为 rhcp('/RHIPE/1/change.txt','/RHIPE/2/change.txt')

  • rhdel:用于从 HDFS 删除目录/文件。其语法为 rhdel("/RHIPE/1")

  • rhget:用于将 HDFS 文件复制到本地目录。其语法为 rhget("/RHIPE/1/part-r-00000", "/usr/local/")

  • rwrite:用于将 R 数据写入 HDFS。其语法为 rhwrite(list(1,2,3),"/tmp/x")

MapReduce

我们使用以下命令进行 MapReduce 操作:

  • rhwatch:用于准备、提交并监控 MapReduce 作业。

    # Syntax:
    rhwatch(map, reduce, combiner, input, output, mapred,partitioner,mapred, jobname)
    
    ## to prepare and submit MapReduce job:
    
    z=rhwatch(map=map,reduce=0,input=5000,output="/tmp/sort",mapred=mapred,read=FALSE)
    
    results <- rhread(z)
    
    
  • rhex:用于从 Hadoop 集群上执行 MapReduce 作业。

    ## Submit the job
    rhex(job)
    
    
  • rhjoin:用于检查 MapReduce 作业是否已完成。其语法为 rhjoin(job)

  • rhkill:用于终止正在运行的 MapReduce 作业。其语法为 rhkill(job)

  • rhoptions:用于获取或设置 RHIPE 配置选项。其语法为 rhoptions()

  • rhstatus:用于获取 RHIPE MapReduce 作业的状态。其语法为 rhstatus(job)

    rhstatus(job, mon.sec = 5, autokill = TRUE,showErrors = TRUE, verbose = FALSE, handler = NULL)
    
    

介绍 RHadoop

RHadoop 是一个包含三个 R 包的集合,用于在 R 环境中提供大数据操作。它由 Revolution Analytics 开发,Revolution Analytics 是基于 R 的商业软件的领先提供商。RHadoop 提供三个主要的 R 包:rhdfsrmrrhbase。每个包提供不同的 Hadoop 功能。

  • rhdfs 是一个 R 接口,提供从 R 控制台访问 HDFS 的功能。由于 Hadoop MapReduce 程序将输出写入 HDFS,因此通过调用 rhdfs 方法,可以轻松访问它们。R 程序员可以轻松地对分布式数据文件执行读写操作。基本上,rhdfs 包通过后台调用 HDFS API 来操作存储在 HDFS 上的数据源。

  • rmr 是一个 R 接口,用于在 R 环境内提供 Hadoop MapReduce 功能。因此,R 程序员只需要将应用逻辑分为 map 和 reduce 阶段,并使用 rmr 方法提交。之后,rmr 会调用 Hadoop streaming MapReduce API,输入参数包括输入目录、输出目录、mapper、reducer 等,来在 Hadoop 集群上执行 R MapReduce 作业。

  • rhbase 是一个 R 接口,用于通过 Thrift 服务器操作存储在分布式网络上的 Hadoop HBase 数据源。rhbase 包设计了多个方法,用于初始化、读写和表操作。

在这里,运行 Hadoop MapReduce 操作并不一定需要安装所有三个 RHadoop 包。如果我们将输入数据源存储在 HBase 数据源中,我们需要安装 rhbase;否则,我们需要 rhdfsrmr 包。由于 Hadoop 主要因其两个主要特性——Hadoop MapReduce 和 HDFS——而广受欢迎,这两个特性将在 R 控制台中通过 RHadoop 的 rhdfsrmr 包得到应用。这些包足以在 R 中运行 Hadoop MapReduce。基本上,rhdfs 提供 HDFS 数据操作,而 rmr 提供 MapReduce 执行操作。

RHadoop 还包括另一个名为 quick check 的包,用于调试由 rmr 包定义的 MapReduce 作业。

在接下来的部分,我们将看到它们的架构关系以及安装步骤。

理解 RHadoop 架构

由于 Hadoop 因 HDFS 和 MapReduce 而非常受欢迎,Revolution Analytics 开发了单独的 R 包,即 rhdfsrmrrhbase。RHadoop 的架构如以下图所示:

https://github.com/OpenDocCN/freelearn-ds-pt5-zh/raw/master/docs/bgdt-anal-r-hdp/img/3282OS_03_07.jpg

RHadoop 生态系统

安装 RHadoop

本节将介绍三个 RHadoop 包的安装技巧以及它们的前提条件。

  • R 和 Hadoop 安装:由于我们将使用 R 和 Hadoop 集成的环境,因此需要在计算机上安装 Hadoop 和 R。如果尚未安装,请参阅 第一章,准备使用 R 和 Hadoop。如我们所知,如果数据量过大,需要通过增加节点数来扩展集群。基于此,为了在系统上安装 RHadoop,我们需要根据数据的大小安装单节点或多节点 Hadoop。

    RHadoop 已经在 Cloudera、Hortonworks 和 MapR 提供的多个 Hadoop 发行版上进行了测试。

  • 安装 R 包:我们需要安装多个 R 包,它们帮助 R 与 Hadoop 连接。包的列表如下:

    • rJava

    • RJSONIO

    • itertools

    • digest

    • Rcpp

    • httr

    • functional

    • devtools

    • plyr

    • reshape2

    我们可以通过在 R 控制台中执行以下 R 命令来安装它们:

    install.packages( c('rJava','RJSONIO', 'itertools', 'digest','Rcpp','httr','functional','devtools', 'plyr','reshape2'))
    
    
  • 设置环境变量:我们可以通过 R 控制台使用以下代码来设置环境变量:

    ## Setting HADOOP_CMD
    Sys.setenv(HADOOP_CMD="/usr/local/hadoop/bin/hadoop")
    
    ## Setting up HADOOP_STREAMING
    Sys.setenv(HADOOP_STREAMING="/usr/local/hadoop/contrib/streaming/hadoop-streaming-1.0.3.jar")
    
    

    或者,我们也可以通过命令行设置 R 控制台,如下所示:

    export HADOOP_CMD=/usr/local/Hadoop
    export HADOOP_STREAMING=/usr/lib/hadoop-0.20-mapreduce/contrib/streaming/hadoop-streaming-2.0.0-mr1-cdh4.1.1.jar
    
    
  • 安装 RHadoop [rhdfsrmrrhbase]

    1. 从 Revolution Analytics 的 GitHub 仓库下载 RHadoop 软件包:github.com/RevolutionAnalytics/RHadoop

      • rmr:[rmr-2.2.2.tar.gz]

      • rhdfs:[rhdfs-1.6.0.tar.gz]

      • rhbase:[rhbase-1.2.0.tar.gz]

    2. 安装软件包。

      • 对于 rmr,我们使用:

        R CMD INSTALL rmr-2.2.2.tar.gz
        
        
      • 对于 rhdfs,我们使用:

        R CMD INSTALL rmr-2.2.2.tar.gz
        
        
      • 对于 rhbase,我们使用:

        R CMD INSTALL rhbase-1.2.0.tar.gz
        
        

      提示

      要安装 rhbase,我们需要在 Hadoop 集群上安装 HBase 和 Zookeeper。

理解 RHadoop 示例

一旦完成 RHadoop 的安装,我们可以通过运行 RHadoop 示例程序中的rmr2rhdfs库来测试设置,如下所示:

## loading the libraries
library(rhdfs')
library('rmr2')

## initializing the RHadoop
hdfs.init()

# defining the input data
small.ints = to.dfs(1:10)

## Defining the MapReduce job
mapreduce(
# defining input parameters as small.ints hdfs object, map parameter as function to calculate the min and max for generated random deviates.
  input = small.ints, 
  map = function(k, v)
  {
lapply(seq_along(v), function(r){

  x <- runif(v[[r]])
    keyval(r,c(max(x),min(x))) 
  })}) 

运行这些代码行后,按下Ctrl + Enter将执行此 MapReduce 程序。如果成功,最后一行将如下面的截图所示:

https://github.com/OpenDocCN/freelearn-ds-pt5-zh/raw/master/docs/bgdt-anal-r-hdp/img/3282OS_03_08.jpg

那一行字符表示 MapReduce 作业的输出位置。

要读取已执行 MapReduce 作业的结果,复制最后一行提供的输出位置,并将其传递给rhdfsfrom.dfs()函数。

https://github.com/OpenDocCN/freelearn-ds-pt5-zh/raw/master/docs/bgdt-anal-r-hdp/img/3282OS_03_09.jpg

其中,前一输出的第一列表示最大值,第二列表示最小值。

单词计数

MapReduce 问题定义:这个 RHadoop MapReduce 程序定义了识别提供的输入文本文件中所有单词频率的任务。

同样,请注意,这是我们在第二章 编写 Hadoop MapReduce 程序中学习的相同 MapReduce 问题。

wordcount = function(input, output = NULL, pattern = " "){

Map 阶段:这个map函数将逐行读取文本文件并按空格拆分。这个 Map 阶段将给所有被映射器捕获的单词分配1作为值。

wc.map = function(., lines) {
 keyval(
 unlist(
 strsplit(
 x = lines,
 split = pattern)),
 1)}

Reduce 阶段:Reduce 阶段将通过对具有相同键的单词进行求和操作来计算所有单词的总频率。

wc.reduce = function(word, counts ) {
 keyval(word, sum(counts))}

定义 MapReduce 作业:在定义完单词计数的映射器和归约器之后,我们需要创建driver方法来启动 MapReduce 的执行。

# To execute the defined Mapper and Reducer functions
# by specifying the input, output, map, reduce and input.format as parameters.

# Syntax:
# mapreduce(input, output, input.format, map,reduce,
# combine)

mapreduce(input = input ,
 output = output,
 input.format = "text",
 map = wc.map,
 reduce = wc.reduce,
 combine = T)}

执行 MapReduce 作业:我们将通过传递输入数据位置作为wordcount函数的参数来执行 RHadoop MapReduce 作业。

wordcount('/RHadoop/1/')

探索wordcount输出:

from.dfs("/tmp/RtmpRMIXzb/file2bda5e10e25f")

理解 RHadoop 函数参考

RHadoop 有三个不同的包,分别用于 HDFS、MapReduce 和 HBase 操作,以便对数据执行操作。

在这里,我们将看到如何使用rmrrhdfs包中的函数:

hdfs 包

分类函数如下:

  • 初始化

    • hdfs.init:用于初始化rhdfs包。其语法为hdfs.init()

    • hdfs.defaults:用于检索和设置rhdfs的默认值。其语法为hdfs.defaults()

    要检索hdfs配置的默认值,请参考以下截图:

    https://github.com/OpenDocCN/freelearn-ds-pt5-zh/raw/master/docs/bgdt-anal-r-hdp/img/3282OS_03_10.jpg

  • 文件操作

    • hdfs.put:用于将文件从本地文件系统复制到 HDFS 文件系统。

      hdfs.put('/usr/local/hadoop/README.txt','/RHadoop/1/')
      
      
    • hdfs.copy:用于将文件从 HDFS 目录复制到本地文件系统。

      hdfs.put('/RHadoop/1/','/RHadoop/2/')
      
      
    • hdfs.move:用于将文件从一个 HDFS 目录移动到另一个 HDFS 目录。

      hdfs.move('/RHadoop/1/README.txt','/RHadoop/2/')
      
      
    • hdfs.rename:用于重命名存储在 HDFS 中的文件(从 R 中进行操作)。

      hdfs.rename('/RHadoop/README.txt','/RHadoop/README1.txt')
      
      
    • hdfs.delete:用于从 R 中删除 HDFS 文件或目录。

      hdfs.delete("/RHadoop")
      
      
    • hdfs.rm:用于从 R 中删除 HDFS 文件或目录。

      hdfs.rm("/RHadoop")
      
      
    • hdfs.chmod:用于更改某些文件的权限。

      hdfs.chmod('/RHadoop', permissions= '777')
      
      
  • 文件读/写:

    • hdfs.file:用于初始化文件,以便进行读/写操作。

      f = hdfs.file("/RHadoop/2/README.txt","r",buffersize=104857600)
      
      
    • hdfs.write:用于通过流写入存储在 HDFS 中的文件。

      f = hdfs.file("/RHadoop/2/README.txt","r",buffersize=104857600)
      hdfs.write(object,con,hsync=FALSE)
      
      
    • hdfs.close:用于在文件操作完成后关闭流。它会关闭流并且不允许进一步的文件操作。

      hdfs.close(f)
      
      
    • hdfs.read:用于从 HDFS 目录中的二进制文件中读取。这将使用流来反序列化数据。

      f = hdfs.file(“/RHadoop/2/README.txt”,“r”,buffersize=104857600)

      m = hdfs.read(f)

      c = rawToChar(m)

      print©

  • 目录操作:

    • hdfs.dircreatehdfs.mkdir:这两个函数用于在 HDFS 文件系统上创建目录。

      hdfs.mkdir("/RHadoop/2/")
      
      
    • hdfs.rmhdfs.rmrhdfs.delete - 用于从 HDFS 删除目录或文件。

      hdfs.rm("/RHadoop/2/")
      
      
  • 工具:

    https://github.com/OpenDocCN/freelearn-ds-pt5-zh/raw/master/docs/bgdt-anal-r-hdp/img/3282OS_03_12.jpg

rmr 包

这些函数的类别如下:

  • 对于数据存储和检索:

    • to.dfs:用于从文件系统中写入或写出 R 对象。

      small.ints = to.dfs(1:10)

    • from.dfs:用于读取以二进制加密格式存储在 HDFS 文件系统中的 R 对象。

      from.dfs(‘/tmp/RtmpRMIXzb/file2bda3fa07850’)

  • 对于 MapReduce:

    • mapreduce:用于定义和执行 MapReduce 任务。

      mapreduce(input, output, map, reduce, combine, input.fromat, output.format, verbose)

    • keyval:用于创建和提取键值对。

      keyval(key, val)

总结

由于 RHadoop 被认为是成熟的,我们将在后续章节中进行数据分析时考虑它。在第五章,《学习 R 和 Hadoop 的数据分析》和第六章,《理解机器学习的大数据分析》中,我们将深入探讨一些大数据分析技术,并看到如何使用 RHadoop 解决现实世界中的问题。到目前为止,我们已经学习了如何使用 RHIPE 和 RHadoop 编写 MapReduce 程序。在下一章中,我们将看到如何使用 Hadoop 流式工具和 Hadoop 流式 R 包编写 Hadoop MapReduce 程序。

第四章. 使用 Hadoop Streaming 与 R

在上一章中,我们学习了如何借助 RHIPE 和 RHadoop 将 R 与 Hadoop 进行集成,并且通过示例进行演示。在本章中,我们将讨论以下主题:

  • 理解 Hadoop Streaming 的基础

  • 理解如何使用 R 运行 Hadoop Streaming

  • 探索 HadoopStreaming R 包

理解 Hadoop Streaming 的基础

Hadoop Streaming 是一个 Hadoop 工具,用于通过可执行脚本(如 Mapper 和 Reducer)运行 Hadoop MapReduce 作业。这类似于 Linux 中的管道操作。通过这种方式,文本输入文件会被打印到流中(stdin),该流作为输入提供给 Mapper,Mapper 的输出(stdout)则作为输入提供给 Reducer;最终,Reducer 将输出写入 HDFS 目录。

Hadoop Streaming 工具的主要优势在于它允许 Java 以及非 Java 编写的 MapReduce 作业在 Hadoop 集群上执行。此外,它还负责处理正在运行的 MapReduce 作业的进度。Hadoop Streaming 支持 Perl、Python、PHP、R 和 C++编程语言。若要运行用其他编程语言编写的应用程序,开发人员只需将应用程序逻辑转换为 Mapper 和 Reducer 部分,并且指定键值输出元素。我们在第二章,编写 Hadoop MapReduce 程序中已经了解到,要创建 Hadoop MapReduce 作业,我们需要 Mapper、Reducer 和 Driver 作为三个主要组件。在这里,当我们用 R 和 Hadoop 实现 MapReduce 时,创建用于运行 MapReduce 作业的驱动程序文件是可选的。

本章的编写目的是为了将 R 与 Hadoop 进行集成。因此,我们将展示 R 与 Hadoop Streaming 的示例。现在,我们将看到如何使用 Hadoop Streaming 与 R 脚本(包括 Mapper 和 Reducer)一起使用。从下图中,我们可以识别出 Hadoop Streaming MapReduce 作业的各个组成部分。

https://github.com/OpenDocCN/freelearn-ds-pt5-zh/raw/master/docs/bgdt-anal-r-hdp/img/3282OS_04_01.jpg

Hadoop Streaming 组件

假设我们已经将 Mapper 和 Reducer 实现为code_mapper.Rcode_reducer.R。我们将看到如何在 R 和 Hadoop 的集成环境中运行它们。这可以通过带有各种通用和 Streaming 选项的 Hadoop Streaming 命令来运行。

让我们来看一下 Hadoop Streaming 命令的格式:

 bin/hadoop command [generic Options] [streaming Options]

下图展示了 Hadoop Streaming 的执行示例,这是一个带有多个 Streaming 选项的 MapReduce 作业。

https://github.com/OpenDocCN/freelearn-ds-pt5-zh/raw/master/docs/bgdt-anal-r-hdp/img/3282OS_04_02.jpg

Hadoop Streaming 命令选项

在上面的图片中,有大约六个独特的重要组件是执行整个 Hadoop Streaming MapReduce 作业所必需的。它们都属于 Streaming 选项,除了 jar。

以下是前面 Hadoop Streaming 命令的逐行描述:

  • Line 1: 此选项用于指定 Hadoop jar 文件(为 Hadoop jar 设置类路径)。

  • Line 2: 此选项用于指定 HDFS 的输入目录。

  • Line 3: 此选项用于指定 HDFS 的输出目录。

  • Line 4: 此选项用于将文件提供给本地机器。

  • Line 5: 此选项用于定义可用的 R 文件作为 Mapper。

  • Line 6: 此选项用于将文件提供给本地机器。

  • Line 7: 此选项用于定义可用的 R 文件作为 Reducer。

上述命令中的六个主要 Hadoop 流式组件列出了并解释如下:

  • jar: 此选项用于运行带有编码类的 jar 文件,这些类设计用于提供 Java 流功能,以及其他编程的 Mapper 和 Reducer。它被称为 Hadoop 流式 jar。

  • input**😗* 此选项用于指定输入数据集的位置(存储在 HDFS 上),并传递给 Hadoop 流式 MapReduce 作业。

  • output: 此选项用于指定 HDFS 输出目录(MapReduce 作业的输出将写入该目录),并传递给 Hadoop 流式 MapReduce 作业。

  • file: 此选项用于将 MapReduce 资源(如 Mapper、Reducer 和 Combiner)复制到计算机节点(Tasktrackers),以使其本地化。

  • mapper: 此选项用于标识可执行的Mapper文件。

  • reducer: 此选项用于标识可执行的Reducer文件。

还有其他 Hadoop 流式命令选项,但它们是可选的。让我们来看看它们:

  • inputformat: 用于通过指定 Java 类名称来定义输入数据格式。默认情况下,它是TextInputFormat

  • outputformat: 用于通过指定 Java 类名称来定义输出数据格式。默认情况下,它是TextOutputFormat

  • partitioner: 用于包括编写的类或文件,以实现将 Mapper 阶段的输出按(键,值)对进行分区。

  • combiner: 用于包括编写的类或文件,用于通过聚合键的值来减少 Mapper 输出的值。另外,我们也可以使用默认的 combiner,它会在将 Mapper 的输出提供给 Reducer 之前,简单地合并所有键属性的值。

  • cmdenv: 此选项用于将环境变量传递给流式命令。例如,可以传递R_LIBS = /your /path /to /R /libraries

  • inputreader: 可用此选项替代inputformat类来指定记录读取器类。

  • verbose: 用于详细显示输出。

  • numReduceTasks: 此选项用于指定 Reducer 的数量。

  • mapdebug: 当 Mapper 任务失败时,用于调试Mapper文件的脚本。

  • reducedebug: 当 Reducer 任务失败时,用于调试Reducer文件的脚本。

现在,是时候来看一些 Hadoop 流式 MapReduce 作业的通用选项了。

  • conf: 用于指定应用程序配置文件。

    -conf configuration_file
    
    
  • D:用于定义特定 MapReduce 或 HDFS 属性的值。例如:

  • -D property = value 或指定临时 HDFS 目录

    -D dfs.temp.dir=/app/tmp/Hadoop/
    
    

    或指定零 Reducer 的总数:

    -D mapred.reduce.tasks=0
    
    

    注意

    -D选项仅在工具实现时有效。

  • fs:用于定义 Hadoop NameNode。

    -fs localhost:port
    
    
  • jt:用于定义 Hadoop JobTracker。

    -jt localhost:port
    
    
  • files:用于指定来自 HDFS 的大型或多个文本文件。

    -files hdfs://host:port/directory/txtfile.txt
    
    
  • libjars:用于指定要包含在类路径中的多个 jar 文件。

    -libjars  /opt/ current/lib/a.jar, /opt/ current/lib/b.jar
    
    
  • archives:用于指定在本地机器上解压的 jar 文件。

    -archives hdfs://host:fs_port/user/testfile.jar
    
    

理解如何使用 R 运行 Hadoop 流式处理

现在,我们了解了 Hadoop 流式处理是什么以及如何使用 Hadoop 通用选项和流式选项调用它。接下来,了解如何开发和运行 R 脚本。为此,我们可以考虑一个比简单的词频统计程序更好的示例。

MapReduce 操作的四个不同阶段如下所述:

  • 理解 MapReduce 应用程序

  • 理解如何编写 MapReduce 应用程序

  • 理解如何运行 MapReduce 应用程序

  • 理解如何探索 MapReduce 应用程序的输出

理解 MapReduce 应用程序

问题定义:该问题是根据地理位置对页面访问进行分段。在这个问题中,我们将考虑网站www.gtuadmissionhelpline.com/,该网站旨在为希望进入古吉拉特科技大学的学生提供指导。该网站包含多个领域的学院信息,如工程(大专、学位和硕士)、医学、酒店管理、建筑、药学、MBA 和 MCA。通过这个 MapReduce 应用程序,我们将识别访客在地理位置上的兴趣领域。

例如,来自瓦尔萨德市的大多数在线访客更常访问 MBA 院校的页面。基于此,我们可以识别瓦尔萨德学生的心态;他们对进入 MBA 领域有着浓厚的兴趣。因此,通过这个网站流量数据集,我们可以识别按城市划分的兴趣水平。现在,如果瓦尔萨德没有 MBA 院校,对他们来说将是一个大问题。他们将需要搬到其他城市,这可能会增加他们的教育成本。

通过使用这种数据,古吉拉特科技大学可以为来自不同城市的学生生成有价值的洞察。

输入数据集来源:要执行此类分析,我们需要获取该网站的 Web 流量数据。Google Analytics 是一个流行的免费服务,用于跟踪在线访客的元数据。Google Analytics 按各种维度和指标存储 Web 流量数据。我们需要设计一个特定的查询,从 Google Analytics 中提取数据集。

输入数据集:提取的 Google Analytics 数据集包含以下四个数据列:

  • date:这是访问日期,格式为 YYYY/MM/DD。

  • country:这是访问者所在的国家。

  • city:这是访问者所在的城市。

  • pagePath:这是网站页面的 URL。

输入数据集的头部如下:

$ head -5 gadata_mr.csv
20120301,India,Ahmedabad,/
20120302,India,Ahmedabad,/gtuadmissionhelpline-team
20120302,India,Mumbai,/
20120302,India,Mumbai,/merit-calculator
20120303,India,Chennai,/

预期的输出格式如下图所示:

https://github.com/OpenDocCN/freelearn-ds-pt5-zh/raw/master/docs/bgdt-anal-r-hdp/img/3282OS_04_03.jpg

以下是一个示例输出:

https://github.com/OpenDocCN/freelearn-ds-pt5-zh/raw/master/docs/bgdt-anal-r-hdp/img/3282OS_04_04.jpg

理解如何编写 MapReduce 应用程序

在这一部分中,我们将学习 MapReduce 应用程序的以下两个单元:

  • Mapper 代码

  • Reducer 代码

让我们从 Mapper 代码开始。

Mapper 代码:这个名为 ga-mapper.R 的 R 脚本将处理 MapReduce 作业的 Map 阶段。

Mapper 的工作是处理每一行,提取一对(键,值)并将其传递给 Reducer 以进行分组/聚合。在这个示例中,每一行是输入到 Mapper 的数据,输出为 City:PagePathCity 是键,PagePath 是值。现在 Reducer 可以获取给定城市的所有页面路径,因此可以轻松地进行分组。

# To identify the type of the script, here it is RScript
#! /usr/bin/env Rscript
# To disable the warning massages to be printed
options(warn=-1)
# To initiating the connection to standard input
input <- file("stdin", "r")
Each line has these four fields (date, country, city, and pagePath) in the same order. We split the line by a comma. The result is a vector which has the date, country, city, and pathPath in the indexes 1,2,3, and 4 respectively.

我们分别提取城市和页面路径的第三个和第四个元素。然后,它们将作为键值对写入流并传递给 Reducer 以进一步处理。

# Running while loop until all the lines are read
while(length(currentLine <- readLines(input, n=1, warn=FALSE)) > 0) {

# Splitting the line into vectors by "," separator 
 fields <- unlist(strsplit(currentLine, ","))

# Capturing the city and pagePath from fields
 city <- as.character(fields[3])
 pagepath <- as.character(fields[4])

# Printing both to the standard output
print(paste(city, pagepath,sep="\t"),stdout())

}

# Closing the connection to that input stream
close(input)

一旦 Mapper 阶段的输出作为(键,值)对可用,Reducers 将从 stdout 读取按行输出,并将其转换为最终的聚合键值对。

让我们看看 Mapper 输出格式是什么样的,以及 Reducer 输入数据格式是怎样的。

Reducer 代码:这个名为 ga_reducer.R 的 R 脚本将处理 MapReduce 作业的 Reducer 部分。

如我们所讨论的,Mapper 的输出将作为 Reducer 的输入。Reducer 会读取这些城市和页面路径对,并将所有值与其相应的键元素进行合并。

# To identify the type of the script, here it is RScript
#! /usr/bin/env Rscript

# Defining the variables with their initial values
city.key <- NA
page.value <- 0.0

# To initiating the connection to standard input
input <- file("stdin", open="r")

# Running while loop until all the lines are read
while (length(currentLine <- readLines(input, n=1)) > 0) {

# Splitting the Mapper output line into vectors by 
# tab("\t") separator
 fields <- strsplit(currentLine, "\t")

# capturing key and value form the fields
# collecting the first data element from line which is city
 key <- fields[[1]][1]
# collecting the pagepath value from line 
 value <- as.character(fields[[1]][2])

Mapper 输出以两个主要字段写入,使用 \t 作为分隔符,并按行输出数据;因此,我们通过使用 \t 分割数据,以便从流输入中捕获两个主要属性(键和值)。

收集键和值后,Reducer 会将其与之前捕获的值进行比较。如果之前没有设置,则进行设置;否则,使用 R 中的 combine 函数将其与之前的字符值结合,最后将其打印到 HDFS 输出位置。

# setting up key and values

# if block will check whether key attribute is 
# initialized or not. If not initialized then it will be # assigned from collected key attribute with value from # mapper output. This is designed to run at initial time.
 if (is.na(city.key)) {
 city.key <- key
 page.value <- value
 }
 else {

# Once key attributes are set, then will match with the previous key attribute value. If both of them matched then they will combined in to one.
 if (city.key == key) {
 page.value <- c(page.value, value)

 }
 else {

# if key attributes are set already but attribute value # is other than previous one then it will emit the store #p agepath values along with associated key attribute value of city,

 page.value <- unique(page.value)
# printing key and value to standard output
print(list(city.key, page.value),stdout())
 city.key <- key
 page.value <- value
 }
 }
}

print(list(city.key, page.value), stdout())

# closing the connection
close(input)

理解如何运行 MapReduce 应用程序

在使用 R 语言开发 Mapper 和 Reducer 脚本后,是时候在 Hadoop 环境中运行它们了。在执行这个脚本之前,建议先在简单的管道操作上测试它们,使用样本数据集进行验证。

$ cat gadata_sample.csv | ga_mapper.R |sort | ga_reducer.R

前面的命令将在本地计算机上运行开发的 Mapper 和 Reducer 脚本。但它将类似于 Hadoop 流式作业的运行方式。我们需要测试这个命令,以便发现可能在运行时出现的问题,或者识别编程或逻辑错误。

现在,我们已经测试并准备好使用 Hadoop 流式命令运行 Mapper 和 Reducer。这个 Hadoop 流式操作可以通过调用通用的 jar 命令并附带流式命令选项来执行,就像我们在本章的 理解 Hadoop 流式处理的基础知识 部分中学到的那样。我们可以通过以下方式执行 Hadoop 流式作业:

  • 从命令提示符

  • R 或 RStudio 控制台

执行命令与通用命令选项和流式命令选项在两种方式下是相同的。

从命令提示符执行 Hadoop 流式作业

正如我们在 理解 Hadoop 流式处理的基础知识 部分中学到的,使用 R 开发的 Hadoop 流式 MapReduce 作业的执行可以使用以下命令:

$ bin/hadoop jar {HADOOP_HOME}/contrib/streaming/hadoop-streaming-1.0.3.jar 
 -input /ga/gadaat_mr.csv 
 -output /ga/output1 
 -file /usr/local/hadoop/ga/ga_mapper.R  
 -mapper ga_mapper.R 
 -file /usr/local/hadoop/ga/ga_ reducer.R 
 -reducer ga_reducer.R

从 R 或 RStudio 控制台执行 Hadoop 流式作业

作为 R 用户,从 R 控制台运行 Hadoop 流式作业会更合适。这可以通过 system 命令完成:

system(paste("bin/hadoop jar”, “{HADOOP_HOME}/contrib/streaming/hadoop-streaming-1.0.3.jar",
 "-input /ga/gadata_mr.csv", 
 "-output /ga/output2", 
 "-file /usr/local/hadoop/ga/ga_mapper.R",
"-mapper ga_mapper.R", 
 "-file /usr/local/hadoop/ga/ga_reducer.R", 
 "-reducer ga_reducer.R")) 

这个前面的命令与您已在命令提示符中使用的命令相似,用于执行带有通用选项和流式选项的 Hadoop 流式作业。

理解如何探索 MapReduce 应用的输出

执行成功后,就该探索输出,以检查生成的输出是否重要。输出将与两个目录 _logs_SUCCESS 一起生成。_logs 用于跟踪所有操作和错误;_SUCCESS 仅在 MapReduce 作业成功完成时生成。

再次,可以通过以下两种方式触发命令:

  • 从命令提示符

  • 从 R 控制台

从命令提示符查看输出

要列出输出目录中生成的文件,将调用以下命令:

$ bin/hadoop dfs -cat /ga/output/part-* > temp.txt
$ head -n 40 temp.txt

用于检查输出的快照如下:

https://github.com/OpenDocCN/freelearn-ds-pt5-zh/raw/master/docs/bgdt-anal-r-hdp/img/3282OS_04_05.jpg

从 R 或 RStudio 控制台查看输出

相同的命令可以在 R(与 RStudio)控制台中通过 system 方法使用。

dir <- system("bin/hadoop dfs -ls /ga/output",intern=TRUE)
out <- system("bin/hadoop dfs -cat /ga/output2/part-00000",intern=TRUE)

前面函数的截图如下:

https://github.com/OpenDocCN/freelearn-ds-pt5-zh/raw/master/docs/bgdt-anal-r-hdp/img/3282OS_04_06.jpg

理解 Hadoop MapReduce 脚本中使用的基本 R 函数

现在,我们将查看一些在 Hadoop Mapper 和 Reducer 中用于数据处理的基本实用函数:

  • file:此函数用于创建文件连接以进行读写操作。它还用于从 stdinstdout 读写。此函数将在 Mapper 和 Reducer 阶段的初始化时使用。

    Con <- file("stdin", "r")
    
    
  • write:此函数用于将数据写入文件或标准输入。它将在 Mapper 中设置好键值对后使用。

    write(paste(city,pagepath,sep="\t"),stdout())
    
    
  • print:此函数用于将数据写入文件或标准输入。它将在 Mapper 中准备好键值对后使用。

    print(paste(city,pagepath,sep="\t"),stdout())
    
    
  • close:此函数可用于在读取或写入操作完成后关闭与文件的连接。它可以在所有处理完成时与 Mapper 和 Reducer 一起使用,位于关闭(conn)端。

  • stdin:这是对应输入的标准连接。stdin() 函数是一个文本模式连接,返回连接对象。此函数将在 Mapper 和 Reducer 中使用。

    conn <- file("stdin", open="r")
    
    
  • stdout:这是对应输出的标准连接。stdout() 函数是一个文本模式连接,也会返回对象。此函数将在 Mapper 和 Reducer 中使用。

    print(list(city.key, page.value),stdout())
    
    ## where city.key is key and page.value is value of that key
    
    
  • sinksink 将 R 输出发送到连接。如果是文件或流连接,输出将返回到文件或流。这将在 Mapper 和 Reducer 中用于跟踪所有功能输出以及错误。

    sink("log.txt")
    k <- 1:5
    for(i in 1:k){
    print(paste("value of k",k))
    }sink()
    unlink("log.txt")
    

监控 Hadoop MapReduce 作业

Reducer 阶段的一个小语法错误会导致 MapReduce 作业失败。在 Hadoop MapReduce 作业失败后,我们可以通过 Hadoop MapReduce 管理页面跟踪问题,在该页面上可以获取关于正在运行的作业以及已完成作业的信息。

如果作业失败,我们可以看到已完成/失败的 Map 和 Reduce 作业的总数。点击失败的作业将提供导致这些特定 Mappers 或 Reducers 失败的原因。

同时,我们可以通过 JobTracker 控制台查看正在运行的 MapReduce 作业的实时进度,如下图所示:

https://github.com/OpenDocCN/freelearn-ds-pt5-zh/raw/master/docs/bgdt-anal-r-hdp/img/3282OS_04_07.jpg

监控 Hadoop MapReduce 作业

通过命令,我们可以通过指定其输出目录来检查特定 MapReduce 作业的历史,使用以下命令:

$ bin/hadoop job –history /output/location 

以下命令将打印 MapReduce 作业的详细信息、失败的作业以及被终止作业的原因。

$ bin/hadoop job -history all /output/location 

上述命令将打印每个任务的成功任务和任务尝试的详细信息。

探索 HadoopStreaming R 包

HadoopStreaming 是一个由 David S. Rosenberg 开发的 R 包。我们可以说这是一个简单的 MapReduce 脚本框架。它还可以在没有 Hadoop 的情况下以流式方式操作数据。我们可以将这个 R 包看作是 Hadoop MapReduce 的启动器。对于任何无法回忆起 Hadoop 流式命令的分析师或开发者,这个包将有助于快速运行 Hadoop MapReduce 作业。

该包的三个主要功能如下:

  • 分块数据读取:该包允许分块数据读取和写入 Hadoop 流式处理。此功能将解决内存问题。

  • 支持多种数据格式:该软件包允许以三种不同的数据格式读取和写入数据。

  • 针对 Hadoop 流式命令的强大工具:该软件包还允许用户为 Hadoop 流式命令指定命令行参数。

本软件包主要设计了三个功能,以高效读取数据:

  • hsTableReader

  • hsKeyValReader

  • hsLineReader

现在,让我们理解这些功能及其用例。之后,我们将通过单词计数的 MapReduce 作业来理解这些功能。

理解hsTableReader函数

hsTableReader函数设计用于读取表格格式的数据。该函数假设已经与文件建立了输入连接,因此它将检索整行数据。它假设所有具有相同键的行都连续存储在输入文件中。

由于 Hadoop 流式作业保证在提供给 Reducer 之前,Mapper 的输出行会被排序,因此在 Hadoop 流式 MapReduce 作业中不需要使用sort函数。当我们不在 Hadoop 上运行时,必须在Mapper函数执行后显式调用sort函数。

定义hsTableReader函数:

hsTableReader(file="", cols='character',
 chunkSize=-1, FUN=print,
 ignoreKey=TRUE, singleKey=TRUE, skip=0,
 sep='\t', keyCol='key',
 FUN=NULL, ,carryMemLimit=512e6,
 carryMaxRows=Inf,
 stringsAsFactors=FALSE)

上述代码中的术语如下:

  • file:这是一个连接对象、流或字符串。

  • chunkSize:指示函数每次读取的最大行数。-1表示一次读取所有行。

  • cols:表示作为“what”参数扫描的列名列表。

  • skip:用于跳过前 n 行数据。

  • FUN:此函数将使用用户输入的数据。

  • carryMemLimit:指示单个键值的最大内存限制。

  • carryMaxRows:指示要考虑或读取的最大行数。

  • stringsAsFactors:定义是否将字符串转换为因子(TRUEFALSE)。

例如,文件中的数据:

# Loading libraries
Library("HadoopStreaming")
# Input data String with collection of key and values
str <- " key1\t1.91\nkey1\t2.1\nkey1\t20.2\nkey1\t3.2\nkey2\t1.2\nkey2\t10\nkey3\t2.5\nkey3\t2.1\nkey4\t1.2\n"cat(str)

上述代码的输出如下图所示:

https://github.com/OpenDocCN/freelearn-ds-pt5-zh/raw/master/docs/bgdt-anal-r-hdp/img/3282OS_04_08.jpg

hsTableReader读取的数据如下:

# A list of column names, as'what' arg to scan
cols = list(key='',val=0)

# To make a text connection
con <- textConnection(str, open = "r")
# To read the data with chunksize 3
hsTableReader(con,cols,chunkSize=3,FUN=print,ignoreKey=TRUE)

上述代码的输出如下图所示:

https://github.com/OpenDocCN/freelearn-ds-pt5-zh/raw/master/docs/bgdt-anal-r-hdp/img/3282OS_04_09.jpg

理解hsKeyValReader函数

hsKeyValReader函数设计用于读取以键值对格式存储的数据。该函数还使用chunkSize定义一次读取的行数,每行由键字符串和值字符串组成。

hsKeyValReader(file = "", chunkSize = -1, skip = 0, sep = "\t",FUN = function(k, v) cat(paste(k, v))

该函数的术语与hsTablereader()类似。

示例:

# Function for reading chunkwise dataset
printkeyval <- function(k,v) {cat('A chunk:\n')cat(paste(k,v,sep=': '),sep='\n')}
str <- "key1\tval1\nkey2\tval2\nkey3\tval3\n"
con <- textConnection(str, open = "r")

hsKeyValReader(con, chunkSize=1, FUN=printFn)

上述代码的输出如下图所示:

https://github.com/OpenDocCN/freelearn-ds-pt5-zh/raw/master/docs/bgdt-anal-r-hdp/img/3282OS_04_10.jpg

理解hsLineReader函数

hsLineReader 函数设计用于将整行读取为字符串,而不执行数据解析操作。它反复从文件中读取 chunkSize 行数据,并将这些字符串的字符向量传递给 FUN

hsLineReader(file = "", chunkSize = 3, skip = 0, FUN = function(x) cat(x, sep = "\n"))

该函数的术语与 hsTablereader() 相似。

示例:

str <- " This is HadoopStreaming!!\n here are,\n examples for chunk dataset!!\n in R\n  ?"

#  For defining the string as data source
con <- textConnection(str, open = "r")

# read from the con object
hsLineReader(con,chunkSize=2,FUN=print)

上述代码的输出如下图所示:

https://github.com/OpenDocCN/freelearn-ds-pt5-zh/raw/master/docs/bgdt-anal-r-hdp/img/3282OS_04_11.jpg

你可以在cran.r-project.org/web/packages/HadoopStreaming/HadoopStreaming.pdf上获取关于这些方法以及其他现有方法的更多信息。

现在,我们将使用 Hadoop MapReduce 程序实现上述数据读取方法,并在 Hadoop 上运行。在某些情况下,键值对或数据行不会被加载到机器内存中,因此逐块读取数据比改进机器配置更为合适。

问题定义:

Hadoop 词频统计:由于我们已经知道什么是词频统计应用,我们将使用上述方法来实现词频统计的概念。这个 R 脚本已从 HadoopStreaming R 包中复制,这个包可以和 HadoopStreaming R 库一起作为示例代码下载。

输入数据集:该数据集取自俄罗斯作家 列夫·托尔斯泰 的小说 安娜·卡列尼娜 第一章。

R 脚本:本节包含了 Mapper、Reducer 及其他配置参数的代码。

文件:hsWordCnt.R

## Loading the library
library(HadoopStreaming)

## Additional command line arguments for this script (rest are default in hsCmdLineArgs)
spec = c('printDone','D',0,"logical","A flag to write DONE at the end.",FALSE)

opts = hsCmdLineArgs(spec, openConnections=T)

if (!opts$set) {
 quit(status=0)
}

# Defining the Mapper columns names
mapperOutCols = c('word','cnt')

# Defining the Reducer columns names
reducerOutCols = c('word','cnt')

# printing the column header for Mapper output
if (opts$mapcols) {
 cat( paste(mapperOutCols,collapse=opts$outsep),'\n', file=opts$outcon )
} 

# Printing the column header for Reducer output 
if (opts$reducecols) {
 cat( paste(reducerOutCols,collapse=opts$outsep),'\n', file=opts$outcon )
}

## For running the Mapper
if (opts$mapper) {
 mapper <- function(d) {
    words <- strsplit(paste(d,collapse=' '),'[[:punct:][:space:]]+')[[1]] # split on punctuation and spaces
    words <- words[!(words=='')]  # get rid of empty words caused by whitespace at beginning of lines
    df = data.frame(word=words)
    df[,'cnt']=1

# For writing the output in the form of key-value table format
hsWriteTable(df[,mapperOutCols],file=opts$outcon,sep=opts$outsep)
  }

## For chunk wise reading the Mapper output, to be feeded to Reducer hsLineReader(opts$incon,chunkSize=opts$chunksize,FUN=mapper)

## For running the Reducer
} else if (opts$reducer) {

  reducer <- function(d) {
    cat(d[1,'word'],sum(d$cnt),'\n',sep=opts$outsep)
  }
  cols=list(word='',cnt=0)  # define the column names and types (''-->string 0-->numeric)
  hsTableReader(opts$incon,cols,chunkSize=opts$chunksize,skip=opts$skip,sep=opts$insep,keyCol='word',singleKey=T, ignoreKey= F, FUN=reducer)
  if (opts$printDone) {
    cat("DONE\n");
  }
}

# For closing the connection corresponding to input
if (!is.na(opts$infile)) {
  close(opts$incon)
}

# For closing the connection corresponding to input
if (!is.na(opts$outfile)) {
  close(opts$outcon)
}

运行 Hadoop 流式作业

由于这是一个 Hadoop 流式作业,它将像之前执行的 Hadoop 流式作业一样运行。对于这个例子,我们将使用一个 shell 脚本来执行 runHadoop.sh 文件以运行 Hadoop 流式作业。

设置系统环境变量:

#! /usr/bin/env bash
HADOOP="$HADOOP_HOME/bin/hadoop"   # Hadoop command

HADOOPSTREAMING="$HADOOP jar
$HADOOP_HOME/contrib/streaming/hadoop-streaming-1.0.3.jar" # change version number as appropriate

RLIBPATH=/usr/local/lib/R/site-library  # can specify additional R Library paths here

设置 MapReduce 作业参数:

INPUTFILE="anna.txt"
HFSINPUTDIR="/HadoopStreaming"
OUTDIR="/HadoopStreamingRpkg_output"

RFILE=" home/hduser/Desktop/HadoopStreaming/inst/wordCntDemo/ hsWordCnt.R"
#LOCALOUT="/home/hduser/Desktop/HadoopStreaming/inst/wordCntDemo/annaWordCnts.out"
# Put the file into the Hadoop file system
#$HADOOP fs -put $INPUTFILE $HFSINPUTDIR

删除现有输出目录:

# Remove the directory if already exists (otherwise, won't run)
#$HADOOP fs -rmr $OUTDIR

设计具有通用选项和流式选项的 Hadoop MapReduce 命令:

MAPARGS="--mapper" 
REDARGS="--reducer"
JOBARGS="-cmdenv R_LIBS=$RLIBPATH" # numReduceTasks 0
# echo $HADOOPSTREAMING -cmdenv R_LIBS=$RLIBPATH  -input $HFSINPUTDIR/$INPUTFILE -output $OUTDIR -mapper "$RFILE $MAPARGS" -reducer "$RFILE $REDARGS" -file $RFILE 

$HADOOPSTREAMING $JOBARGS   -input $HFSINPUTDIR/$INPUTFILE -output $OUTDIR -mapper "$RFILE $MAPARGS" -reducer "$RFILE $REDARGS" -file $RFILE 

从 HDFS 提取输出到本地目录:

# Extract output
./$RFILE --reducecols > $LOCALOUT
$HADOOP fs -cat $OUTDIR/part* >> $LOCALOUT

执行 Hadoop 流式作业

我们现在可以通过执行命令 runHadoop.sh 来执行 Hadoop 流式作业。为了执行此操作,我们需要设置用户权限。

sudo chmod +x runHadoop.sh

通过以下命令执行:

./runHadoop.sh

最后,它将执行整个 Hadoop 流式作业,然后将输出复制到本地目录。

总结

我们已经学习了大部分将 R 与 Hadoop 集成以执行数据操作的方法。在下一章中,我们将学习如何利用 R 和 Hadoop 解决现实世界的数据分析问题。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值