Hadoop-集群部署手册-全-

Hadoop 集群部署手册(全)

原文:Deep learning with Hadoop

协议:CC BY-NC-SA 4.0

零、前言

在过去的几年里,Hadoop 已经成为构建数据集成平台的标准解决方案。将任何新技术引入公司的数据基础架构堆栈都需要系统工程师和数据库管理员快速学习新组件的所有方面。Hadoop 并没有让这项任务变得更容易,因为它不是一个单一的软件产品,而是多个独立的开源项目的集合。这些项目需要正确安装和配置,以使 Hadoop 平台健壮可靠。

许多现有的 Hadoop 发行版提供了一种使用某种图形界面安装 Hadoop 的简化方法。这种方法大大减少了从零到全功能 Hadoop 集群所需的时间。它还简化了集群配置的管理。自动设置和配置的问题在于,它实际上隐藏了很多关于 Hadoop 组件协同工作的重要方面,比如为什么有些组件需要其他组件,哪些配置参数最重要等等。

本书提供了手动安装和配置所有主要 Hadoop 组件的指南。您自己设置至少一个完全运行的集群将为 Hadoop 如何在幕后运行提供非常有用的见解,并使您更容易调试任何可能出现的问题。您也可以使用这本书作为快速参考,以简洁的格式在一个地方收集主要的 Hadoop 组件和配置选项。在写这本书的时候,我发现自己在处理真正的生产 Hadoop 集群时经常引用它,以便在操作系统配置方面查找特定的变量或刷新最佳实践。这个习惯让我确信,这样的指南可能对其他有抱负和经验的 Hadoop 管理员和开发人员有用。

这本书涵盖了什么

第 1 章设置 Hadoop 集群–从硬件到分发,回顾了 Hadoop 的主要组件以及选择和调整集群硬件的方法。它还涉及各种 Hadoop 发行版的主题。

第 2 章安装和配置 Hadoop ,提供了安装和配置 Hadoop 主要组件的分步说明:名称节点(包括高可用性)、作业跟踪器、数据节点和任务跟踪器。

第 3 章配置 Hadoop 生态系统,回顾了 Sqoop、Hive 和 Impala 的配置过程。

第 4 章保护 Hadoop 安装,提供了保护各种 Hadoop 组件的指南。它还概述了使用 Hadoop 配置 Kerberos。

第 5 章监控 Hadoop 集群,指导您为生产使用做好集群准备。

第 6 章将 Hadoop 部署到云,回顾了在虚拟化环境中使用 Hadoop 的情况,包括 Elastic MapReduce 和使用 Whirr。

这本书你需要什么

本书中的例子没有具体的软件要求。如果您计划在沙盒环境中安装 Hadoop 集群,您将需要某种虚拟化软件,如虚拟盒子。

这本书是给谁的

这本书主要面向计划安装、配置和支持生产级 Hadoop 集群的人。这可能是系统管理员、数据库管理员或 Hadoop 管理员(目前仍是一个罕见的职位)。总的来说,任何计划使用 Hadoop 平台的人都会感兴趣。

惯例

在这本书里,你会发现许多区分不同种类信息的文本风格。以下是这些风格的一些例子,以及对它们的含义的解释。

文本中的码字、数据库表名、文件夹名、文件名、文件扩展名、路径名、伪 URL、用户输入和 Twitter 句柄如下所示:“您需要在hive.metastore.uris变量中为所有这些元存储指定连接字符串。”

代码块设置如下:

{
"access_id": "Your Access Key ID",
"private_key": "Your AWS Secret Access Key",
"keypair": "emr-keys",
"key-pair-file": "/path/to/key-file/emr-keys.pem",
"log_uri": "s3n://emr-logs-x123/",
"egion": "us-east-1"
}

当我们希望将您的注意力吸引到代码块的特定部分时,相关的行或项目以粗体显示:

{
"access_id": "Your Access Key ID",
"private_key": "Your AWS Secret Access Key",
"keypair": "emr-keys",
"key-pair-file": "/path/to/key-file/emr-keys.pem",
"log_uri": "s3n://emr-logs-x123/",
"egion": "us-east-1"
}

任何命令行输入或输出都编写如下:

# hdfs dfs -mkdir /warehouse
# hdfs dfs -chmod a+w /warehouse

新名词重要词语以粗体显示。你在屏幕上看到的单词,例如在菜单或对话框中,出现在如下文本中:“点击下一步按钮,进入下一个屏幕”。

警告或重要提示会出现在这样的框中。

类型

提示和技巧是这样出现的。

读者反馈

我们随时欢迎读者的反馈。让我们知道你对这本书的看法——你喜欢或可能不喜欢什么。读者反馈对我们开发您真正能从中获得最大收益的标题非常重要。

要给我们发送一般反馈,只需向<[feedback@packtpub.com](mailto:feedback@packtpub.com)>发送电子邮件,并通过您的消息主题提及书名。

如果你对某个主题有专业知识,并且对写作或投稿感兴趣,请参阅我们在www.packtpub.com/authors上的作者指南。

客户支持

现在,您已经自豪地拥有了一本书,我们有许多东西可以帮助您从购买中获得最大收益。

勘误表

尽管我们尽了最大努力来确保我们内容的准确性,但错误还是会发生。如果你在我们的某本书里发现了错误——可能是文本或代码中的错误——如果你能向我们报告,我们将不胜感激。通过这样做,你可以让其他读者免受挫折,并帮助我们改进这本书的后续版本。如果您发现任何勘误表,请访问http://www.packtpub.com/submit-errata,选择您的书籍,点击勘误表 提交 表格链接,并输入您的勘误表详情。一旦您的勘误表得到验证,您的提交将被接受,勘误表将上传到我们的网站上,或添加到该标题的勘误表部分下的任何现有勘误表列表中。通过从http://www.packtpub.com/support中选择您的标题,可以查看任何现有的勘误表。

盗版

互联网上版权材料的盗版是所有媒体的一个持续问题。在 Packt,我们非常重视版权和许可证的保护。如果您在互联网上遇到任何形式的我们作品的非法拷贝,请立即向我们提供位置地址或网站名称,以便我们寻求补救。

请通过<[copyright@packtpub.com](mailto:copyright@packtpub.com)>联系我们,获取疑似盗版资料的链接。

我们感谢您在保护我们作者方面的帮助,以及我们为您带来有价值内容的能力。

问题

如果您对本书的任何方面有问题,可以在<[questions@packtpub.com](mailto:questions@packtpub.com)>联系我们,我们将尽最大努力解决。

一、设置 Hadoop 集群——从硬件到发行版

Hadoop 是一个免费开放的开源分布式存储和计算平台。它的创建是为了允许使用商品硬件集群存储和处理大量数据。在过去的几年里,Hadoop 成为了大数据项目事实上的标准。在本章中,我们将涵盖以下主题:

  • 选择 Hadoop 集群硬件
  • Hadoop 发行版
  • 为 Hadoop 集群选择操作系统

本章将概述为集群选择和配置硬件时的 Hadoop 理念。我们还将回顾不同的 Hadoop 发行版,其数量每年都在增长。本章将解释这些分布之间的异同。

对您来说,作为 Hadoop 管理员或架构师,集群实施的实际部分始于决定使用什么样的硬件以及需要多少硬件,但在您下硬件订单、卷起袖子并开始设置之前,需要问一些基本问题。这些问题包括与集群设计相关的问题,例如集群需要存储多少数据,数据增长率的预测是什么,主要的数据访问模式是什么,集群将主要用于预定义的计划任务,还是用于探索性数据分析的多租户环境?Hadoop 的架构和数据访问模型允许极大的灵活性。它可以适应不同类型的工作负载,例如批量处理海量数据或支持像 Impala 这样的项目的实时分析。

与此同时,一些集群更适合特定类型的工作,因此在到达硬件规范阶段时,考虑集群设计和目的的想法是很重要的。在处理数百台服务器的集群时,关于硬件和总体布局的初步决策将对集群的性能、稳定性和相关成本产生重大影响。

选择 Hadoop 集群硬件

Hadoop 是一个可扩展的集群非共享系统,用于大规模并行数据处理。Hadoop 的整个概念是,单个节点在整个集群的可靠性和性能中不起重要作用。这种设计假设导致选择能够在单个节点上高效处理少量(相对于总数据大小)数据并且在硬件级别上不需要大量可靠性和冗余的硬件。您可能已经知道,有几种类型的服务器组成了 Hadoop 集群。有主节点,如命名节点次命名节点作业跟踪器和称为数据节点的工作节点。除了核心的 Hadoop 组件之外,部署几个辅助服务器也是一种常见的做法,例如网关、Hue 服务器和 Hive Metastore。典型的 Hadoop 集群如下图所示:

Choosing Hadoop cluster hardware

典型的 Hadoop 集群布局

这些类型的服务器在集群中扮演的角色不同,对这些节点的硬件规格和可靠性的要求也不同。我们将首先讨论数据节点的不同硬件配置,然后讨论名称节点和作业跟踪器的典型设置。

选择数据节点硬件

数据节点是 Hadoop 集群中的主要工作节点,它扮演两个主要角色:存储 HDFS 数据和执行 MapReduce 任务。数据节点是 Hadoop 的主要存储和计算资源。人们可能会认为,由于数据节点在集群中扮演着如此重要的角色,您应该为它们使用最好的硬件。这并不完全正确。Hadoop 的设计理念是,数据节点是“一次性工作人员”,服务器作为集群的一部分,速度足够快,可以完成有用的工作,但价格足够便宜,如果出现故障,可以轻松更换。大型集群中的硬件故障频率可能是核心 Hadoop 开发人员考虑的最重要因素之一。Hadoop 通过将冗余实现从集群硬件转移到集群软件本身来解决这个问题。

Hadoop 在许多层面上提供冗余。每个数据节点只存储 HDFS 文件的一些数据块,这些数据块被多次复制到不同的节点,因此在单个服务器出现故障时,数据仍然可以访问。根据您选择的配置,群集甚至可以容忍多个节点出现故障。Hadoop 超越了这一点,允许您指定哪些服务器驻留在哪些机架上,并尝试在不同的机架上存储数据副本,因此,即使整个机架停机,您的数据保持可访问的可能性也会大大增加(尽管这不是严格的保证)。这种设计意味着没有理由为 Hadoop 数据节点投资 RAID 控制器。

与其对本地磁盘使用 RAID,不如选择称为 JBOD(只是一堆磁盘)的设置。为 Hadoop 工作负载提供更好的性能,降低硬件成本。您不必担心个别磁盘故障,因为冗余是由 HDFS 提供的。

存储数据是数据节点扮演的第一个角色。第二个角色是充当数据处理节点并执行自定义的 MapReduce 代码。MapReduce 作业被分成许多独立的任务,这些任务在多个数据节点上并行执行,为了使一个作业产生逻辑一致的结果,必须完成所有子任务。

这意味着 Hadoop 不仅要在存储上提供冗余,还要在计算层提供冗余。Hadoop 通过在不同节点上重试失败的任务来实现这一点,而不会中断整个作业。它还跟踪故障率异常高或响应速度比其他节点慢的节点,最终这些节点可能会被列入黑名单并从集群中排除。

那么,典型数据节点的硬件应该是什么样的呢?理想情况下,数据节点应该是一个平衡的系统,具有合理数量的磁盘存储和处理能力。定义“平衡系统”和“合理存储量”并不像听起来那么简单。当您试图设计出一个最佳且可扩展的 Hadoop 集群时,有许多因素会起作用。最重要的考虑因素之一是总群集存储容量和群集存储密度。这些参数紧密相关。总群集存储容量的估计相对简单。它基本上回答了诸如我们可以向集群中放入多少数据之类的问题。以下是您可以用来估计集群所需容量的步骤列表:

  1. 确定数据源:列出所有已知的数据源,并决定是否需要全部或部分初始数据导入。您应该保留总群集容量的 15-20%,甚至更多,以适应任何新的数据源或计划外的数据大小增长。
  2. 估计数据增长率:每个确定的数据源都有一个相关的数据摄取率。例如,如果您计划每天从您的 OLTP 数据库导出数据,您可以很容易地估计这个源在一周、一月、一年等过程中将产生多少数据。您需要做一些测试导出来获得一个准确的数字。
  3. 将您估计的存储需求乘以复制因子:到目前为止,我们已经讨论了可用存储容量。Hadoop 通过多次复制数据块并将它们放在集群中的不同节点上,实现了 HDFS 级的冗余。默认情况下,每个数据块复制三次。您可以通过增加或减少复制因子来调整此参数。将复制因子设置为1会完全降低集群的可靠性,因此不应使用。因此,要获得原始群集存储容量,您需要将估计值乘以复制因子。如果您估计今年需要 300 TB 的可用存储,并且计划使用3的复制系数,则原始容量将为 900 TB。
  4. 将 MapReduce 临时文件和系统数据考虑在内:MapReduce 任务产生中间数据,该数据正从地图执行阶段传递到 Reduce 阶段。这些临时数据不在 HDFS,但是您需要为临时文件分配总服务器磁盘容量的 25-30%。此外,操作系统需要单独的磁盘卷,但操作系统的存储需求通常微不足道。

确定总的可用和原始群集存储容量是确定数据节点硬件规格的第一步。为了进一步讨论,我们将在提及群集的总可用存储时指原始容量,因为从硬件角度来看,这一点很重要。另一个重要指标是存储密度,即总群集存储容量除以群集中的数据节点数。一般来说,你有两种选择:要么部署大量存储密度低的服务器,要么使用更少的存储密度更高的服务器。我们将回顾这两种选择,并概述每种选择的利弊。

低存储密度集群

历史上,Hadoop 集群部署在合理的低存储密度服务器上。这允许使用当时市场上可用的低容量硬盘将集群扩展到千兆字节的存储容量。虽然硬盘容量在过去几年中显著增加,但使用大型低密度群集对许多人来说仍然是一个有效的选择。成本是你想走这条路的主要原因。单个 Hadoop 节点的性能不仅取决于存储容量,还取决于内存/中央处理器和磁盘之间的平衡。在大多数情况下,在每个数据节点上都有大量存储,但没有足够的内存和 CPU 资源来处理所有数据是没有好处的。

很难给出关于 Hadoop 集群硬件的具体建议。平衡的设置将取决于集群工作负载以及分配的预算。新硬件一直在市场上出现,所以任何考虑都应该相应调整。为了说明低密度集群的硬件选择逻辑,我们将使用以下示例:

假设我们选择了一台带有 6 个硬盘插槽的服务器。如果我们选择价格合理的 2 TB 硬盘,它将为我们提供每台服务器 12 TB 的原始容量。

几乎没有理由为集群选择更快的 15000 rpm 驱动器。对于 Hadoop 集群来说,顺序读/写性能比随机访问速度更重要。在大多数情况下,7200 rpm 驱动器是首选。

对于低密度服务器,我们的主要目标是保持低成本,以便能够负担大量的机器。2×4 核心 CPU 符合这一要求,将提供合理的处理能力。每个映射或缩减任务将使用一个中央处理器内核,但是由于一些时间将花费在等待输入输出上,超额订阅中央处理器内核是可以的。有了 8 个可用内核,我们可以为每个节点配置大约 12 个映射/缩减插槽。

每项任务都需要 2 到 4 GB 的内存。对于这种类型的服务器,36 GB 的内存是一个合理的选择,但是 48 GB 是理想的选择。请注意,我们正在尝试平衡不同的组件。对于这种配置来说,大幅增加内存量没有多大用处,因为您将无法在一个节点上安排足够的任务来正确利用它。

假设您计划在集群中存储 500 TB 的数据。使用3的默认复制因子,这将导致 1500 TB 的原始容量。如果您使用低密度数据节点配置,您将需要 63 台服务器来满足这一要求。如果将所需容量增加一倍,您的群集中需要 100 多台服务器。管理大量服务器本身就有很多挑战。您需要考虑您的数据中心是否有足够的物理空间来容纳额外的机架。随着服务器数量的增长,额外的功耗和空调也带来了巨大的挑战。为了解决这些问题,您可以增加单个服务器的存储容量,以及调整其他硬件规格。

高存储密度集群

许多公司正在寻求构建更小的 Hadoop 集群,但每台服务器的存储和计算能力更强。除了解决上面提到的问题,这样的集群可以更好地适应大容量存储不是优先考虑的工作负载。这样的工作负载是计算密集型的,包括机器学习、探索性分析和其他问题。

为高密度集群选择和平衡硬件组件背后的逻辑与低密度集群相同。作为这种配置的一个示例,我们将选择具有 16 x 2 TB 硬盘或 24 x 1 TB 硬盘的服务器。每台服务器拥有更多容量较低的磁盘更好,因为这将提供更好的 IO 吞吐量和更好的容错能力。为了提高单台机器的计算能力,我们将使用 16 个中央处理器内核和 96 GB 内存。

名称节点和作业跟踪器硬件配置

Hadoop 实现了一个集中式协调模型,其中有一个节点(或一组节点),其角色是协调组成集群的服务器之间的任务。负责 HDFS 协调的服务器称为名称节点,负责 MapReduce 作业调度的服务器称为作业跟踪器。实际上,NameNode 和 JobTracker 只是独立的 Hadoop 进程,但由于它们在几乎所有情况下的关键作用,这些服务都在专用机器上运行。

命名节点硬件

名称节点对于 HDFS 的可用性至关重要。它存储所有文件系统元数据:哪些块包含哪些文件,这些块可以在哪些数据节点上找到,有多少空闲块可用,以及哪些服务器可以托管它们。没有 NameNode,HDFS 的数据几乎完全没用。数据实际上仍然存在,但是没有名称节点,您将无法从数据块重建文件,也无法上传新数据。很长一段时间以来,NameNode 都是单点故障,这对于一个宣扬大多数组件和进程具有高容错性和冗余性的系统来说并不理想。在 Apache Hadoop 2.0.0 中引入名称节点高可用性设置解决了这个问题,但是名称节点的硬件要求仍然与上一节中概述的数据节点有很大不同。让我们从名称节点的内存估计开始。名称节点必须在内存中存储所有 HDFS 元数据信息,包括文件、目录结构和块分配。这听起来像是对内存的浪费,但是 NameNode 必须保证能够快速访问成百上千台机器上的文件,所以使用硬盘来访问这些信息太慢了。根据 Apache Hadoop 文档,每个 HDFS 块将占用名称节点上大约 250 字节的内存,另外每个文件和目录还需要 250 字节的内存。假设您有 5000 个文件,每个文件平均 20 GB。如果您使用 64 MB 的默认 HDFS 块文件大小和的复制因子3,您的名称节点将需要保存大约 5000 万个块的信息,这将需要 5000 万 x 250 字节加上等于 1.5 GB 内存的文件系统开销。这并没有您想象的那么多,但是在大多数情况下,Hadoop 集群总共有更多的文件,并且由于每个文件至少由一个块组成,因此 NameNode 上的内存使用量会高得多。名称节点上的内存超过集群目前的需求不会带来任何损失,因此过度配置是可以的。内存为 64-96 GB 的系统是命名节点服务器的好选择。

为了保证文件系统元数据的持久性,NameNode 还必须在磁盘上保留其内存结构的副本。为此,NameNode 维护一个名为editlog的文件,该文件捕获 HDFS 发生的所有更改,例如新文件和目录的创建以及复制因子的更改。这与大多数关系数据库使用的重做日志文件非常相似。除了editlog之外,名称节点在fsimage文件中维护当前 HDFS 元数据状态的完整快照。在重启或服务器崩溃的情况下,名称节点将使用最新的fsimage并应用editlog文件中需要应用的所有更改,以恢复文件系统的有效时间点状态。

与传统的数据库系统不同,名称节点将定期将从editlogfsimage的更改应用到一个名为辅助名称节点的独立服务器的任务。这样做是为了控制editlog文件的大小,因为日志文件中不再需要已经应用于fsimage的更改,同时也是为了最大限度地减少恢复时间。由于这些文件是 NameNode 保存在内存中的镜像数据结构,因此对它们的磁盘空间要求通常很低。fsimage不会增长到超过您为名称节点分配的内存量,editlog将在默认情况下达到 64 MB 后旋转。这意味着您可以将名称节点的磁盘空间要求保持在 500 GB 范围内。在命名节点上使用 RAID 很有意义,因为它可以保护关键数据免受单个磁盘崩溃的影响。除了服务来自 HDFS 客户端的文件系统请求,名称节点还必须处理来自集群中所有数据节点的心跳消息。这种类型的工作负载需要大量的 CPU 资源,因此根据计划的集群大小,为名称节点调配 8-16 个 CPU 内核是一个好主意。

在本书中,我们将重点设置名称节点 HA,这将要求主名称节点和备用名称节点在硬件方面相同。关于如何实现名称节点高可用性的更多细节将在第 2 章安装和配置 Hadoop 中提供。

作业跟踪器硬件

除了名称节点和辅助名称节点,在 Hadoop 集群中还有另一个主服务器,称为作业跟踪器。从概念上讲,它在 MapReduce 框架中扮演着与 HDFS 的 NameNode 相似的角色。作业跟踪器负责向任务跟踪器提交用户作业,任务跟踪器是运行在每个数据节点上的服务。任务跟踪器定期向作业跟踪器发送心跳消息,报告正在运行的作业的当前状态、可用的映射/缩减插槽等。此外,作业跟踪器在内存中保存最后执行的作业的历史记录(数量可配置),并提供对与作业相关联的特定于 Hadoop 或用户定义的计数器的访问。虽然内存可用性对作业跟踪器至关重要,但它的内存占用通常小于名称节点。中型和大型集群拥有 24-48 GB 内存是一个合理的估计。如果您的集群是一个拥有数千用户的多租户环境,您可以查看此数字。默认情况下,JobTracker 不会将任何状态信息保存到磁盘,并且仅出于日志记录的目的使用永久存储。这意味着此服务的总磁盘需求极低。就像名称节点一样,作业跟踪器需要能够处理来自任务跟踪器的大量心跳信息,接受和调度传入的用户作业,并应用作业调度算法,以便能够最有效地利用集群。这些都是高 CPU 密集型任务,因此请确保您投资于快速多核处理器,类似于您将为 NameNode 购买的处理器。

所有三种类型的主节点对于 Hadoop 集群的可用性都至关重要。如果您失去了名称节点服务器,您将无法访问 HDFS 数据。辅助名称节点的问题不会导致立即停机,但会延迟文件系统检查点进程。同样,作业跟踪器的崩溃将导致所有正在运行的 MapReduce 作业中止,并且没有新作业能够运行。所有这些结果都要求对主机的硬件选择采取与我们讨论的数据节点不同的方法。将 RAID 阵列用于关键数据卷、冗余网络和电源以及可能更高级别的企业级硬件组件是首选。

网关等辅助服务

网关服务器是客户端对 Hadoop 集群的访问点。在 HDFS 与数据交互需要客户端程序和集群内的所有节点之间的连接。从网络设计和安全角度来看,这并不总是切实可行的。网关通常部署在主群集子网之外,用于数据导入和其他用户程序。额外的基础架构组件和不同的外壳可以部署在独立的服务器上,也可以与其他服务结合使用。硬件对这些可选服务的要求显然比集群节点的要求低得多,通常您可以在虚拟机上部署网关。对于网关节点来说,4-8 个 CPU 内核和 16-24 GB 内存是合理的配置。

网络注意事项

在 Hadoop 集群中,网络是与 CPU、磁盘或 RAM 同等重要的组件。HDFS 依靠网络通信来更新当前文件系统状态的名称节点,以及接收和发送数据块到客户端。MapReduce 作业还使用网络来发送状态消息,但是当必须从当前 TaskTracker 不本地的数据节点读取文件块时,它还会使用带宽,并将中间数据从 mappers 发送到 Reduce。简而言之,Hadoop 集群中存在大量网络活动。到目前为止,网络硬件主要有两种选择。1gb 网络很便宜,但吞吐量相当有限,而 10gb 网络会显著增加大型 Hadoop 部署的成本。与集群的其他组件一样,网络选择将取决于预期的集群布局。

对于更大的集群,我们提出了通常规格更低的机器,每个节点具有更少的磁盘、内存和中央处理器,假设大量这样的服务器将提供足够的容量。对于较小的集群,我们选择了高端服务器。在选择应用哪种网络架构时,我们可以使用相同的论点。

对于具有多个功能较弱的节点的集群,安装 10 GbE 没有什么意义,原因有二。首先,这将显著增加构建群集的总成本,并且您可能无法利用所有可用的网络容量。例如,每个数据节点有六个磁盘,您应该能够实现大约 420 兆字节/秒的本地写入吞吐量,这小于网络带宽。这意味着集群瓶颈将从网络转移到磁盘的 IO 容量。另一方面,拥有大量存储空间的小型快速服务器集群很可能会被 1gb 网络阻塞,服务器的大部分可用资源将被浪费。由于此类集群通常较小,10 GbE 网络硬件对预算的影响不会像更大的设置那样大。

类型

大多数现代服务器都带有几个网络控制器。您可以使用绑定来提高网络吞吐量。

Hadoop 硬件总结

让我们总结一下不同类型集群可能需要的 Hadoop 硬件配置。

低存储密度集群的数据节点:

|

成分

|

规格

|
| --- | --- |
| 储存;储备 | 每台服务器 6-8 个 2 TB 硬盘,JBOD 设置,无 RAID |
| 中央处理器 | 8 个彩色 CPU |
| 随机存取存储 | 每个节点 32-48 GB |
| 网络 | 1gb 接口,可以绑定多个网卡以获得更高的吞吐量 |

高存储密度集群的数据节点

|

成分

|

规格

|
| --- | --- |
| 储存;储备 | 每台服务器 16-24 个 1 TB 硬盘,JBOD 设置,无 RAID |
| 中央处理器 | 16 个彩色 CPU |
| 随机存取存储 | 每个节点 64-96 GB |
| 网络 | 10 GbE 网络接口 |

名称节点和备用名称节点

|

成分

|

规格

|
| --- | --- |
| 储存;储备 | 低磁盘空间要求:500 GB 在大多数情况下应该足够了。fsimageeditlog的 RAID 10 或 RAID 5。放置这些文件副本的网络连接存储 |
| 中央处理器 | 8-16 个 CPU 内核,具体取决于集群大小 |
| 随机存取存储 | 64-96 GB |
| 网络 | 1 千兆以太网或 10 千兆以太网接口,可以绑定多个网卡以获得更高的吞吐量 |

工作跟踪者

|

成分

|

规格

|
| --- | --- |
| 储存;储备 | 低磁盘空间要求:对于日志文件和作业状态信息,500 GB 在大多数情况下应该足够了 |
| 中央处理器 | 8-16 个 CPU 内核,具体取决于集群大小 |
| 随机存取存储 | 64-96 GB。 |
| 网络 | 1gb 或 10gb 接口,多个网卡的绑定可以提高吞吐量 |

Hadoop 发行版

Hadoop 有许多不同的风格。有许多不同的版本和许多不同的发行版可以从许多公司获得。今天在这个领域有几个关键人物,我们将讨论他们提供了哪些选择。

Hadoop 版本

至少可以说,Hadoop 发布版本控制系统令人困惑。有几个分支有不同的稳定版本,了解每个分支提供(或排除)哪些功能非常重要。到目前为止,这些是以下可用的 Hadoop 版本:0.23、1.0 和 2.0。令人惊讶的是,较高版本并不总是包含较低版本的所有功能。例如,0.23 包括名称节点高可用性和名称节点联盟,但放弃了对传统地图简化框架(MRv1)的支持,转而支持新的 Yarn 框架(MRv2)。

MRv2 在 API 级别上与 MRv1 兼容,但是守护进程的设置和配置以及概念是不同的。1.0 版本仍然包含 MRv1,但缺少 NameNode HA 和联合功能,许多人认为这些功能对于生产使用至关重要。2.0 版本实际上是基于 0.23 的,具有相同的功能集,但将用于未来的开发和发布。Hadoop 发布的版本似乎没有遵循简单的逻辑的原因之一是,Hadoop 仍然是一种相对较新的技术,一些用户非常希望的许多功能可能会引入不稳定性,有时它们需要重大的代码更改和方法更改,例如在 Yarn 的情况下。这导致许多不同的代码分支,具有不同的稳定发布版本,并给最终用户带来许多困惑。由于本书的目的是指导您规划和实施生产 Hadoop 集群,因此我们将重点关注稳定的 Hadoop 版本,这些版本提供了经验证的解决方案,如 MRv1,但也将包括 NameNode 的重要可用性功能。如您所见,这将立即缩小 Hadoop 版本的选择范围。

选择 Hadoop 分布

Apache Hadoop 不是唯一可用的发行版。还有其他几家公司维护自己的项目分支,既有免费的,也有专有的。您可能已经开始明白为什么这样做是有意义的:简化 Hadoop 的发布过程,并结合几个 Hadoop 分支的不同特性,使最终用户更容易实现集群。Hadoop 最受欢迎的非 Apache 发行版之一是 Cloudera Hadoop 发行版CDH

Cloudera Hadoop 发行版

Cloudera 是为 Hadoop 提供商业支持、专业服务和高级工具的公司。他们的 CDH 发行版是免费的,并且在相同的 Apache 2.0 许可下是开源的。CDH 吸引最终用户的地方在于它的代码分支更少,版本号一致,关键的错误修复被回溯到旧版本。目前,CDH 最新的主要版本是 CDH4,它结合了 Apache 2.0 和 1.0 版本的功能。它包括名称节点高可用性和联盟,支持 MRv1 和 MRv2,目前没有一个 Apache 版本支持。CDH 提供的另一个有价值的特性是集成不同的 Hadoop 生态系统项目。HDFS 和 MapReduce 是 Hadoop 的核心组件,但随着时间的推移,许多新项目都建立在这些组件之上。这些项目使 Hadoop 更加用户友好,加快开发周期,轻松构建多层 MapReduce 作业,等等。

在 CDH 获得大量关注的项目之一是 Impala,它允许在 Hadoop 上运行实时查询,完全绕过 MapReduce 层,直接从 HDFS 访问数据。拥有几十个生态系统组件,每个组件都有自己的兼容性要求和各种 Apache Hadoop 分支,并不能使集成成为一项轻松的任务。CDH 通过提供核心 Hadoop 和大多数流行的生态系统项目来为您解决这个问题,这些项目在一个发行版中相互兼容并经过测试。这对用户来说是一个很大的优势,它使 CDH 成为目前最受欢迎的 Hadoop 发行版(根据谷歌趋势)。除了 CDH,Cloudera 还分发 Cloudera Manager—一种基于网络的管理工具,用于调配、配置和监控您的 Hadoop 集群。Cloudera Manager 有免费和付费企业版。

Hortonworks Hadoop 发行版

另一个流行的 Hadoop 发行版是霍顿工程公司的霍顿工程数据平台(HDP)。与 Cloudera 类似,Hortonworks 提供了核心和生态系统 Hadoop 项目的预打包分发,以及对其的商业支持和服务。截至目前,HDP 1.2 和 2.0 的最新稳定版本处于 Alpha 阶段;两者都相应地基于 Apache Hadoop 1.0 和 2.0。HDP 1.2 提供了 CDH 或 Apache 发行版中没有的几个功能。Hortonworks 在 Hadoop 1.0 上实现了 NameNode HA,这不是通过从 Apache Hadoop 2.0 中向后移植 JournalNodes 和基于 Quorum 的存储,而是通过基于 Linux HA 解决方案实现冷集群故障转移。HDP 还包括 HCatalog——一种为像 Pig 和 Hive 这样的项目提供集成点的服务。Hortonworks 押注于将 Hadoop 与传统商业智能工具相集成,这是一个现有和潜在 Hadoop 用户非常感兴趣的领域。HDP 包括一个用于 Hive 的 ODBC 驱动程序,据称它与大多数现有的 BI 工具兼容。另一个独特的 HDP 特色是其在视窗平台上的可用性。将 Hadoop 引入视窗世界将对平台的采用率产生巨大影响,并可能使 HDP 成为该操作系统的领先发行版,但不幸的是,这仍处于 alpha 版本,目前无法推荐用于生产。说到集群管理和监控,HDP 包括 Apache Ambari,这是一个基于网络的工具,类似于 Cloudera Manager,但它是 100%免费和开源的,不区分免费和企业版本。

MapR

虽然 Cloudera 和 Hortonworks 提供了最受欢迎的 Hadoop 发行版,但它们并不是唯一使用 Hadoop 作为产品基础的公司。这里应该提到几个项目。MapR 是一家提供基于 Hadoop 的平台的公司。他们的产品有几个不同的版本:M3 是免费版,功能有限,M5 和 M7 是企业级商业版。MapR 采用了与 Cloudera 或 Hortonworks 不同的方法。他们的软件不是免费的,但是有一些吸引企业用户的功能。MapR 平台与 Apache Hadoop 的主要区别在于,使用了一个名为 MapR-FS 的不同专有文件系统来代替 HDFS。MapR-FS 是用 C++实现的,比基于 Java 的 HDFS 提供了更低的延迟和更高的并发访问。它在 API 级别上与 Hadoop 兼容,但它是一个完全不同的实现。其他 MapR-FS 功能包括将 Hadoop 集群装载为 NFS 卷的能力、集群范围的快照和集群镜像。显然,所有这些特性都依赖于 MapR-FS 实现。

如您所见,现代 Hadoop 环境远非一帆风顺。有很多选择。当您考虑生产集群的需求时,很容易缩小可用选项的列表。生产 Hadoop 版本需要稳定且经过良好测试。它需要包括重要的组件,比如 NameNode HA 和经过验证的 MRv1 框架。对于您来说,作为一名 Hadoop 管理员,能够在多个节点上轻松安装 Hadoop 非常重要,而无需精心挑选所需组件和担心兼容性。这些要求会很快让你注意到像 CDH 或 HDP 这样的发行版。这本书的其余部分将集中在 CDH 发行,因为它是目前最受欢迎的生产装置的选择。CDH 还提供了丰富的功能集和良好的稳定性。值得一提的是,Hadoop 2 在本书进行期间获得了第一个 GA 版本。Hadoop 2 引入了许多新功能,如名称节点高可用性,这些功能以前只在 CDH 提供。

为 Hadoop 集群选择操作系统

为您未来的 Hadoop 集群选择操作系统是一项相对简单的任务。除了少数例外,Hadoop 核心及其生态系统组件都是用 Java 编写的。虽然 Java 代码本身是跨平台的,但目前 Hadoop 只在类似 Linux 的系统上运行。其原因是,太多的设计决策都是在考虑 Linux 的情况下做出的,这使得围绕核心 Hadoop 组件(如start/stop脚本和权限模型)的代码依赖于 Linux 环境。

说到 Linux,Hadoop 对具体的实现相当漠不关心,并且在这种操作系统的不同变种上运行良好:红帽、CentOS、Debian、Ubuntu、Suse 和 Fedora。所有这些发行版都没有运行 Hadoop 的具体要求。一般来说,如果您确保所有依赖关系都得到正确解决,并且所有外壳支持脚本都在工作,那么没有什么可以阻止 Hadoop 在任何其他 POSIX 风格的操作系统上成功工作,例如 Solaris 或 BSD。尽管如此,Hadoop 的大多数生产安装都是在 Linux 上运行的,这是我们在进一步讨论中将重点关注的操作系统。具体来说,本书中的例子将集中在 CentOS 上,因为它是生产系统的流行选择之一,还有它的孪生兄弟红帽。

Apache Hadoop 提供了源代码二进制文件,以及 RPMDEB 包,用于稳定发布。目前,这是一个 1.0 分支。从源代码构建 Hadoop 虽然仍然是一种选择,但不建议大多数用户使用,因为它需要有组装大型基于 Java 的项目的经验和仔细的依赖项解析。Cloudera 和 Hortonworks 发行版都提供了一种在服务器上设置存储库并从中安装所有必需包的简单方法。

类型

没有严格要求在所有 Hadoop 节点上运行相同的操作系统,但常识表明,节点配置的偏差越小,管理和管理就越容易。

总结

构建生产 Hadoop 集群是一项复杂的任务,涉及许多步骤。规划集群时经常被忽略的一个步骤是概述未来集群将处理什么样的工作负载。正如您在本章中所看到的,了解您正在构建的集群类型对于正确调整规模和选择正确的硬件配置非常重要。Hadoop 最初是为商品硬件设计的,但现在它正被那些用例不同于雅虎这样的网络巨头的公司所采用!和脸书。这些公司有不同的目标和资源,应该相应地规划他们的 Hadoop 集群。构建具有更强大节点的较小集群来节省数据中心的空间并控制功耗并不罕见。

Hadoop 一直在不断发展,不断添加新功能,新的重要生态系统项目不断涌现。通常,这些变化会影响核心 Hadoop 组件,新版本可能并不总是与旧版本兼容。有几种 Hadoop 发行版可供最终用户选择,它们都提供了组件之间的良好集成,甚至还提供了一些附加功能。选择最新和功能最丰富的 Hadoop 版本通常很有诱惑力,但从可靠性的角度来看,最好选择经历了一些生产老化时间并且足够稳定的版本。这将使你免于不愉快的惊喜。在下一章中,我们将深入了解关于安装和配置核心 Hadoop 组件的细节。卷起你的袖子,准备弄脏你的手!

二、安装和配置 Hadoop

在您决定了集群布局和规模之后,是时候安装 Hadoop 并让集群开始运行了。我们将引导您完成三个核心 Hadoop 组件的安装和配置步骤:名称节点、数据节点和作业跟踪器。我们还将回顾配置名称节点高可用性的不同选项,以及快速评估集群运行状况和性能的方法。到本章结束时,您应该已经启动并运行了您的 Hadoop 集群。我们将保持集群的结构类似于第 1 章中概述的设置 Hadoop 集群-从硬件到分发

为 Hadoop 集群配置操作系统

如前所述, Hadoop 几乎可以在任何现代风格的 Linux 上运行。本节和后续章节中的说明将集中在 CentOS 6.x 上,CentOS 和红帽是与生产相关的 Hadoop 安装中最受欢迎的选择。对于 Debian 来说,采用这些指令应该不会太难,因为所有与配置 Hadoop 组件直接相关的东西都将保持不变,并且您应该能够轻松地用包管理器替换您最喜欢的发行版。

选择和设置文件系统

现代 Linux 发行版支持不同的文件系统:EXT3、EXT4、 XFS、BTRFS 等等。这些文件系统在某些工作负载上的性能具有稍微不同的特点。

如果您更喜欢稳定性而不是性能和高级功能,您可能想使用 EXT3,它在一些最大的 Hadoop 集群上经过了战斗测试。完整的名单可以在http://wiki.apache.org/hadoop/DiskSetup看到。我们将使用 EXT4 进行我们的集群设置,因为它在大文件上提供了更好的性能,这使得它成为 Hadoop 的一个很好的候选。

要使用 EXT4 文件系统格式化卷,请在 shell 中以 root 用户身份运行以下命令:

# mkfs –t ext4 –m 0 –O extent,sparse_super,flex_bg /dev/sdb1

在本例中,驱动器 b 上的分区 1 将被格式化。format 命令中有几个选项需要解释。

  • -m 0:该选项将为超级用户预留的空间从默认值 5%减少到的 0%。这可以在大型文件系统上节省大量磁盘空间。如果每台服务器有 16 TB,您将节省大约 800 GB。
  • -O extent,sparse_super,flex_bg : 此选项将启用基于范围的分配,这将提高大型顺序 IO 请求的性能。 sparse_super选项是另一个节省磁盘空间的选项。您可以通过分配更少的超级块备份副本来节省大型文件系统的空间。flex_bg选项强制文件系统将元数据块打包在一起,提供了一些性能改进。

挂载文件系统时,您需要了解几个重要的选项。那就是noatimenoadirtime。默认情况下,文件系统会通过更新元数据时间戳字段来跟踪所有操作,包括读取文件或访问目录。这可能会给繁忙的系统带来巨大的开销,应该禁用。以下是如何在/etc/fstab中禁用此功能的示例:

/dev/sda1 /disk1 ext4 noatime,noadirtime 1 2
/dev/sdb1 /disk2 ext4 noatime,noadirtime 1 2

请记住,这些磁盘配置选项仅适用于数据节点数据磁盘。建议为命名节点卷配置 RAID。RAID 配置特定于您的控制器制造商。

设置 Java 开发工具包

由于 Hadoop 是用 Java 编写的,您需要确保在所有 Hadoop 节点上都安装了正确版本的 JDK。确保 JDK 的版本和发行版在所有节点上都是相同的,这一点至关重要。目前,唯一官方支持的 JVM 发行版是 Oracle JVM。有报道称,Hadoop 可以在 OpenJDK 上构建并运行良好,但我们将坚持使用甲骨文 JDK。在写这本书的时候,Hadoop 被测试在 Java Version 6 上工作,而目前的 Oracle Java 版本是 7,Java 6 实际上在 2013 年 2 月就到了生命的尽头。你可以看到 Hadoop 在 http://wiki.apache.org/hadoop/HadoopJavaVersions T4 测试过的所有 Java 版本的列表。CentOS 的存储库中不包含 Oracle JDK,所以需要单独下载安装。从http://www . Oracle . com/tech network/Java/javase/downloads/JDK 6 downloads-1902814 . html(或谷歌Oracle Java 6 download如果链接发生变化)。选择最新的 6.x 版本是可以的,因为经常会发布新的更新和安全补丁。确保进行 rpm 安装。我们将使用 Cloudera 的发行版,包括 Apache Hadoop ( CDH )包,在更多依赖 Oracle Java rpms 的部分安装 Hadoop。以下是如何安装 64 位 Oracle Java 1 . 6 . 0 _ 45 版:

# chmod 755 jdk-6u45-linux-x64-rpm.bin
# ./jdk-6u45-linux-x64-rpm.bin

确保在所有 Hadoop 节点上重复此步骤,包括网关服务器。

其他操作系统设置

为了确保 Hadoop 集群的正常运行,您需要更改其他几个操作系统设置。首先,您需要确保主机名/IP 解析在整个集群中正常工作。当 Hadoop 主节点(如名称节点或作业跟踪器)第一次从新的数据节点接收心跳消息时,它们会记录其 IP 地址,并将其用于进一步的通信。因此,为集群中的所有节点配置正确的主机名,并确保它们使用/etc/hosts文件解析为正确的 IP 地址是非常重要的。要确保主机报告正确的 IP 地址,请使用ping命令并检查返回的 IP 地址。以下是/etc/hosts的一个例子:

127.0.0.1   localhost.localdomain localhost
::1         localhost.localdomain localhost
192.168.0.100 nn1.hadoop.test.com nn1
192.168.0.101 sn1.hadoop.test.com sn1
192.168.0.102 jt1.hadoop.test.com jt1
192.168.0.40  dn1.hadoop.test.com dn1
192.168.0.41  dn2.hadoop.test.com dn2

类型

给集群中的节点起一个有意义的名字是一个很好的做法,这样名字就反映了主机所扮演的角色。这种方法可以很容易地用脚本生成主机/IP 列表,并在所有服务器上传播。

建立 CDH 存储库

安装 Hadoop 的方法有很多,具体要看你选择哪个发行版。即使在一个配送中心内,您也可以选择不同的路线。 CDH 提供了在集群上安装 Hadoop 软件包的各种辅助模式:您可以使用 Cloudera Manager web 界面来执行集群中节点的自动发现,并为您安装和预配置合适的软件包,或者您可以设置 CDH 存储库并手动安装组件。在本书中,我们将继续手动安装,因为这将有助于更好地理解 Hadoop 机制以及不同组件之间的交互方式。我们仍将使用 百胜包管理实用程序来处理在正确位置复制文件、设置服务等工作。这将允许我们更加关注组件的配置。

您需要做的第一件事,就是添加一个新的 yum 存储库。您需要的存储库取决于您的操作系统版本,完整列表可在http://www . cloudera . com/content/cloudera-content/cloudera-docs/CDH 4/latest/CDH 4-安装指南/cdh4ig_topic_4_4.html 上找到。本书中的所有示例都将使用最新的可用版本,即 CentOS 6 64 位上的 CDH 4.2。请务必相应地调整说明,因为当您阅读这本书时,可能会有更新的 CDH 版本。要添加存储库,请下载此文件http://archive . cloudera . com/CDH 4/red hat/6/x86 _ 64/CDH/cloudera-CDH 4 . repo并将其放入服务器上的/etc/yum.repos.d/:

您还需要添加一个存储库 GPG 密钥:

# rpm --import http://archive.cloudera.com/cdh4/redhat/6/x86_64/cdh/RPM-GPG-KEY-cloudera

完成后,您可以通过运行以下命令来检查有哪些 Hadoop 包可用:

# yum search Hadoop

设置名称节点

在本节中,我们将逐步安装和配置名称节点服务,包括高可用性(高可用性)设置。与许多其他在线指南和教程不同,它们将名称节点的高可用性设置视为一个高级主题,我们将从一开始就专注于设置名称节点的高可用性。其原因是名称节点在 Hadoop 设置中扮演的关键角色。基本上,名称节点是 Hadoop 集群的单点故障。没有这项服务,就无法访问 Hadoop 分布式文件系统( HDFS )上的文件。

有几种方法可以设置名称节点高可用性。在 CDH 4.1 之前,高可用性可以使用共享存储设置来实施。在这种情况下,主名称节点将文件系统元数据更改写入位于共享网络存储上的编辑日志中,辅助名称节点从编辑日志中轮询更改,并将其应用到自己的元数据快照副本中。此外,所有数据节点都用当前块的位置信息更新了两个名称节点,因此在主名称节点出现故障的情况下,辅助名称节点可以接管主角色。

在 CDH 版本 4 之前,辅助名称节点不执行备用功能。它唯一的作用是执行检查点操作。在高可用性实施中,备用名称节点同时执行高可用性和检查点功能。您可以将备用名称节点视为辅助名称节点+热备盘。

这种设置并不理想。它需要额外的硬件,而这些硬件又需要易于获得。在 CDH 4.1 中,发布了一个易于获得的名称节点设置的新版本,它依赖于分布式服务来同步两个数据节点,并且消除了对共享网络存储的需求。这个设置叫做法定日志管理器,它引入了几个新的组件。有两个命名节点:主节点和备用节点。这与前面的设置类似,但是主名称节点不是将编辑日志写入共享网络文件,而是将它们写入 日志节点的集群。日志节点是 CDH 4.1 中引入的一种新型守护进程。日志节点背后的思想是,主名称节点将编辑日志更改提交给一组日志节点,这些节点将它们存储在本地磁盘上。如果大多数日志节点能够将其保存在磁盘上,则写入被视为成功。这消除了共享存储需求,但仍然保证了 editlog 写入的持久性,并且没有单点故障。关于日志节点的一个很好的事情是它们的操作是轻量级的,你不需要在单独的硬件上运行它们。

通常的做法是运行三个日志节点(奇数保证适当的仲裁)。其中两个可以在与名称节点相同的服务器上运行,一个可以在作业跟踪器上运行。这不是强制要求,您可以在您选择的群集中的任何服务器上运行日志节点。对于我们的设置,我们将选择这个选项。

备用名称节点从一群日志节点中轮询一个编辑日志,并将它们应用于它所拥有的文件系统映像的副本。备用名称节点仍然执行校验和功能,并将更新后的 fsimage 文件发送回主名称节点。此外,数据节点被配置为向两个节点发送带有数据块分配信息的心跳。在主名称节点出现故障的情况下,辅助名称节点可以无缝接管 HDFS 操作。

为了使整个跨节点协调成为可能,名称节点依靠动物园管理员来跟踪哪个名称节点是主节点,哪个是备用节点,以防止两个节点都决定它们是主节点并开始将编辑日志写入日志节点的情况。动物园管理员是另一个 Apache 项目,是 CDH 的一部分。它提供分布式协调服务,并且在许多不同的节点需要共享状态、锁定信息或任何其他数据信息时非常有用。你可以在http://zookeeper.apache.org找到更多关于动物园管理员的信息。名称节点高可用性难题的最后一块是动物园管理员故障转移控制器。ZKFC 是一个守护程序,它在主名称节点和备用名称节点上运行,检查它们的运行状况和状态,并在需要时启动到备用名称节点的故障转移。在处理名称节点故障时,集群管理员有两种选择:

  • 使用手动故障转移 从故障名称节点转移到备用名称节点。这是一个更简单的设置,但这意味着集群管理员必须仔细监控活动名称节点的运行状况,并在出现问题时快速启动故障转移步骤。
  • 配置自动故障转移 选项,该选项依赖 ZKFC 监控活动名称节点的状态。如果需要,ZKFC 将启动故障转移,并使用 ZooKeeper 集群作为状态同步点。

对于我们的设置,我们将选择自动名称节点故障转移选项。

如您所见,名称节点高可用性设置中添加了许多移动部件。下面是一个图表,它将帮助您可视化所有涉及的组件及其相互关系:

Setting up NameNode

名称带日志节点仲裁的节点高可用性设置图

以下各节中的所有示例都是在测试集群上执行的,其中设置并配置了以下节点:nn1.hadoop.test.com、nn2.hadoop.test.com 和 jt1.hadoop.test.com。名字应该是不言而喻:nn1 和 nn2 分别是主备 NameNodes,jt1 是 JobTracker。我将暂时省略数据节点,因为我们将在本章后面讨论它们。

类型

显然,大规模处理一组机器需要某种程度的普通任务自动化。在设置和配置集群时,需要不断重复的任务之一是在不同的机器上传播这些配置文件。Cloudera Manager 在配置管理方面可以提供很多帮助。您也可以使用工具,如木偶,厨师,或 Ansible。

我们将从在 nn1、nn2 和 jt1 上安装 NameNode 所需的包开始。我们在作业跟踪器服务器上安装 HDFS 包的原因是因为我们需要在那里运行一个日志节点。

除非另有说明,否则所有命令都将作为根用户执行。

您可以通过在 nn1、nn2 和 jt1 服务器上运行一个简单的 yum命令来实现:

# yum install hadoop-hdfs-namenode

这将安装几个依赖包。让我们快速看一下那些是什么。

  • bigtop-jsvcbigtop-utils :这些包是针对 Apache Bigtop 项目(http://bigtop.apache.org)这个项目是为了帮助简化 Hadoop 组件的开发和打包而创建的。它负责正确的环境设置,确保在不同的系统中正确检测到 JAVA_HOME,等等。一般来说,您不必担心这个问题,但需要知道它的存在,因为自 Bigtop 推出以来,一些配置文件的位置和用途已经发生了变化。
  • hadoop :这个包包含核心 hadoop 组件、配置文件和共享库。它将安装在所有群集节点上。
  • hadoop-hdfs :这个为 hdfs、NameNode、JournalNode、DataNode 提供配置文件,内置 web 服务器配置等等。
  • zookeeper :我们之前讨论过 ZooKeeper 在 NameNode HA 中的角色,但是它也被 HBase 柱状存储使用。

这里需要注意的一点是,随着 HDFS 软件包的设置,CDH 还将创建一个名为hdfs的新操作系统用户。所有守护进程都将以该用户身份执行。

日志节点、动物园管理员和故障转移控制器

下一步是在所有三个服务器上安装日志节点包:

# yum install hadoop-hdfs-journalnode

我们已经安装了 zookeeper 包作为 NameNode 依赖项的一部分,但是我们还需要安装脚本来启动/停止 ZooKeeper 服务器。在 nn1、nn2 和 jt1 上运行以下命令:

# yum install zookeeper-server

最后,我们需要安装故障转移控制器。这个守护进程只需要在主备命名节点上执行,所以我们在 nn1 和 nn2 上安装:

# yum install hadoop-hdfs-zkfc

在我们继续配置名称节点和其他组件之前,我们需要确保 ZooKeeper 集群已经启动并运行。在我们的例子中,我们在 nn1、nn2 和 jt1 上有三个 ZooKeeper 节点。动物园管理员配置文件zoo.cfg位于/etc/zookeeper/conf/,下面是我们的设置:

maxClientCnxns=50
# The number of milliseconds of each tick
tickTime=2000
# The number of ticks that the initial
# synchronization phase can take
initLimit=10
# The number of ticks that can pass between
# sending a request and getting an acknowledgement
syncLimit=5
# the directory where the snapshot is stored.
dataDir=/var/lib/zookeeper
# the port at which the clients will connect
clientPort=2181

server.1=nn1.hadoop.test.com:2888:3888
server.2=nn2.hadoop.test.com:2888:3888
server.3=jt1.hadoop.test.com:2888:3888

示例配置文件包含一些默认值,除非您正在进行一些高级调整,否则不需要进行任何更改。根据您的设置,您可能需要更改dataDir选项。需要添加到这个配置文件中的是您可以在前面的代码中看到的最后三行。这些行为 ZooKeeper 集群提供了一个配置。每个server字后面的数字是服务器标识,28883888分别是连接到动物园管理员和选举新领导的端口。我们现在不必关心这些细节,但是您需要做的一件事是仔细检查 ZooKeeper 节点上的这些端口是否打开,以及客户端端口 2181 是否可用于任何其他需要使用 ZooKeeper 的服务器,例如 HBase 节点。

配置文件更新后(别忘了在所有节点上更新!),您需要运行以下命令,该命令将创建并初始化数据目录:

# service zookeeper-server init --myid=1

我们已经安装了 zookeeper 包作为 NameNode 依赖项的一部分,但是我们还需要安装脚本来启动/停止 ZooKeeper 服务器。

在 nn1、nn2 和 jt1 上运行以下命令:

# yum install zookeeper-server

该命令需要在 nn1、nn2 和 jt1 上执行。它还将在所有三个节点上创建一个名为/var/lib/zookeeper/(位置取决于dataDir选项)的文件。该文件包含 ZooKeeper 节点的唯一服务器标识,这是您通过--myid选项提供的。因此,您需要在每台服务器上提供不同的--myid值。这是 ZooKeeper 守护进程了解集群中谁的一种方式。

要启动 ZooKeeper 服务,在所有三个节点上执行以下命令:

# service zookeeper-server start

确保您验证了默认情况下 ZooKeeper 在/var/log/zookeeper/zookeeper.log写入的日志文件的内容。有时,即使在失败的情况下,zookeeper-server start命令仍然返回成功,查看服务器是否已经正确启动的唯一方法是检查日志文件。

现在,我们准备继续进行名称节点配置。

Hadoop 配置文件

在我们深入了解名称节点守护程序配置的细节之前,需要说几句关于 Hadoop 配置文件的话。Hadoop 集群中涉及许多不同的守护程序,人们可能会期望它们都有自己的配置文件。事实上,核心 Hadoop 服务只需要使用几个配置文件。最初可能会很混乱,因为不同角色的选项在几个文件中混合在一起。

核心 Hadoop 组件有三个主要配置文件:core-site.xmlhdfs-site.xmlmapred-site.xmlcore-site.xml文件包含集群中所有服务器通用的配置选项。 hdfs-site.xmlmapred-site.xml文件分别为集群的 HDFS 和 MapReduce 组件提供配置。还有控制集群不同方面的其他配置文件,我们将很快了解这些文件。CDH 将这些配置文件放入/etc/hadoop/conf目录,该目录又是alternatives目录的符号链接。CDH 使用 Linux 替代项目来维护不同版本的配置和其他文件。我们不必担心确切的设置,因为它不会真正影响我们设置集群所需的步骤。

你可以在http://www.linuxalt.com了解更多关于 Linux 替代品的信息。

让我们看看我们的一个名称节点服务器 nn1 上的/etc/hadoop/conf中有哪些文件:

# ls –lh /etc/hadoop/conf
-rw-r--r--1 root root 1.2K May 21 05:40 core-site.xml
-rw-r--r--1 root root 1.8K Apr 22 19:36 hadoop-metrics2.properties
-rw-r--r--1 root root 2.5K Apr 22 19:36 hadoop-metrics.properties
-rw-r--r--1 root root 2.4K May 22 04:51 hdfs-site.xml
-rw-r--r--1 root root 8.6K Apr 22 19:36 log4j.properties
-rw-r--r--1 root root   10 Apr 22 19:36 slaves
-rw-r--r--1 root root 2.3K Apr 22 19:36 ssl-client.xml.example
-rw-r--r--1 root root 2.2K Apr 22 19:36 ssl-server.xml.example

可以看到core-site.xml``hdfs-site.xml到位,但是mapred-site.xml不见了。这是因为我们还没有在这台服务器上安装任何与 MapReduce 相关的软件包,比如 JobTracker 或 TaskTracker。

hadoop-metrics.propertieshadoop-metrics2.properties文件控制着 Hadoop 公开其内部指标的方式。这在配置集群监控时将变得重要,我们将在第 5 章监控 Hadoop 集群中更详细地讨论这些文件。

log4j.properties配置文件用于指定 Hadoop 日志记录工具的详细信息。它非常灵活,允许您指定保留和归档选项、日志详细级别,甚至日志格式。Hadoop 附带了一套很好的默认值,因此我们在此不会讨论所有可用的选项,但是如果默认值不符合您的需求,请随意浏览 Log4j 和 Hadoop 文档。

slaves文件是可选的,默认为空。您可以用数据节点列表填充它。该列表将由脚本使用,例如start-all.sh,它将启动集群中的所有守护程序。在 CDH,不建议使用这种启动服务的方法,而应该使用服务命令。

示例文件ssl-client.xml.examplessl-server.xml.example是示例配置文件,可用于为 MapReduce 设置加密混洗阶段。

除了/etc/hadoop/conf目录,还有一个位置需要注意。随着 Bigtop 项目的引入,一些设置被移动到/etc/default目录中的一组 shell 脚本中。这些脚本设置了不同服务使用的一些环境变量。以下是默认hadoop-hdfs-namenode脚本的示例(为了节省空间,去掉了标题):

export HADOOP_PID_DIR=/var/run/hadoop-hdfs
export HADOOP_LOG_DIR=/var/log/hadoop-hdfs
export HADOOP_NAMENODE_USER=hdfs
export HADOOP_SECONDARYNAMENODE_USER=hdfs
export HADOOP_DATANODE_USER=hdfs
export HADOOP_IDENT_STRING=hdfs
export HADOOP_NAMENODE_OPTS="-Xmx10g"
# export HADOOP_SECURE_DN_USER=hdfs
# export HADOOP_SECURE_DN_PID_DIR=/var/run/hadoop-hdfs
# export HADOOP_SECURE_DN_LOG_DIR=/var/log/hadoop-hdfsewew

如您所见,该文件指定了 PID 和日志文件的位置、将用于运行名称节点守护程序的操作系统用户以及其他选项。在大多数情况下,当您实现 CDH 软件包安装时,默认路径就足够了。不属于默认值的一个变量是HADOOP_NAMENODE_OPTS。此变量指定将用于启动名称节点守护程序的 JVM 选项列表。在这种情况下,NameNode JVM 将以 10 GB 的最大堆大小启动。您需要根据对您计划在 HDFS 存储的文件/数据块数量的估计来调整您的配置。有关名称节点内存要求的详细信息,请参考第 1 章设置 Hadoop 集群-从硬件到分发

名称节点高可用性配置

我们将通过向 core-site.xml文件添加几个选项来开始配置名称节点高可用性设置。以下是该特定步骤的文件结构。如果您不熟悉的话,它会让您了解 XML 结构。标题注释被剥离出来:

<?xml version="1.0"?>
<?xml-stylesheet type="text/xsl" href="configuration.xsl"?>
<configuration>
<property>
    <name>fs.default.name</name>
    <value>hdfs://sample-cluster/</value>
</property>
<property>
    <name>ha.zookeeper.quorum</name>
    <value>nn1.hadoop.test.com:2181,nn2.hadoop.test.com:2181,
       jt1.hadoop.test.com:2181
    </value>
</property>
</configuration>

配置文件格式几乎是不言自明的;变量被<property>标记包围,每个变量都有一个名称和值。

现阶段我们只需要增加两个变量。fs.default.name是 NameNode 集群的逻辑名称。值hdfs://sample-cluster/特定于高可用性设置。这是名称节点群集的逻辑名称。我们将在hdfs-site.xml文件中定义组成它的服务器。在非高可用性设置中,这个变量被分配了一个主机和一个名称节点端口,因为集群中只有一个名称节点。

ha.zookeeper.quorum 变量指定了动物园管理员服务器的位置和端口。ZooKeeper 集群可以被其他服务使用,比如 HBase,这就是为什么在core-site.xml中定义它的原因。

下一步是配置hdfs-site.xml文件,并在那里添加所有 HDFS 特有的参数。我将省略<property>标签,仅包含<name><value>,以使列表不那么冗长。

<name>dfs.name.dir</name>
<value>/dfs/nn/</value>

名称节点将使用dfs.name.dir变量指定的位置来存储 HDFS 元数据的持久快照。这是 fsimage 文件的存储位置。如前所述,该目录所在的卷需要由 RAID 支持。丢失此卷意味着名称节点完全丢失。/dfs/nn路径就是一个例子,但是你可以自由选择你自己的。您实际上可以用dfs.name.dir值指定几个路径,并用逗号分隔。名称节点将镜像每个指定目录中的元数据文件。如果您有可用的共享网络存储,您可以将其用作 HDFS 元数据的目标之一。这将提供额外的异地备份。

<name>dfs.nameservices</name>
<value>sample-cluster</value>

dfs.nameservices变量指定了 NameNode 集群的逻辑名称,应该用对你有意义的东西来代替,比如prod-cluster或者stage-clusterdfs.nameservices的值必须与core-site.xml文件中的fs.default.name的值相匹配。

<name>dfs.ha.namenodes.sample-cluster</name>
<value>nn1,nn2</value>

在这里,我们指定了组成高可用性集群设置的名称节点。这些是逻辑名称,不是真实的服务器主机名或 IP。这些逻辑名称将在其他配置变量中引用。

<name>dfs.namenode.rpc-address.sample-cluster.nn1</name>
<value>nn1.hadoop.test.com:8020</value>
<name>dfs.namenode.rpc-address.sample-cluster.nn2</name>
<value>nn2.hadoop.test.com:8020</value>

这对变量提供了从逻辑名称(如 nn1 和 nn2)到真实主机和端口值的映射。默认情况下,名称节点守护程序使用端口 8020 与客户端和彼此通信。确保此端口对群集节点开放。

<name>dfs.namenode.http-address.sample-cluster.nn1</name>
<value>nn1.hadoop.test.com:50070</value>

<name>dfs.namenode.http-address.sample-cluster.nn2</name>
<value>nn2.hadoop.test.com:50070</value>

每个名称节点守护程序运行一个内置的 HTTP 服务器,名称节点 web 界面将使用该服务器来公开有关 HDFS 操作的各种指标和状态信息。此外,备用名称节点使用 HTTP 调用定期从主服务器复制 fsimage 文件,执行检查点操作,并将其发送回来。

<name>dfs.namenode.shared.edits.dir</name>
<value>qjournal://nn1.hadoop.test.com:8485;nn2.hadoop.test.com:8485;jt1.hadoop.test.com:8485/sample-cluster</value>

dfs.namenode.shared.edits.dir变量指定了日志节点集群的设置。在我们的配置中,有三个运行在 nn1、nn2 和 nn3 上的日志节点。主节点和备用节点都将使用该变量来标识它们应该联系哪些主机来发送或接收来自 editlog 的新更改。

<name>dfs.journalnode.edits.dir</name>
<value>/dfs/journal</value>

日志节点需要保存活动名称节点提交给它们的编辑日志更改。dfs.journalnode.edits.dir变量指定本地文件系统上存储编辑日志更改的位置。请记住,该路径必须存在于所有日志节点上,并且所有目录的所有权必须设置为hdfs:hdfs(用户和组)。

<name>dfs.client.failover.proxy.provider.sample-cluster</name>
<value>org.apache.hadoop.hdfs.server.namenode.ha.ConfiguredFailoverProxyProvider</value>

在高可用性设置中,访问 HDFS 的客户端需要知道他们的请求应该联系哪个名称节点。dfs.client.failover.proxy.provider.sample-cluster变量指定 Java 类名,客户端将使用该类名来确定活动的名称节点。

目前只有ConfiguredFailoverProxyProvider可用。

<name>dfs.ha.automatic-failover.enabled</name>
<value>true</value>

dfs.ha.automatic-failover.enabled变量指示名称节点集群将使用手动还是自动故障转移。

<name>dfs.ha.fencing.methods</name>
<value>sshfence
       shell(/bin/true)
</value>

在群集设置中协调故障转移是一项复杂的任务,涉及多个步骤。一个常见的问题不是 Hadoop 集群独有的,而是影响任何分布式系统的,这就是“裂脑”场景。大脑分裂是指两个命名节点决定它们都扮演一个积极的角色,并开始向编辑日志写入更改。为了防止此类问题的发生, HA 配置在 ZooKeeper 中维护一个标记,清楚地说明哪个名称节点是活动的,并且日志节点只接受来自该节点的写入。为了绝对确保两个名称节点不会同时处于活动状态,在故障转移期间使用了一种称为隔离的技术。其思想是在将活动状态转移到备用状态之前强制关闭活动名称节点。

目前有两种击剑方式:sshfenceshellsshfence。这些需要作为启动名称节点守护程序的用户的无密码 ssh 访问,从活动的名称节点到备用节点,反之亦然。默认情况下,这是 hdfs 用户。隔离进程使用nc命令检查是否有人在名称节点端口上侦听,如果发现端口繁忙,它会尝试终止名称节点进程。dfs.ha.fencing.methods的另一个选择是贝壳。这将执行指定的 shell 脚本来执行隔离。重要的是要理解,如果隔离失败,故障转移将失败。在我们的例子中,我们指定了两个选项,第二个总是返回成功。这样做是为了解决以下情况:主 NameNode 计算机出现故障,ssh 方法将失败,并且不会执行故障切换。我们希望避免这种情况,所以第二种选择是无论如何都进行故障转移,即使没有隔离,正如已经提到的,这在我们的设置中是安全的。为了实现这一点,我们指定了两种剑术方法,ZKFC 将按照以下顺序尝试:如果第一种失败,将尝试第二种。在我们的例子中,第二个将总是返回成功,并且将启动故障转移,即使运行主名称节点的服务器通过 ssh 不可用。

<name>dfs.ha.fencing.ssh.private-key-files</name>
<value>/var/lib/hadoop-hdfs/.ssh/id_rsa</value>

我们需要为名称节点高可用性设置配置的最后一个选项是 ssh 密钥,它将由 sshfence 使用。请确保将此文件的所有权更改为 hdfs 用户。需要生成两个密钥,一个用于主名称节点,一个用于辅助名称节点。以 hdfs 用户的身份双向测试 ssh 访问是一个好主意,以确保它工作正常。

hdfs-site.xml配置文件现在已经全部设置好,用于测试高可用性设置。不要忘记将这些配置文件同步到群集中的所有节点。接下来需要做的是启动日志节点。在 nn1、nn2 和 jt1 a 根用户上执行此命令:

# service hadoop-hdfs-journalnode start

对于 CDH,建议始终使用服务命令,而不是直接调用/etc/init.d/中的脚本。这样做是为了保证在守护进程启动之前,所有环境变量都设置正确。始终检查守护程序的日志文件。

现在,我们需要初步格式化 HDFS。为此,请在 nn1 上运行以下命令:

# sudo -u hdfs hdfs namenode –format

这是 NameNode 的初始设置,因此我们不必担心会影响任何 HDFS 元数据,但是要小心这个命令,因为它会破坏任何以前的元数据项。在 nn1 上运行 format 命令没有严格的要求,但是为了更容易理解,让我们假设我们希望 nn1 成为一个活动的 NameNode。命令还将格式化日志节点的存储。

下一步是在 ZooKeeper 中为高可用性集群创建一个条目,并在第一个名称节点上启动名称节点和 ZKFC。在我们的例子中,这是 nn1:

# sudo -u hdfs hdfs zkfc -formatZK
# service hadoop-hdfs-namenode start
# service hadoop-hdfs-zkfc start

检查 ZKFC 日志文件(默认在/var/log/hadoop-hdfs/中),确保 nn1 现在是活动的名称节点:

INFO org.apache.hadoop.ha.ZKFailoverController: Trying to make NameNode at nn1.hadoop.test.com/192.168.0.100:8020 active...
INFO org.apache.hadoop.ha.ZKFailoverController: Successfully transitioned NameNode at nn1.hadoop.test.com/192.168.0.100:8020 to active state

要激活辅助名称节点,需要执行一个称为引导的操作。为此,请在 nn2 上执行以下命令:

# sudo -u hdfs hdfs namenode –bootstrapStandby

这将从活动名称节点中提取当前文件系统状态,并将辅助名称节点与日志节点仲裁同步。

现在,您已经准备好在 nn2 上启动名称节点守护程序和 ZKFC 守护程序。使用与 nn1 相同的命令。检查 ZKFC 日志文件,确保 nn2 成功获得辅助名称节点角色。您应该会在日志文件的末尾看到以下消息:

INFO org.apache.hadoop.ha.ZKFailoverController: ZK Election indicated that NameNode at nn2.hadoop.test.com/192.168.0.101:8020 should become standby
INFO org.apache.hadoop.ha.ZKFailoverController: Successfully transitioned NameNode at nn2.hadoop.test.com/192.168.0.101:8020 to standby state

这是配置名称节点高可用性的最后一步。最好验证自动故障切换是否配置正确,以及在主名称节点中断的情况下,它是否会像预期的那样运行。在群集设置阶段测试故障转移比发现故障转移在生产阶段不起作用并导致群集中断更容易、更安全。您可以执行一个简单的测试:终止主名称节点守护程序,并验证辅助名称节点是否接管其角色。之后,让旧的主要角色重新上线,并确保它接管次要角色。

您可以使用执行以下命令来获取名称节点 nn1 的当前状态:

# sudo -u hdfs hdfs haadmin -getServiceState nn1

在手动故障转移设置中,hdfs haadmin命令也可用于启动故障转移。

此时,您已经有了一个完全配置且功能正常的名称节点高可用性设置。

作业跟踪器配置

和 NameNode 一样,JobTracker 在 MapReduce 框架中扮演着主角色;它从集群中的 TaskTrackers 收集心跳消息,维护关于集群当前容量的信息,并负责调度、提交和跟踪用户定义的作业的进度。这是很多工作要做,在一个大型集群上,JobTracker 可能会变得非常繁忙;但是与 NameNode 不同,JobTracker 需要维护的关于正在运行的作业的状态信息要少得多,此外,在维护作业日志时,对持久存储的要求也很低。

长期以来,JobTracker 就像 NameNode 一样,是 Hadoop 集群中的单点故障。如果作业跟踪器进程失败,所有当前正在运行或计划的作业都将失败,必须重新启动。在 CDH 4.1 发布之前,用户有责任监控作业状态,并在作业跟踪器失败时重新提交。在 CDH 4.1 中,向高可用性迈出了第一步,并将作业持久性功能添加到了作业跟踪器中。现在,作业跟踪器可以自动重启在作业跟踪器崩溃或重启期间运行的所有作业。在 CDH 4.2 中,引入了作业跟踪器的高可用性设置。它允许配置活动和备用作业跟踪器,并在活动作业跟踪器失败时执行自动故障转移。配置作业跟踪器高可用性时,您需要注意的一点是,在故障切换时运行的所有作业都必须在备用作业跟踪器上从头重新启动。作业跟踪器高可用性设置对名称节点高可用性设置使用类似的组件。它使用 ZooKeeper 来存储关于哪个节点当前处于活动状态的信息,并依赖 ZKFC 守护程序来监控 JobTracker 的运行状况并执行自动故障转移。作业跟踪器将通过 HDFS 上的文件共享作业状态信息,因此不需要额外的存储集群,如日志节点。

对于我们的示例安装,我们将不会使用 JobTracker HA,但是我们将配置作业状态信息持久性。以这种方式设置有几个原因。首先,作业跟踪器高可用性没有名称节点高可用性那么关键。守护进程重新启动或计划外的服务器重新启动很容易被容忍,作业跟踪器会在启动时自动重新启动作业。在服务器完全故障的情况下,设置一个新的作业跟踪器非常容易,因为不需要以前的状态信息就可以使作业跟踪器快速运行。因此,在守护进程崩溃和重启时,JobTracker HA 不会提供太多,但在灾难性节点故障的情况下,它可以缩短恢复时间。取决于您对运行在那里的作业的服务级别协议,由您决定作业跟踪器在集群中的重要位置。不详细讨论 JobTracker HA 的第二个原因是因为设置它在很多方面与 NameNode HA 相似;您将需要为 JobTracker 集群配置一个逻辑名称,在配置文件中描述参与其中的两台服务器,设置 ZKFC,等等。

您应该可以按照http://www . cloudera . com/content/cloudera-content/cloudera-docs/CDH 4/latest/CDH 4-High-Availability-Guide/CDH 4 hag _ topic _ 3 . html找到的 CDH HA 指南快速配置 JobTracker 的 HA

要安装作业跟踪器包,请在专用服务器上执行以下命令。在我们的示例集群中,作业跟踪器的主机名是jt1.hadoop.test.com:

# yum install hadoop-0.20-mapreduce-jobtracker

这个命令将把hadoop-0.20-mapreduce作为一个依赖包安装,这个依赖包实际上包含了所有相关的.jar文件,以及其他相关的文件。JobTracker 包只提供默认文件和服务器启动脚本。从现在开始,你应该开始看到事物包装的趋势。

MapReduce 特定参数存储在/etc/hadoop/conf/mapred-site.xml中,JobTracker 和 TaskTracker 都使用这个参数。JobTracker 包的一个小怪癖是它不提供框架配置文件,所以您应该手动创建它。

我们首先需要配置的是作业跟踪器的主机名和端口。任务跟踪器将使用此选项来了解在哪里查找主节点:

<name>mapred.job.tracker</name>
<value>jt1.hadoop.test.com:8021</value>

如前所述,JobTracker 的本地磁盘空间要求很低。除了标准日志文件,作业跟踪器还存储所有提交的用户作业的配置以及已完成作业的历史信息。该日志记录到标准的 Hadoop 日志目录,在 CDH,该目录位于/var/log/hadoop-0.20-mapreduce/。此外,作业跟踪器需要在本地磁盘上存储一些系统信息。这些数据并不重要,通常不会占用太多磁盘空间。以下变量指定了此本地目录的位置:

<name>mapred.local.dir</name>
<value>/tpm/mapred/jt</value>

mapred.local.dir目录需要由映射的用户和组拥有。这是 CDH 在软件包安装期间创建的用户。

MapReduce 作业需要在大量机器上运行,因此需要能够将作业共享文件(如作业配置文件、jar 文件等)传播给所有机器。JobTracker 使用 HDFS 来存储这样的文件。它允许所有集群节点上的任务跟踪器轻松访问共享文件。

以下变量指定了此类共享目录的位置:

<name>mapred.system.dir</name>
<value>/tmp/mapred/system</value>

没有真正的迹象表明mapred-site.xml文件中的路径是指本地文件系统,还是使用 HDFS,所以记住哪个变量负责什么是很重要的。

MapReduce 还将一些正在运行和已完成作业的信息写入 HDFS,因此提交作业的用户可以轻松访问这些信息。为了实现这一点,以下变量需要指向根用户目录,在 HDFS 通常是/user:

<name>mapreduce.jobtracker.staging.root.dir</name>
<value>/user</value>

接下来的几个变量与工作状态信息在 HDFS 的存储方式有关。以前,JobTracker 将作业状态信息存储在内存中,因此在守护程序重新启动的情况下,MapReduce 客户端可能永远不会获得其提交作业的状态。为了解决这个问题,创建了作业状态存储,它基本上是 HDFS 的一个目录。要激活作业状态存储,您需要启用以下变量:

<name>mapred.job.tracker.persist.jobstatus.active</name>
<value>true</value>

默认情况下,作业状态信息将被写入 HDFS 的/jobtracker/jobsInfo目录。您可以使用mapred.job.tracker.persist.jobstatus.dir变量控制该位置。我们将使用默认设置,因此我们需要在 HDFS 创建这些目录并设置适当的权限:

# sudo -u hdfs hdfs dfs -mkdir /jobtracker
# sudo -u hdfs hdfs dfs -chown mapred:mapred /jobtracker

下一个变量允许重新启动作业跟踪器重新启动或崩溃时正在运行的作业。作业跟踪器从 HDFS 读取作业状态并重新启动它。虽然它可以提供额外的可靠性,并允许比需要人工交互的情况更快地恢复失败的作业,但是您应该决定集群中是否需要此选项。自动作业重新启动可能会出现几个潜在问题。首先,在出现故障的情况下,一些客户端可能会决定自己重新启动作业,这将导致提交同一作业的多个副本的情况。在多租户环境中,提交工作的一般规则可能很难实施。

另一个潜在的问题是,JobTracker 崩溃实际上可能与当前正在运行的作业有关,在 JobTracker 恢复在线后重新启动所有作业,而不适当调查导致崩溃的原因,可能不是最好的主意。另一方面,如果您对集群上运行的作业有很好的控制,或者您对作业完成有严格的服务级别协议,则启用自动作业重启是一个有效的选项。

<name>mapred.jobtracker.restart.recover</name>
<value>true</value>

您还可以通过设置以下选项来控制作业状态信息在 HDFS 存储的时间:

<name>mapred.job.tracker.persist.jobstatus.hours</name>
<value>24</value>

配置作业计划程序

作业跟踪器的主要作用之一是调度用户作业并将其提交给任务跟踪器。很可能没有用于生产目的的 Hadoop 集群被用来一次运行一个作业。在大多数情况下,不同的用户会提交几个作业,对于如何为竞争作业分配集群资源,这是一个合理的问题。从 MapReduce 框架的角度来看,集群容量由可用的 map 和 Reduce 插槽组成。这些参数是在任务跟踪器的配置过程中定义的,并且是每个工作节点的固定数字。任务跟踪器向作业跟踪器发送常规消息,其中包含给定服务器上当前占用多少 map 和 reduce 插槽的信息,作业跟踪器调度程序有责任决定如何以最有效的方式利用这些插槽。

JobTracker 可以使用几种算法来调度并发作业。这些算法实现为可插拔类,需要在mapred-site.xml文件中指定。管理员有责任为给定的工作负载选择最佳的调度程序。调度程序由mapred.jobtracker.taskScheduler变量标识,该变量是特定调度程序的 Java 类名。目前,有三种不同的调度器可用:作业队列任务调度器、公平调度器和容量任务调度器。由于实现良好的集群利用率是任何 Hadoop 管理员的首要任务,因此有必要简要概述一下调度器之间的主要差异。

作业队列调度程序

默认的最原始的调度程序是作业队列任务调度程序或先进先出调度程序。这个调度程序形成一个提交作业的队列,让第一个作业到达并占据集群中所有可用的位置。所有其他作业都必须在队列中等待第一个作业完全完成。这可能会导致相当长的等待时间,即使是小的工作,如果他们在长时间的工作后不走运的话。在长的 ETL 过程必须与短时间的用户请求共存的环境中,这种方法不是最佳的。先进先出调度器允许为提交的作业分配不同的优先级,但每个优先级只是分配给一个单独的队列,高优先级队列中的作业比低优先级队列中的作业更快地提交给任务跟踪器。这个调度程序缺少适当的资源管理器的重要特性,不太适合大多数生产安装。

FairScheduler

第二个可用的调度程序是 FairScheduler。FairScheduler 背后的主要思想是允许在一段时间内将集群资源平均分配给个不同的作业。作业被组织到池中,每个池获得等量的群集插槽。默认情况下,FairScheduler 被配置为为每个用户创建一个池,但也有其他选项可用。如果只有一个作业在运行,则允许消耗所有可用的槽,但是被释放的槽(一些地图任务会比其他任务完成得更快)可以被其他作业重用。还有一种方法可以将最少量的群集资源分配给更重要的池。例如,您可能希望为关键的生产作业执行此操作。您还可以将此调度程序配置为终止正在运行的任务,以保证高优先级作业有足够的容量。FairScheduler 为多租户环境提供了更好的集群利用率,并具有更高级的调整选项。我们将为集群配置选择这个调度程序。

容量任务计划程序

当前最后一个可用的调度程序是 capacity tasksscheduler。这个调度器使用了一个类似于 FairScheduler 的方法,但是有一些不同。作业被分配到一组预定义的队列中,每个队列获得一部分由管理员指定的集群资源。这部分资源被分配给一个队列,即使没有其他作业在运行,也不会被放弃。在队列中,作业以先进先出的方式进行调度,这意味着来自一个用户的作业将在队列中序列化。CapacityTaskScheduler 的一个有趣特性是,这个调度程序可以解释任务跟踪器报告的关于系统资源利用率(如内存)的信息,并根据一般的服务器利用率而不仅仅是通过查看可用的集群插槽来做出调度决定。这是生产使用的一个流行选项,并且在负载类型或多或少是静态的情况下工作良好。

如前所述,我们将为示例设置配置公平调度器。我们将使用基本设置,为每个用户创建任务池,所有池都配置为无最小容量共享要求。首先我们需要指定我们想要使用的调度器:

<name>mapred.jobtracker.taskScheduler</name>
<value>org.apache.hadoop.mapred.FairScheduler</value>

接下来,我们需要配置如何创建池。在以下示例中,提交作业的每个用户将获得一个单独的池:

<name>mapred.fairscheduler.poolnameproperty</name>
<value>user.name</value>

mapred.fairscheduler.poolnameproperty变量的值可以是任何作业属性。例如,要基于用户的主操作系统组创建池,您可以将该值设置为group.name

管理员可以在名为allocations文件的单独的 XML 文件中预定义池。所有其他池属性(如共享的最小插槽)都在此文件中指定。在我们的设置中,我们将允许 FairScheduler 为提交作业的每个用户动态创建池,没有额外的选项。为此,在/etc/hadoop/conf/中创建新文件,并将其命名为fair-scheduler.xml。它将是一个空的 XML 文件,其中只有一个部分:

<?xml version="1.0"?>
<allocations>
</allocations>

现在,我们需要在mapred-site.xml中指定这个文件的位置:

<name>mapred.fairscheduler.allocation.file</name>
<value>/etc/hadoop/conf/fair-scheduler.xml</value>

由于我们没有声明任何池,我们需要允许 FairScheduler 动态分配池。这是通过将mapred.fairscheduler.allow.undeclared.pools变量设置为真来实现的:

<name>mapred.fairscheduler.allow.undeclared.pools</name>
<value>true</value>

如果您想要微调池的行为,您可以在http://hadoop.apache.org/docs/r1.2.1/fair_scheduler.html的调度程序文档中探索可用的选项。

这些是我们在这个阶段需要指定的所有 JobTracker 配置选项。现在,您可以使用服务命令启动守护程序:

# service hadoop-0.20-mapreduce-jobtracker start

数据节点配置

现在我们已经完成了配置 Hadoop 主服务、名称节点和作业跟踪器,现在是时候配置完成大部分数据处理的节点了:数据节点。

数据节点是 Hadoop 的工作节点,也是集群服务器的主要组成部分。数据节点扮演双重角色;它们托管数据节点 HDFS 守护程序,以及来自 MapReduce 框架的任务跟踪器。这种混合允许 MapReduce 作业利用数据的局部性,并尽可能避免昂贵的网络传输。

让我们浏览一下数据节点配置的细节。然后,您将能够跨集群中的所有数据节点复制这些步骤。对于以下示例,我向示例集群添加了一个新主机:dn1.hadoop.test.com。我们对名称节点安装所做的假设同样适用于本节。应该正确格式化和装载本地磁盘卷,应用操作系统调整,对 Hadoop 端口不应该有防火墙限制,并且应该配置 CDH 存储库。

要使用 CDH 软件包安装数据节点,请使用以下 yum 命令:

# yum install hadoop-hdfs-datanode.x86_64

这将安装 Hadoop 核心、Hadoop HDFS 和特定于数据节点的软件包。实际上hadoop-hdfs-datanode包只包含默认配置文件和服务启动脚本。所有核心组件都作为 hadoop 和 hadoop-hdfs 包的一部分进行安装。

现在,我们需要在hdfs-site.xml中添加几个数据节点特定的选项。其中一些选项仅由数据节点使用,一些选项可由不同的 HDFS 客户端使用,但为了保持一致,我们将在完成名称节点配置并将其传播到群集中的所有节点后,编辑已经存在的hdfs-site.xml文件。

首先,我们需要指定数据节点将使用哪些卷来存储实际的 HDFS 数据。这是通过设置 dfs.data.dir变量来完成的:

<name>dfs.data.dir</name>
<value>
/dfs/data1,/dfs/data2,/dfs/data3,/dfs/data4,/dfs/data5,/dfs/data6
</value>

此变量是每个数据节点上本地卷的逗号分隔列表。由于通常没有为数据节点配置 RAID,因此这些卷实际上是独立的磁盘。数据节点将以循环方式使用这些磁盘来存储 HDFS 数据。

我们添加到hdfs-site.xml的下一个变量是dfs.block.size。此变量设置存储在 HDFS 的文件的默认块大小(以字节为单位)。您可以通过指定给定文件的块大小来覆盖此设置。默认情况下,Hadoop 使用 64 MB 的块大小,如今在大多数生产安装中,128 MB 的块大小已经成为标准。当您通过指定客户端选项将文件上传到 HDFS 时,可以改变不同文件的块大小。如果没有提供这样的选项,Hadoop 将使用配置文件中的dfs.block.size。对于我们的示例集群,我们将使用 128 MB 的块大小:

<name>dfs.block.size</name>
<value>134217728</value>

控制 HDFS 行为的另一个核心变量是dfs.replication。此变量指定每个文件块将被复制多少次。默认设置为3,在大多数情况下,这是群集弹性和总可用群集存储容量之间的最佳选择。就像块大小一样,HDFS 客户端可以基于每个文件指定一个复制因子。即使不需要调整该变量,也最好将其显式添加到配置文件中,以便于理解使用了哪种设置:

<name>dfs.replication</name>
<value>3</value>

还有两个与dfs.replication(即dfs.replication.max变量)相关的变量限制了群集中一个数据块的可能副本数量。默认情况下是512。如果您不信任所有使用您的集群的客户端,并且如果您不希望任何人将文件系统设置为复制 512 次,您可能希望降低该值。另一个相关设置是dfs.namenode.replication.min。它控制给定数据块的最小副本数,以认为数据块写入已完成。该变量的默认值为1,这意味着如果至少有一个数据节点存储了该块,则写操作被视为成功。这种默认行为意味着某些文件存储的副本数量将少于 dfs.replication 设置所要求的数量。当群集中出现网络问题或并非所有数据节点都可用时,就会出现这种情况。

Hadoop 将定期扫描文件系统中这种复制不足的数据块,并尝试复制它们以匹配系统默认值。1的缺省值对于dfs.namenode.replication.min来说是一个合理的设置,对于我们的设置,我们将保持不变,但是您可能想要查看这个设置,尤其是如果您对数据弹性有很强的要求。

我们将为数据节点配置指定的下一个变量是dfs.du.reserve。这个变量的名称不是很有描述性,但其思想是 Hadoop 可以在数据节点正在使用的磁盘上保留一些空间。这是必需的,因为 MapReduce 框架需要一个本地卷来存储临时数据。作业的映射和缩减阶段都将生成临时文件,并且在映射缩减临时目录中有足够的空间至关重要。通常的做法是使用 HDFS 使用的相同本地磁盘,以便能够将 IO 负载分配给多个磁盘轴,但这意味着需要保留一些空间,以防止所有磁盘空间都被 HDFS 占用,并且 MapReduce 作业开始失败,因为没有地方传输临时数据。最好在每个磁盘上保留大约 10%的总磁盘容量,除非您计划在每个服务器上为 MapReduce 临时目录保留一个专用卷。要为每个磁盘保留 10 GB,我们将使用以下设置:

<name>dfs.du.reserve</name>
<value>10737418240</value>

在我们启动数据节点守护程序之前,值得仔细检查一下 JVM 堆设置。默认情况下,数据节点将以 1 GB 堆内存大小开始。在大多数情况下,这已经足够了,因为数据节点主要集中在大型顺序读写上,但是如果您需要调整它,请使用/etc/default/hadoop-hdfs-datanode文件并设置HADOOP_DATANODE_OPTS变量,类似于我们对名称节点的堆大小所做的:

export HADOOP_DATANODE_OPTS="-Xmx1024m"

现在,我们准备使用service命令启动数据节点守护程序:

# service hadoop-hdfs-datanode start

始终检查刚刚启动的守护程序的日志文件,尤其是在对配置文件进行更改时。如果数据节点成功启动并能够与活动和备用名称节点通信,您应该会在日志文件中看到消息,表明数据节点开始向名称节点发送块分配信息。

为了验证数据节点是否正常工作,我们将执行两个简单的测试。此时可以使用 HDFS,尽管我们只配置了一个数据节点。回忆dfs.namenode.replication.min设置。默认值为1,如果至少可以创建一个文件块的副本,HDFS 将能够存储文件。这将允许我们在投入时间在所有数据节点上传播这些设置之前,先验证一个数据节点上的配置。

首先,我们将在 HDFS 创建一个临时目录,然后在那里上传一个示例文件。Hadoop 中的临时目录与您的 Linux 安装中的/tmp目录扮演着相同的角色。我们将在后续章节中建立的一些生态系统项目将要求/tmp出现在 HDFS。要在 HDFS 创建新目录,我们将使用hdfs命令:

# sudo -u hdfs hdfs dfs -mkdir /tmp

hdfs命令行客户端工具是用来对 HDFS 进行各种操作。它接受 HDFS 命令作为参数,并且通常试图模仿标准的 Linux 命令,例如mkdirlsrm等等。请注意,我们以 hdfs 用户的身份执行此命令,因为我们需要在文件系统中创建根目录,而 hdfs 相当于本地文件系统的根用户。如果您尝试以根用户身份执行此命令,将会出现权限被拒绝的错误。

现在,我们需要在 HDFS 的/tmp目录上设置权限,就像对本地文件系统一样;每个人都可以读写这个目录,但用户只能删除或重命名自己的文件(粘性位)。HDFS 有一个chmod命令,类似于下面的 Linux 命令:

# sudo -u hdfs hdfs dfs -chmod 1777 /tmp

让我们创建一个简单的文本文件,test.txt并将其上传到 HDFS,假设文件在/root中,您可以使用以下命令上传它:

# hdfs dfs -put /root/test.txt /tmp

为了验证文件是否被正确加载,我们可以对 hdfs 使用-ls-cat命令。您也可以使用hdfs fsck命令来验证文件系统的健康状况。

此时,您应该继续配置集群中的其余数据节点。显然,在处理大量机器时,使用自动化工具传播配置文件并并行执行命令会很方便。

任务跟踪器配置

任务跟踪器是我们需要设置和配置的 Hadoop 核心的最后一部分。任务跟踪器对于 MapReduce 框架就像数据节点对于 HDFS 一样。任务跟踪器负责为作业跟踪器提交给它们的作业启动和执行单个任务。任务跟踪器的守护程序运行在与数据节点相同的服务器上。这是在地图阶段最大化本地数据访问所必需的。JobTracker 足够聪明,能够找出各个任务所需的文件块驻留在哪些数据节点上,并将这些任务提交给运行在同一服务器上的 TaskTrackers。

首先,我们需要安装所需的软件包:

# yum install hadoop-0.20-mapreduce-tasktracker

与 JobTracker 类似,hadoop-0.20-mapreduce包将作为依赖项安装。

任务跟踪器守护程序使用相同的mapred-site.xml配置文件,就像作业跟踪器一样。这可能不是最好的决定,因为任务跟踪器和作业跟踪器的某些设置可能有不同的值。在下面的例子中,我们将假设您维护两个不同版本的mapred-site.xml,一个用于作业跟踪器,一个用于所有的任务跟踪器。

我们需要指定的第一个设置是 JobTracker 守护程序的地址和端口:

<name>mapred.job.tracker</name>
<value>jt1.hadoop.test.com:8021</value>

这与我们为 JobTracker 配置的值完全相同。

我们也在 JobTracker 服务器上配置了mapred.local.dir,但是在 TaskTracker 上,它有不同的功能。虽然它仍然指定本地卷来存储临时数据,但是对本地存储的要求在 TaskTracker 上更加苛刻。MapReduce 作业将使用这个本地存储来保存临时数据(地图任务输出数据),这些数据稍后将被传递到 Reduce 阶段。数据的大小和输入输出的强度可能很重要,这取决于您运行的作业类型和作业并发性。一种常见的做法是在数据节点使用的相同磁盘上为作业数据分配单独的目录。这允许足够的磁盘空间,并利用多个磁盘来提高输入输出吞吐量。之前,我们已经为数据节点守护程序配置了dfs.du.reserve变量。这是为了防止 HDFS 占用所有磁盘空间并导致作业失败,因为它们无法再写入临时位置。我们在 JobTracker 上配置了相同的变量,但是那里的磁盘空间要求要低得多。以下是如何在任务跟踪器上配置此变量:

<name>mapred.local.dir</name>
<value>
/dfs/data1/mapred,/dfs/data2/mapred,/dfs/data3/mapred,/dfs/data4/mapred,/dfs/data5/mapred,/dfs/data6/mapred
</value>

这假设您的 HDFS 卷安装在/dfs/data*上。确保映射操作系统用户可以访问映射目录。

任务跟踪器是 Hadoop 集群容量配置发生的地方。从 MapReduce 的角度来看,集群容量由可用的映射槽和可用的缩减槽组成。每个任务跟踪器可分配的插槽数量取决于服务器硬件配置,特别是可用的中央处理器和内存。创建单个工作节点可以处理的更多插槽没有太大意义,因为这样作业进程将开始争夺机器资源,从而导致速度显著下降。让我们假设我们正在设置一个更小的高端机器集群,每个节点有 16 个 CPU 内核和 64 GB 内存,如前所述。经验法则是将可用插槽的数量与可用内核的数量大致匹配。对于速度更快的服务器,稍微超额订阅 CPU 是可以的,对于 16 核机器,我们总共可以分配 24 个任务槽(16 * 1.5 = 24)。请记住,这些是总的可用时段,包括地图和缩减时段,因为地图任务进行初始数据处理,并且为每个输入分割创建一个地图任务,所以您可以预计对地图时段的需求将多于缩减时段。缩减阶段是对地图任务生成的数据执行的,通常预期处理的数据比地图阶段少得多。可用映射减少插槽的确切比例将取决于实际工作负载,但一个好的起点是将所有服务器插槽的 2/3 分配给映射任务,1/3 分配给减少任务。对于我们的 16 核机器,我们将有 16 个映射插槽和 8 个缩减插槽:

<name>mapred.tasktracker.map.tasks.maximum</name>
<value>16</value>
<name>mapred.tasktracker.reduce.tasks.maximum</name>
<value>8</value>

任务跟踪器为每个映射创建单独的 Java 进程并减少任务,因此除了它自己的堆内存设置之外,它还需要向子进程提供这些设置。就像我们到目前为止配置的所有其他 Hadoop 守护程序一样,TaskTracker 的堆大小可以通过设置/etc/default/hadoop-0.20-mapreduce文件中的HADOOP_TASKTRACKER_OPTS变量来配置:

export HADOOP_TASKTRACKER_OPTS="-Xmx1G"

任务跟踪器堆内存的默认设置是1G,对于大多数安装来说应该足够了。不过,此设置与可用于映射和减少进程的内存无关。为此,使用了mapred-site.xml中的mapred.java.child.opts变量。实际上,它可以用来提供不同的参数来映射和减少进程,但最常见的是最小和最大堆内存设置。应该分配给各个任务的内存量取决于配置的插槽总数和服务器内存。例如,对于一台具有 64 GB 内存和总共 24 个任务插槽的服务器,为每个任务分配2G是合理的:

<name>mapred.java.child.opts</name>
<value>-Xmx2G</value>

mapred.java.child.opts 变量只是一个将被传递给任务进程的选项字符串,因此您可以包含其他选项,例如最初用-Xms选项分配给进程的内存量。

基本的任务跟踪器配置到此结束,我们现在可以开始了。使用以下命令将其联机:

service hadoop-0.20-mapreduce-tasktracker

检查任务跟踪器日志文件,确保没有错误。初始设置期间的典型问题是由本地目录上的不正确权限、JobTracker 地址中的拼写错误等引起的。您也可以运行以下命令来列出已成功注册到作业跟踪器的所有作业跟踪器:

# hadoop job -list-active-trackers

在您将此设置传播到所有任务跟踪器之前,我们运行一个最终的验证测试,它正在执行一个实际的 MapReduce 作业。这将是一个基本的字数统计示例,通常作为 MapReduce 的“你好,世界”等价物出现。它也包括在随 CDH 包裹一起运送的例子中。

  1. 首先,创建一个包含任意文本的文件,并将其保存在本地目录中。让我们假设您在 jt1 服务器上这样做,并且作为根用户操作。要执行 MapReduce 作业,您需要在 HDFS 创建一个/user/root目录。它将用作作业暂存目录。确保所有权被分配给根:

    # sudo –u hdfs hdfs dfs -mkdir /user/root
    # sudo -u hdfs hdfs dfs -chown root:root /user/root
    
    
  2. 请注意,我们是作为 hdfs 用户执行这些操作的,HDFS 用户是 HDFS 的超级用户,而从 HDFS 的角度来看,root 只是一个普通用户。接下来,在/user/root :

    # hdfs dfs -mkdir /user/root/words_input
    
    

    中创建作业输入目录

  3. 要将文件上传到 HDFS,请使用以下命令:

    # hdfs dfs -put /tmp/words.txt /user/root/words_input
    
    
  4. 字数示例,连同其他样本作业一起位于/usr/lib/hadoop-0.20-mapreduce/hadoop-examples.jar。要提交地图缩减作业,请使用hadoop jar命令:

    # hadoop jar /usr/lib/hadoop-0.20-mapreduce/hadoop-examples.jar wordcount /user/root/words_input/tmp/words_output
    
    
  5. hadoop jar命令接受几个参数:.jar文件的位置,我们要运行的作业的类名,查找输入文件的目录,以及写入最终结果的目录。每次运行作业时都会创建输出目录,因此在开始作业之前,请确保它不存在。如果在执行此命令后一切都配置正确,您应该会看到作业执行进度和一些额外的统计信息,包括在映射和缩减阶段花费的时间、处理的行数等。

  6. 看一下输出目录,应该会看到以下文件:

    # hdfs dfs -ls /user/root/words_output
    Found 3 items
    -rw-r--r--   3 root supergroup          0  /user/root/words_output/_SUCCESS
    drwxrwxrwt   - root supergroup          0  /user/root/words_output/_logs
    -rw-r--r--   3 root supergroup         65  /user/root/words_output part-r-00000
    
    
  7. _SUCCESS文件是一个有标记的文件,表示作业完成没有错误。_logs目录包含作业执行日志,最后part-r-00000是结果文件,包含输入文件中的单词及其各自的计数。您可以通过运行以下命令来检查其内容:

    # hdfs dfs -cat /user/root/words_output/part-r-00000
    
    

如果一切都如这里描述的那样工作,那么您的 MapReduce 和 HDFS 配置是有效的,您可以继续在集群中的所有节点上传播它们。

高级 Hadoop 调优

前面几节描述了设置和配置核心 Hadoop 组件的步骤。了解了典型的生产工作负载和正在执行的作业类型后,您可能希望调整一些附加配置设置,以更好地改善或平衡工作负载。Hadoop 公开了比我们已经讨论过的更多的配置选项。您可能永远不需要更改其中的大部分,但是这里有几个与性能相关的变量值得一提。

hdfs-site.xml

名称节点需要响应来自 HDFS 客户的许多不同请求,包括数据节点和外部应用。为了有效地处理这些请求,名称节点生成几个线程来处理这个负载,它创建的线程数量可以通过dfs.namenode.handler.count变量来配置。线程的默认数量是10,但是如果你正在设置一个大的集群,你可能想要增加它。对于如何计算这个数字有不同的意见,但是一般来说,如果将这个值设置得太高,您将不会获得显著的性能提升。如果集群大小超过 200 个节点,将该值设置为100,如果小于 200 个节点,将该值设置为50:

<name>dfs.namenode.handler.count</name>
<value>50</value>

向集群中添加新的数据节点以增加总容量,或者替换出现故障的节点,是 Hadoop 管理员迟早需要执行的一项常见任务。虽然新节点将开始接受新创建的文件和副本的数据块,但现有数据不会自动重新平衡。这意味着您的新节点不会得到充分利用。要强制 Hadoop 将现有数据块移动到具有大量容量的服务器,您需要运行hdfs balancer命令,,但是跨网络移动万亿字节的数据很容易中断常规作业。为了防止出现这种情况,Hadoop 将平衡数据移动限制到dfs.datanode.balance.bandwidthPerSec变量中定义的值,即每秒字节数。确切的值将取决于集群中的网络带宽;默认值为 1mb/秒。要将其增加到 10mb/秒,请使用以下设置:

<name>dfs.datanode.balance.bandwidthPerSec</name>
<value>10485760</value>

mapred-site.xml

类似于名称节点,作业跟踪器可以非常繁忙地响应多个客户端请求。为了确保 JobTracker 为此分配了足够的线程,您需要调整mapred.job.tracker.handler.count 变量。使用与命名节点线程数相同的规则:

<name>mapred.job.tracker.handler.count</name>
<value>50</name>

MapReduce 作业的性能受排序和洗牌阶段的影响很大,在这个阶段,单个地图任务的输出必须按关键字排序,合并成几个更大的文件,然后发送给 Reduce。此阶段通常会产生大量网络流量,还会导致大量本地 IO。当地图任务需要对其输出进行排序时,它会使用一个内部缓冲区,一旦该缓冲区已满,它就会将数据溢出到本地磁盘上。为了减少这种溢出的次数,可以增加io.sort.mb变量的值。默认情况下,它被设置为100 MB,对于大多数工作负载来说,这是一个很好的缓冲区大小。如果在排序阶段观察到大量本地 IO,可以增加该值。要将排序缓冲区增加到 200 MB,请在mapred-site.xml文件中添加以下行:

<name>io.sort.mb</name>
<value>200</value>

请记住,该缓冲区是作为任务堆大小的一部分分配的,由mapred.java.child.opts变量指定。

一个相关的选项是io.sort.factor。它指定一批中要合并多少个文件。同样,这个变量没有严格的规则,但是10的默认值似乎太低了。您可以从32开始,这是一个有点任意的数字,观察集群的性能来进一步调整它:

<name>io.sort.factor</name>
<value>32</value>

在作业图的缩减阶段,属于给定关键范围的输出需要被复制到特定的缩减器。集群中可能有许多这样的片段,为了加快复制速度,减少器使用了几个并行的进程。默认情况下,并行创建五个拷贝过程。如果要设置大型集群,或者计划运行需要数千个地图任务的作业,则可能需要增加该值。对于中小型集群(20-100 个节点),采用 12-16 个并行流程:

<name>mapred.reduce.parallel.copies</name>
<value>12</value>

core-site.xml

大型 Hadoop 集群在数据中心的多个机架上大量涌现,但较小的集群被分割在两个或三个不同的机架上并不罕见。对于较小的集群,多机架设置可在其中一个机架出现故障时提供额外的冗余。 Hadoop 被设计为机架感知型,例如,能够根据给定服务器属于哪个机架进行一些优化。其中一个优化是 Hadoop 使用的块副本放置策略。它将尝试在不同的机架中存储至少一个副本,以提高数据恢复能力。当请求数据块时,比如说一个 MapReduce 作业,Hadoop 将尝试最小化跨机架网络流量,取而代之的是在同一个机架中的服务器。

为了能够使用这个功能,Hadoop 需要知道哪个服务器属于哪个机架。想法是 Hadoop 管理员将提供一个可执行文件,该文件将返回机架标识和服务器 IP 或主机名。这个可执行文件的实现完全取决于管理员。最常见的情况是创建一个逗号分隔的文本文件,该文件将保持服务器映射到机架,并编写一个 shell / python / perl 脚本,该脚本将以 IP 或主机名作为参数并返回机架 ID。试管架号可以是任何字符串。提供这样的脚本超出了本书的范围,但是在线上有多个版本。要启用机架感知,您需要在net.topology.script.file.name变量中指定您的脚本路径:

<name>net.topology.script.file.name</name>
<value>/etc/Hadoop/conf/rack_topology.bash</value>

如果没有提供脚本,Hadoop 假设所有服务器都在一个机架内。

总结

本章提供了设置和配置核心 Hadoop 组件的分步指南。我们已经开始确定 Hadoop 服务器需要调整的最关键的操作系统设置。然后,我们重点介绍了使用 CDH 分发版为 CentOS Linux 分发版设置名称节点、数据节点、作业跟踪器和任务跟踪器的步骤。为了消除 HDFS 的单点故障,我们使用日志节点仲裁配置了一个名称节点高可用性集群。按照这些步骤,您可以构建一个功能齐全、生产就绪的集群。Hadoop 核心组件足以开始执行有用的工作,但是随着时间的推移,许多生态系统项目围绕 Hadoop 发展。其中一些成为了必备的集群组件。在下一章配置 Hadoop 生态系统中,我们将通过这些项目提供的附加功能来丰富我们的集群。

三、配置 Hadoop 生态系统

Hadoop 是一个强大的分布式数据处理系统。我们在上一章中配置的集群是一个现成的系统,但是如果您开始在这个配置中为任何实际应用使用 Hadoop,您将很快发现 MapReduce 提供了一种非常低级的方法来访问和处理数据。你需要自己解决很多事情。您需要决定如何从外部来源导出数据,并以最有效的方式将其上传到 Hadoop 中。您将需要弄清楚以什么格式存储数据,并编写 Java 代码来实现 MapReduce 范例中的数据处理。Hadoop 生态系统包括许多辅助项目,这些项目是为了解决加载、处理和提取数据的不同方面而创建的。在本章中,我们将讨论几个流行且重要的 Hadoop 生态系统项目的设置和配置:

  • 用于从外部数据源提取数据的 Sqoop
  • 高级、类似于 SQL 的数据访问配置单元
  • 用于实时数据处理的 Impala

还有许多与 Hadoop 相关的项目,但我们将重点关注那些能立即提高 Hadoop 集群对最终用户可用性的项目。

托管 Hadoop 生态系统

通常,额外的 Hadoop 组件不会托管在集群本身中。这些项目大多作为 HDFS 和 MapReduce 的客户端,可以在不同的服务器上执行。这些服务器被标记为 Hadoop 客户端,如第 1 章设置 Hadoop 集群-从硬件到分发的集群图所示。在物理上和网络级别上将 Hadoop 节点与客户端分开的主要原因是安全性。Hadoop 客户端服务器应该由组织内的不同人员访问。如果您决定在与 Hadoop 相同的服务器上运行客户端,您将不得不投入大量精力为每个用户提供适当的访问级别。从逻辑和物理上分离这些实例简化了任务。Hadoop 客户端通常部署在虚拟机上,因为资源要求不高。

请记住,读写 HDFS 数据的客户端需要能够访问命名节点以及群集中的所有数据节点。

如果您正在运行一个小型集群或者的用户数量有限,并且不太关心安全问题,您可以将大多数客户端程序托管在与名称节点或数据节点相同的节点上。

Sqoop

Sqoop 是一个工具,它连接了两个世界:关系数据库和 Hadoop。将关系数据库中的数据导入 Hadoop,反之亦然,这是一项非常常见的任务。对于许多组织来说,Hadoop 是一个数据集成平台。让我们假设您的网站生成了大量的应用日志文件。这些日志包含关于用户如何与您的应用交互的非常有价值的信息,但是您可以在日志中捕获的唯一用户信息是用户名。另一方面,您的关系数据库中有非常详细的用户配置文件数据。能够轻松地将这些数据导出到 Hadoop 中,并对不同类别的用户如何与网站交互进行一些分析是极其重要的。另一方面,复杂的长时间运行的 MapReduce 作业产生的结果可能相对较小。通常,这些数据被加载到关系数据库管理系统中,用于实时数据访问或与商业智能工具集成。

安装和配置 Sqoop

Sqoop 是一个命令行工具,尽管未来的版本将提供客户端-服务器类型的访问。Sqoop 几乎总是部署在 Hadoop 集群之外的服务器上。

Sqoop 需要能够访问所有 Hadoop 节点,以及您计划使用的关系数据库。只对几个选定的 Sqoop 节点提供这种级别的访问更容易。

使用 CDH 存储库很容易安装 Sqoop:

# yum install sqoop

如果您在尚未安装 CDH 软件包的客户端服务器上安装它,您将需要安装几个依赖项,包括 Hadoop-client 和 Hadoop-MapReduce 软件包。

Sqoop 包附带了几个配置文件:

# ls -lh /etc/sqoop/conf/
-rwxr-xr-x 1 root root 1.4K Apr 22 20:38 sqoop-env-template.sh
-rwxr-xr-x 1 root root 5.0K Apr 22 20:38 sqoop-site-template.xml
-rwxr-xr-x 1 root root 5.0K Apr 22 20:38 sqoop-site.xml

模板文件提供了一个选项列表,您可以使用它来优化 Sqoop。幸运的是,如果你使用 CDH 分布,你将不需要在那里改变很多东西。主 Sqoop 配置文件sqoop-site.xml带有一组很好的默认值,Sqoop 可以开箱即用。有几个与 Metastore 配置相关的选项,您可能想要更改。我们稍后将讨论它们。

Sqoop 依靠 JDBC 驱动程序将连接到不同的数据库服务器。由于许可差异,这些驱动程序不随 Sqoop 一起提供,必须单独安装。为了演示 Sqoop 的基本导入/导出功能,我们将使用一个 MySQL 数据库作为源。可以从mysql.com下载 MySQL JDBC 驱动。驱动程序以.jar文件的形式出现,需要复制到/usr/lib/sqoop/lib下,由 Sqoop 自动拾取。

Sqoop 导入示例

对于下面的例子,我们将使用 MySQL“world”数据库,该数据库可以在http://dev.mysql.com/doc/index-other.html找到。要执行这些示例,您需要启动并运行 MySQL 服务器,将world数据库加载到其中,为 Sqoop 创建一个用户,并确保运行 Sqoop 的机器可以访问远程(或本地)MySQL 服务器。

要将表从 MySQL 导入 Hadoop,可以运行以下命令:

# sqoop import --connect jdbc:mysql://mysql-db.server.example.com/world --table Country --username sqoop_user –P
Enter password:

在这种情况下,传递给 Sqoop 的选项非常简单。我们需要指定 JDBC 连接字符串、我们想要导入的表(本例中为Country)以及我们为此目的创建的 MySQL 用户。您也可以使用--driver 选项指定使用哪个 JDBC 驱动程序。请记住,JDBC 连接字符串格式因数据库而异,因此请务必参考数据库文档。

了解 Sqoop 如何执行导入非常重要。Sqoop 分析您试图导入的表,并生成要在 Hadoop 集群上执行的 Java MapReduce 代码。每个地图任务将连接到 MySQL 数据库,使用SELECT语句读取一部分数据,并将其写入 HDFS。Sqoop 试图利用 Hadoop 提供的并行性来加快导入过程。这对于性能来说非常好,但是需要记住这种方法的一些含义。最重要的影响之一是,导入任务是从几个集群服务器运行的,并且从数据库的角度来看是完全独立的。这意味着无法保证事务一致性。您可以使用--num-mappers 选项控制并行任务的数量,默认为 4。

使用--num-mappers选项时要小心。来自多个 Hadoop 节点的并发连接太多,很容易使数据库过载。

让我们看看导入的文件。默认情况下,Sqoop 将在运行作业的用户的 HDFS 主目录中创建新目录。新的目录名将与正在导入的表名相匹配。您可以使用--warehouse-dir选项控制目标目录。如果您在导入后检查您的 HDFS 主目录,您将会看到以下内容(为简洁起见,输出被删除):

# hdfs dfs -ls /user/alice/Country
Found 6 items
0 2013-06-05 20:56 /user/alice/Country/_SUCCESS
0 2013-06-05 20:54 /user/alice/Country/_logs
9919 2013-06-05 20:56 /user/alice/Country/part-m-00000
6990 2013-06-05 20:56 /user/alice/Country/part-m-00001
7069 2013-06-05 20:56 /user/alice/Country/part-m-00002
7512 2013-06-05 20:56 /user/alice/Country/part-m-00003

从我们在第 2 章安装和配置 Hadoop 中运行的 Wordcount MapReduce 程序中,您应该对_SUCCESS_logs文件很熟悉。这非常清楚地表明,每个 Sqoop 导入实际上都是一个 MapReduce 作业。您还会注意到有四个结果文件。这是因为本次导入使用了 4 个独立的地图任务。他们每个人都生成了一个单独的纯文本文件。您现在可以使用hdfs命令检查这些文件,对它们运行 MapReduce 作业,等等。

Sqoop 导出示例

为了演示将数据加载到 MySQL(或任何其他关系数据库)中的相反过程,创建一个示例 CSV 文件并将其保存到 HDFS /user/alice/tomysql目录中:

# hdfs dfs -cat /user/alice/tomysql/result

要将数据导出到 MySQL 表中,请运行以下命令:

# sqoop export --connect jdbc:mysql://mysql-db.server.example.com/test --table hadoop_results --username sqoop_user -P --export-dir /user/root/tomysql/

这与的import命令没有太大区别。在这里,我们需要用--test选项指定哪个 MySQL 表将用于数据加载,以及从哪里用--export-dir读取数据。作业完成后,您可以使用简单的SELECT 语句验证数据是否正确加载。

这些例子只展示了 Sqoop 可以执行的非常基本的操作。Sqoop 比所展示的更加灵活和强大。它允许使用自定义条件控制从关系数据库导入哪些数据。Sqoop 可以执行增量导入,跟踪已经导入了哪些行。您可以指定要使用的文件格式和压缩类型等等。关于 Sqoop 的详细文档可以在http://sqoop.apache.org/docs/1.4.3/SqoopUserGuide.html找到。

新版本的 Sqoop 2 将解决当前版本的几个限制。这包括以客户机-服务器模式运行、提供可重用的数据库连接、拥有适当的权限模型等等。到目前为止,Sqoop 2 还没有一个稳定的版本。

鼠标

如果你想从第二章安装和配置 Hadoop 中探究 WordCount MapReduce 作业示例的源代码,或者试图自己编写一些代码,你现在应该已经意识到这是 Hadoop 中处理数据的一种非常低级的方式。事实上,如果编写 MapReduce 作业是 Hadoop 中访问数据的唯一方式,那么它的可用性将非常有限。

Hive 就是为了解决这个特殊的问题而设计的。事实证明,大量处理数据过滤、聚合和分组的 MapReduce 代码可以自动生成。因此,可以设计一种高级数据处理语言,然后将其编译成本机 Java MapReduce 代码。实际上,没有必要为此设计新的语言。SQL 已经成为关系数据库中处理数据的事实标准。对于 Hive 开发人员来说,解决方案是显而易见的:采用一种 SQL 方言,构建 Hive 作为从 SQL 到 MapReduce 的编译器。Hive 提供的语言叫做 HiveQL 。值得一提的是,像 Pig 这样的项目走了不同的道路,他们没有重新使用 SQL 作为高级语言,而是想出了自己的新语言。

在 Hadoop 集群上使用 SQL 的能力极大地提高了其可用性,并扩大了可以使用集群数据的用户群体。它还允许将使用 SQL 接口的应用与 Hadoop 集成在一起。这使得 Hive 成为 Hadoop 生态系统中的必备组件之一。

Hive 建筑

本质上,Hive 执行以下任务:获取一个 HiveQL 查询,将其编译成一个 MapReduce 任务,将该任务提交给集群,并将结果呈现给用户。为了将 HiveQL 编译成 MapReduce 代码,Hive 必须理解被查询数据的结构。Hive 将数据组织到熟悉的关系表中,这些关系表有定义类型的列。另一方面,Hive 对存储在 Hadoop 集群中的数据进行操作,Hadoop 不会对其数据强加任何模式,这一点您已经知道。这意味着 Hive 必须提供一个额外的层来存储其表的元数据。Hive 通过 Metastore 服务实现这一层。

Metastore 是一个双组件服务。第一个组件是一个服务器,它接受来自 Hive 客户端的连接,并向它们提供所需表的信息。第二个是关系数据库,Metastore 使用它将元数据保存在磁盘上。为此,Hive Metastore 支持几个数据库,如 MySQL、PostgreSQL 和 Oracle。MySQL 是 Metastore 后端的流行选择,我们将在集群中使用它。Metastore 可以在不同的模式下运行。您可以使用嵌入在 Hive 客户端中的 Metastore。

您可以将 Metastore 作为本地服务运行,并将几个 Hive 客户端连接到它。或者,您可以运行远程集群范围的服务,该服务可以由来自多台机器的多个客户端使用。所有选项都有用例,但是对于生产 Hadoop 集群,运行远程 Metastore 是最常见的选择。这样,您可以轻松地在多个客户端之间共享 Hive 元数据,同时将客户端与后端关系数据库隔离开来。为了实现高可用性,您还可以运行多个 Metastore 服务器。

到目前为止,当我们提到 Hive 客户端时,我们实际上指的是 Hive 命令行界面。类似于 SQL 的接口允许 Hive 支持使用 JDBC 和 ODBC 驱动程序的应用。这使得 Hive 查询引擎和数据可供各种第三方应用使用。这些应用不直接与 Metastore 通信,而是依赖于一个 Hive Server ,它提供查询编译和 Metastore 访问服务。

如果您再次参考第 1 章中的 Hadoop 集群图设置 Hadoop 集群–从硬件到分发,您会看到我们已经为 Hive Metastore 和其他服务分配了一个单独的服务器。我们将坚持这个计划,在单独的机器上安装 Hive Metastore、Hive Server 和 Metastore 后端数据库。这是可选的,您可以选择将这些服务器与其他 Hadoop 组件(如作业跟踪器或名称节点)共存。Hive 的硬件资源要求一般,但取决于客户端的数量和您计划托管的 Hive 表。

安装 Hive 元存储

在我们安装 Hive Metastore 之前,我们需要确保有一个后端数据库启动并运行。对于我们的集群,我们将为此目的使用 MySQL 数据库。我们将在运行 Hive Metastore 的同一台服务器上运行 MySQL 数据库,但是后端数据库通常位于 Hadoop 集群之外。安装和配置 MySQL 超出了本书的范围。MySQL 安装详情可以参考[http://dev.mysql.com/doc/refman/5.5/en/installing.html](http:// http://dev.mysql.com/doc/refman/5.5/en/installing.html)。值得一提的是,丢失 Hive 元数据会有很大的影响,因为您需要重新创建所有的表定义。为 Metastore 后端数据库设置适当的高可用性和备份非常重要。

安装并配置完 MySQL 后,您需要为 Hive Metastore 创建一个 MySQL 数据库和一个用户。

如果您已经在 Hive Metastore 服务器上配置了 CDH 存储库,如第 2 章安装和配置 Hadoop 中所述,您现在可以简单地使用以下yum命令来安装 Metastore:

# yum install hive-metastore

配置单元配置类似于其他 Hadoop 组件。配置文件,包括带有所有选项的模板文件及其描述,位于/etc/hive/conf下。有许多配置选项可用,但我们将重点关注核心选项,以快速启动和运行 Hive。所有选项都应添加到hive-site.xml文件中。

您需要将 Hadoop 集群节点中的hdfs-site.xmlmapred-site.xml文件复制到所有与 Hive 相关的服务器上的/etc/Hadoop/conf目录中。否则,Hive 将无法与 HDFS 通信并启动 MapReduce 作业。

首先,我们需要指定后端使用哪个数据库驱动程序。在我们的例子中,我们需要添加以下属性:

<name>javax.jdo.option.ConnectionDriverName</name>
<value>com.mysql.jdbc.Driver</value>

几个选项为后端数据库提供凭证,并且是不言自明的,因此我们将它们包含在一个块中,如下所示:

<name>javax.jdo.option.ConnectionURL</name>
<value>jdbc:mysql://localhost/hive_meta </value>

<name>javax.jdo.option.ConnectionUserName</name>
<value>hivemetauser</value>

<name>javax.jdo.option.ConnectionPassword</name>
<value>secret</value>

数据库连接字符串具有简单的 JDBC 格式,并且 MySQL 用户和密码应该与 MySQL 安装期间创建的匹配。

如前所述,您可以运行几个 Metastore 服务,使用相同的数据库后端来实现高可用性。您需要在hive.metastore.uris变量中为所有这些元存储指定连接字符串。在我们的例子中,只有一个 Metastore:

<name>hive.metastore.uris</name>
<value>thrift://hive.hadoop.test.com:9083</value>

在前面的代码中,hive.hadoop.test.com是运行 Metastore 的机器的主机名,9083是正在监听的默认端口。您可以通过修改/etc/default/hive-metastore文件中的PORT变量来更改端口。确保该端口对所有 Hive 客户端可用。

最后,我们需要指定 Hive 将存储表数据的位置。在 Hive 中,每个数据库和表都由 HDFS 的一个目录和一组文件来表示。您可以使用hive.metastore.warehouse.dir变量指定这些文件的默认位置:

<name>hive.metastore.warehouse.dir</name>
<value>/warehouse</value>

要启动 Metastore 服务,我们需要采取以下步骤:

  1. 需要在 HDFS 创建具有适当权限的 Hive 仓库目录。以hdfs用户身份运行以下命令:

    # hdfs dfs -mkdir /warehouse
    # hdfs dfs -chmod a+w /warehouse
    
    
  2. 请注意,我们允许所有用户写入/warehouse目录。这对于允许多个用户使用 Hive 非常重要。另一种方法是将所有 Hive 用户分配到一个组,并将/warehouse所有权更改为该组。

  3. 下载并安装 MySQL JDBC 驱动程序。由于许可证差异,它没有随 Hive 包一起发货,所以您需要从http://dev.mysql.com/downloads/connector/j/下载。打开档案后,使用以下命令将.jar文件复制到 Hive lib目录:

    # cp mysql-connector-java-5.1.25-bin.jar /usr/lib/hive/lib/
    
    
  4. 使用以下命令启动 Hive Metastore】

始终检查错误日志文件以确认服务已经正确启动。默认情况下,可以在/var/log/hive目录中找到 Hive 日志文件。

安装配置单元客户端

在本节中,我们将安装 Hive CLI 并将其链接到 Hive Metastore。Hive 客户端可以安装在集群内的任何机器上,但在大多数情况下,它们安装在专用的 Gateway 服务器上。通常,作为 Hadoop 管理员,您需要向组织内的多个用户提供 Hive 客户端访问。将这些用户隔离在网关机器上可以更容易地控制和管理这些权限。

要安装配置单元客户端,请运行以下命令:

# yum install hive

就像在 Hive Metastore 的情况下一样,您需要将 Hadoop 配置文件复制到客户端机器,以提供对 HDFS 和 MapReduce 的 Hive 访问。

Hive 客户端使用与 Metastore 相同的配置文件hive-site.xml。但是,您不需要将 Metastore 配置文件复制到客户端。Metastore 的整个思想是封装对后端数据库的访问。Hive 客户端不需要访问我们为 Metastore 配置的 MySQL 数据库。只有 Hive Metastore 需要在其配置文件中指定 MySQL 凭据。

相反,您将使用单独的 Hive 客户端配置文件。幸运的是,让 Hive 启动并运行只需要几个核心选项。

首先,您需要指定您将使用远程 Metastore。将以下选项添加到您的 Hive 客户端服务器上的hive-site.xml中:

<name>hive.metastore.local</name>
<value>false</value>

接下来,您需要将 Hive 客户端指向 Hive Metastore 的位置:

<name>hive.metastore.uris</name>
<value>thrift://hive.hadoop.test.com:9083</value>

这两个选项足以让 Hive 客户端运行。要启动配置单元命令行界面,请运行以下hive命令:

# hive
Logging initialized using configuration in file:/etc/hive/conf.dist/hive-log4j.properties
Hive history file=/tmp/root/hive_job_log_88a7e774-cdb5-4d6c-b1eb-77ad36207a91_1397164153.txt
hive>

您可以在屏幕上看到一些关于正在打印的 Hive 日志文件的信息。日志文件的级别和位置可以在hive-log4j.properties文件中调整。

有关创建 Hive 表、编写 HiveQL 查询等的详细信息,您可以参考以下网站的 Hive 文档:https://cwiki.apache.org/confluence/display/Hive/Tutorial

安装配置单元服务器

此时,您应该已经安装并配置了 Hive Metastore 和 Hive 客户端。如果您只打算使用 Hive CLI,这个设置就足够了,但是如果您需要使用 Hive JDBC 或 ODBC 驱动程序提供对应用的访问,则需要安装和配置 Hive Server。这类应用可能包括高级网络界面,如 Beeline 和 BI 工具。这也将允许您从 Python、Perl 和其他语言的程序中访问 Hive。

我们将在用于 Hive Metastore 的物理机器上安装 Hive 服务器,尽管这不是必需的。您可以在集群中的任何其他计算机上安装配置单元服务器。

CDH 存储库中目前有两个版本的 Hive Server:Hive Server 1 和 HiveServer2。我们将安装 HiveServer2,因为它提供并发客户端支持、额外的安全选项和一些其他改进。HiveServer2 是所有新开发发生的地方,为了兼容性,HiveServer1 包含在存储库中。

要安装 HiveServer2,请运行以下命令:

# yum install hive-server2

如果您查看包内容,您会注意到它只提供服务器启动/关闭的脚本。所有必需的二进制文件都已经安装了 Hive 和 Hive Metastore 包。

有几个选项,您需要将其添加到/etc/hive/conf/hive-site.xml文件中,以获得 HiveServer2 支持。首先,我们需要支持并发客户端:

<name>hive.support.concurrency</name>
<value>true</value>

HiveServer2 使用 ZooKeeper 集群来管理表锁,这是正确的并发管理所必需的。我们将把它指向 ZooKeeper 服务器,我们已经在第 2 章为 NameNode HA 安装和配置了 Hadoop :

<name>hive.zookeeper.quorum</name>
<value>nn1.hadoop.test.com:2181,nn2.hadoop.test.com:2181,jt1.hadoop.test.com:2181</value>

因为我们在与 Hive Metastore 相同的机器上安装 HiveServer2,所以我们使用相同的配置文件。如果您决定在单独的机器上安装 HiveServer2,您需要使用hive.metastore.uris选项将其指向 Metastore。

默认情况下,HiveServer2 将使用端口10000,但您可以通过更改/etc/defaults/hive-server2文件中的HIVE_PORT选项来控制这一点。

现在,您可以通过运行以下命令来启动 HiveServer2:

# service hive-server2 start

黑斑羚

黑斑羚是 Hadoop 生态系统的新成员。它的测试版于 2012 年首次推出,第一个稳定版本于 2013 年 6 月发布。即使 Impala 是一个新项目,仍然有很多需要改进的地方,但它试图实现的目标的意义使其在本书中值得一提。Impala 的目标非常远大——为 Hadoop 带来实时查询。Hive 使得在 Hadoop 中使用类似 SQL 的语言来查询数据成为可能,但是在性能方面仍然受到 MapReduce 框架的限制。值得一提的是,像 Stinger(http://hortonworks.com/labs/stinger/)这样的项目致力于显著提高 Hive 的性能,但它仍在开发中。

Impala 绕过 MapReduce,直接在 HDFS 对数据进行操作,以实现显著的性能提升。Impala 大部分是用 C++写的。它使用内存缓冲区来缓存数据,通常操作起来更像并行关系数据库。黑斑羚被设计成与 Hive 兼容。它使用相同的 HiveQL 语言,甚至利用现有的 Hive Metastore 来获取关于表和列的信息。如果您的集群中有现有的 Hive 表,您将能够使用 Impala 查询它们,而无需任何更改。

黑斑羚建筑

黑斑羚由几个部分组成。有一个 Impala 服务器进程,应该运行在集群中的每个数据节点上。它的职责是处理来自客户端的查询,将数据读写到 HDFS,执行连接和聚合任务,等等。由于查询在许多服务器上并行执行,接收用户请求的守护程序成为查询协调器,并同步该特定查询的所有其他节点的工作。

由于 Hadoop 集群中的数据节点或单个 Impala 守护程序可能会不时停机,因此需要持续跟踪集群中所有守护程序的状态。为此,黑斑羚使用了一个 黑斑羚州立商店。如果一些 Impala 服务器没有向状态存储报告,它们会被标记为死亡,并被排除在进一步的查询尝试之外。Impala 服务器可以在没有状态存储的情况下运行,但是如果集群中有故障节点,响应可能会延迟。

此外,Impala 使用了我们在安装 Hive Metastore 部分为 Hive 配置的相同 Metastore 服务。Impala 同时提供了命令行界面和 JDBC/ODBC 访问。

Impala 服务没有额外的硬件要求。Impala 服务器总是运行在数据节点上,因为它们依赖于本地数据访问。Impala 状态存储可以与现有的 Hadoop 服务(如 JobTracker 或备用名称节点)位于同一位置。

安装黑斑羚州立商店

对于我们的集群,我们将在 JobTracker 节点上安装状态存储。Impala 不包含在标准的 CDH 存储库中,因此您需要通过将http://archive . cloudera . com/impala/red hat/6/x86 _ 64/impala/cloudera-impala . repo文件复制到除 NameNodes 之外的所有 Hadoop 节点上的/etc/yum.repos.d/目录中来添加一个新的存储库。

黑斑羚储存库的链接可能会改变。请参考以下网站的 Cloudera 文档了解最新信息:http://www . Cloudera . com/content/Cloudera-content/Cloudera-docs/Impala/latest/Installing-and-use-Impala/ciiu _ prereqs . html

完成后,您可以通过运行以下yum命令来安装 Impala 状态存储:

# yum install impala-state-store

状态存储包仅包含启动脚本,impala 二进制文件将作为依赖 Impala 包的一部分安装。

状态存储不需要太多配置。Impala 不提取现有的 Hadoop 配置文件,而是依赖 HDFS 进行数据访问。这意味着您需要手动将core-site.xmlhdfs-site.xml文件从您的 Hadoop 配置目录复制到/etc/imala/conf目录。

您可以通过编辑/etc/default/impala文件来调整状态存储端口和日志目录。默认情况下,状态存储使用端口24000。我们将保持现状。

要启动状态存储,运行以下命令:

# service impala-state-store start

您需要检查/var/log/impala中的日志文件,以确保服务已经正确启动。

安装黑斑羚服务器

要在数据节点上安装 Impala 服务器,运行以下命令:

# yum install impala-server

这将安装 Impala 二进制文件,以及服务器启动停止脚本。在启动 Impala 服务器之前,需要对数据节点配置进行一些额外的调整。

黑斑羚使用一种叫做短路读数的 HDFS 特征。它允许 Impala 绕过标准的数据节点级别,并能够直接从本地存储中读取文件块。要启用该功能,需要在hdfs-site.xml文件中添加以下选项:

<name>dfs.client.read.shortcircuit</name>
<value>true</value>

<name>dfs.domain.socket.path</name>
<value>/var/run/hadoop-hdfs/dn._PORT</value>

像 Impala 这样的本地 HDFS 客户端将使用套接字路径与数据节点通信。您需要保留dfs.domain.socket.path的值,如这里所示。Hadoop 将用数据节点端口号替换它。

此外,Impala 将尝试独立于数据节点跟踪文件块的位置。以前,名称节点服务只能提供哪个块驻留在哪个服务器上的信息。Impala 更进一步,跟踪这个数据节点的哪些文件块存储在哪个磁盘上。为此,在 CDH 4.1 中引入了一个新的 API。要启用它,您需要在hdfs-site.xml文件中添加以下选项:

<name>dfs.datanode.hdfs-blocks-metadata.enabled</name>
<value>true</value>

<name>dfs.client.file-block-storage-locations.timeout</name>
<value>3000</value>

您需要在所有数据节点上应用上述更改,并重新启动数据节点守护程序,然后才能继续进行 Impala 配置。

我们需要做的下一件事是将 Impala 服务器指向状态存储,这是我们之前在 JobTracker 上配置的。为此,更改/etc/default/impala配置文件中的以下变量:

IMPALA_STATE_STORE_HOST=jt1.hadoop.test.com
IMPALA_STATE_STORE_PORT=24000

Impala 是一个非常消耗内存的过程。目前,它必须在内存中完全执行表连接等操作。如果没有足够的可用内存,查询将被中止。此外,Impala 需要缓存关于现有表、文件和块位置的元数据。要控制 Impala 内存分配的上限,请将–mem_limit=X选项添加到/etc/default/impala中的IMPALA_SERVER_ARGS变量。X将是服务器上可用物理内存的百分比。

要为 MapReduce 任务和 Impala 查询正确分配资源,您需要知道您的集群工作负载概要是什么。如果您知道将有一个 MapReduce 作业与 Impala 查询同时运行,您可能需要将 Impala 内存限制为可用 RAM 的 40%,甚至更少。请做好准备,在这种情况下,某些 Impala 查询将无法完成。如果你计划使用 Impala 作为主要的数据处理工具,你可以分配 70-80%的内存给它。

Impala 服务器以及 Impala 状态存储不重用现有的 Hadoop 配置文件。在启动 Impala 服务器之前,需要将core-site.xmlhdfs-site.xml文件复制到/etc/impala/conf目录中。

要启动英帕拉服务器,运行以下命令:

# service impala-server start

要在命令行中使用 Impala,您需要安装 Impala 命令行界面:

# yum install impala-shell

要启动 Impala shell,请执行以下命令:

# imapla-shell

要连接到 Impala 服务器,在 Impala shell 中运行以下命令:

> connect dn1.hadoop.test.com;
Connected to dn1.hadoop.test.com:21000
Server version: impalad version 1.0.1 RELEASE (build df844fb967cec8740f08dfb8b21962bc053527ef)

请记住,目前 Impala 不处理自动元数据更新。例如,如果您已经使用 Hive 创建了一个新表,您将需要在 Impala shell 中运行一个REFRESH命令来查看更改。

现在,您的一个数据节点上运行着一个功能齐全的 Impala 服务器。要完成安装,您需要将此设置传播到所有数据节点。每个 Impala 服务器都可以接受来自 shell 或应用的客户端请求。接收请求的服务器成为查询协调器,因此在集群中的节点之间平均分配请求是一个好主意。

Impala 仍处于活跃的开发阶段。请务必查看每个新版本的文档,因为 Impala 配置和一般行为的许多方面在未来可能会发生变化。

总结

在本章中,我们学习了安装三个主要的 Hadoop 生态系统项目。Sqoop、Hive 和 Impala 显著提高了集群的可用性。还有很多 Hadoop 生态系统项目,我们无法在本书中涵盖。它们中的大多数都可以在 CDH 存储库中找到,因此您可以在需要时安装它们。在下一章中,我们将介绍 Hadoop 安全选项。公司将其最关键和最敏感的数据托付给 Hadoop,因此了解如何确保这些数据的安全非常重要。

四、保护 Hadoop 安装

在本章中,我们将探讨与 Hadoop 安全相关的基本主题。如您所知,Hadoop 由多个组件组成,保护 Hadoop 集群意味着保护这些组件中的每一个。这使得保护 Hadoop 集群成为一项不平凡的任务。在本章中,我们将涵盖以下主题:

  • Hadoop 安全概述
  • HDFS 安全
  • MapReduce 安全性
  • Hadoop 服务级别授权
  • Hadoop 和 Kerberos

Hadoop 安全概述

最初,Hadoop 被设计成在一个可信的环境中运行。假设所有集群用户都可以被信任来正确地呈现他们的身份,并且不会试图获得比他们拥有的更多的权限。这导致了简单安全模式的实现,这是 Hadoop 中的默认身份验证系统。在简单的安全模式下,Hadoop 信任操作系统来提供用户的身份。与大多数关系数据库不同,Hadoop 没有任何集中的用户和特权存储。没有允许 Hadoop 正确验证用户身份的用户/密码概念。相反,Hadoop 接受由操作系统表示的用户名,并信任它,而无需任何进一步的检查。这种模式的问题是有可能模拟另一个用户。例如,一个流氓用户可以使用一个定制的 HDFS 客户端,而不是使用 Java 调用来识别当前的操作系统用户,将它替换为根用户,并获得对所有数据的完全访问权限。在某些情况下,简单安全模式仍然是首选,尤其是当集群处于受信任的环境中,并且只有少数用户可以访问系统时。

对于许多组织来说,这种宽松的用户授权方式是不可接受的。公司开始在他们的 Hadoop 集群中存储敏感数据,并关注能够在大型多租户环境中隔离数据。为了解决这个问题,Hadoop 引入了对 Kerberos 的支持。 Kerberos 是一种成熟的身份验证协议。Kerberos 服务器用作外部用户的存储库,允许用户使用密码进行身份验证。成功通过 Kerberos 身份验证的用户将被授予访问票证。在这张票有效期间,他们可以使用 Hadoop 服务。Kerberos 支持不仅针对外部集群用户,也针对所有内部服务。这意味着所有数据节点、任务跟踪器、名称节点等守护程序都需要通过 Kerberos 身份验证才能加入集群。Kerberos 为 Hadoop 提供了更强的安全模式,但它也在集群的配置和维护方面带来了额外的挑战。

HDFS 安全

HDFS 模仿了 Unix 风格的文件系统权限模式。每个文件和目录都有一个用户、组所有者和一组权限。这些权限可以允许或禁止用户访问给定的目录或文件。例如:

# hdfs dfs -ls /
drwxr-xr-x   - mapred mapred        0 2013-05-27 04:40 /jobtracker
drwxrwxrwt   - hdfs   supergroup    0 2013-06-08 16:03 /tmp

可以看到/jobtracker目录归用户mapred所有,只有这个用户才允许将文件写入这个目录,而每个用户都可以读取这个目录中的文件。另一方面,虽然/tmp目录归hdfs用户所有,但每个人都可以在那里读写文件。这模仿了 Unix 类型的/tmp目录的行为。

请注意,在/tmp目录上也设置了一个粘性位。这将只允许文件所有者删除和重命名那里的文件。

为了操作文件权限,HDFS 提供了类似于 Unix 环境的命令。例如,让我们为用户alice创建一个主目录,并更改目录所有权:

[root@nn1 ~]# hdfs dfs -mkdir /user/alice/
mkdir: Permission denied: user=root, access=WRITE, inode="/user":hdfs:hdfs:drwxr-xr-x

这个创建目录的尝试失败了,我们得到一个错误,因为 Linux 根用户在 HDFS 没有适当的权限。

在 CDH,hdfs用户相当于superuser——拥有最高级别特权的用户。这是因为所有的 HDFS 守护进程都在hdfs用户下运行。

区分用户“hdfs”和 hdfs 命令行工具很重要。

要修复这个错误,我们将切换到hdfs用户:

# sudo su - hdfs
$ hdfs dfs -mkdir /user/alice/
$ hdfs dfs -chown alice:alice /user/alice/

您也可以使用语法类似于 Linux 中语法的–chmod 命令来更改文件和目录的访问模式。

操作系统用户和您分配给 HDFS 的权限之间没有直接联系。当您更改目录或文件所有权时,Hadoop 不会检查用户是否真的存在。你需要小心用户名的正确拼写,因为你不会从 HDFS 得到用户不存在错误。

MapReduce 安全

MapReduce 安全性关注于作业提交和管理。默认情况下,它是完全开放的。任何有权访问作业跟踪器服务的用户都可以提交、查看和终止作业。这种行为对于开发或概念验证集群来说是可以接受的,但是对于多租户生产环境来说显然是失败的。

为了解决这些问题,Hadoop 支持 集群管理员队列管理员的概念。集群和队列管理员是拥有查看和操作正在运行的作业的权限的 Linux 用户和组。例如,管理员可以更改作业优先级或终止任何正在运行的作业。

如果你还记得的话,在第 2 章安装和配置 Hadoop 中,我们已经将我们的 JobTracker 配置为使用 FairScheduler 。使用此调度程序,您可以定义一组固定的作业队列,并允许特定的用户和组向它们提交作业。每个队列还可以配置一个自定义的管理员列表。

要启用权限模型,您需要对您的mapred-site.xml文件进行一些更改:

<name>mapred.acls.enabled</name>
<value>true</value>

接下来,需要设置集群级别mapred管理员:

<name>mapred.cluster.administrators</name>
<value>alice,bob admin</value>

在前面的例子中,我们已经为名为alice,bob的 Linux 用户和管理 Linux 组中的所有用户分配了管理员访问权限。您可以使用逗号分隔的列表指定多个用户和组。用户列表必须用空格与组列表分开。“*”符号表示每个人都可以对 MapReduce 作业执行管理任务。

生产 Hadoop 集群经常执行组织内不同组提交的作业。这些群体可以有不同的优先事项,他们的工作可以有不同的重要性。例如,可以有一个生产组,其作业为业务关键型应用提供数据,还有一个分析组执行后台数据挖掘。您可以定义哪个用户可以访问哪个队列,以及为每个队列分配单独的管理员。

首先,您需要在mapred-site.xml中创建一个命名队列列表:

<name>mapred.queue.names</name>
<value>production,analytics</value>

每个作业队列的权限在一个名为mapred-queue-acls.xml的单独文件中定义。该文件需要放在 JobTracker 上的/ etc/hadoop/conf目录中。CDH 提供了一个模板文件mapred-queues.xml.template,您可以将其用作基线。

该文件的格式与其他 Hadoop 配置文件略有不同。以下是一个可能的示例:

<queues>
 <queue>
   <name>production</name>
    <acl-submit-job> prodgroup</acl-submit-job>
    <acl-administer-jobs>alice </acl-administer-jobs>
 </queue>
 <queue>
   <name>analytics</name>
    <acl-submit-job> datascience</acl-submit-job>
    <acl-administer-jobs>bob </acl-administer-jobs>
 </queue>
</queues>

在前面的例子中,我们定义了两个队列:productionanalytics。每个队列都支持可以向该队列提交作业的用户和组列表,以及管理员列表。对于production组,我们只有使用acl-submit-job选项的prodgroup Linux 组的有限提交权。请注意,没有列出单个用户,组名前有一个前导空格字符。我们选择alice作为生产队列管理员,并使用acl-administer-jobs选项进行指定。该特定配置在管理员列表中没有组,因此用户名后面有一个空格字符。

mapred-site.xml进行所有更改后,需要重新启动 JobTracker 服务。对mapred-queue-acls.xml的更改会自动获得,无需重启。

要向给定队列提交作业,可以使用mapred.job.queue.name选项。例如,要将WordCount作业提交到分析队列中,可以使用以下命令:

# hadoop jar /usr/lib/hadoop-0.20-mapreduce/hadoop-examples.jar wordcount -Dmapred.job.queue.name=analytics /tmp/word_in /tmp/word_out 

通过运行以下mapred命令,您可以监控分配给特定队列的活动队列和作业列表:

# mapred queue –list
# mapred queue -info analytics –showJobs

Hadoop 服务级别授权

除了 HDFS 权限模型和 MapReduce 作业队列管理,您还可以指定哪些用户和组可以访问不同的集群服务。这个可以用来限制对 HDFS 的访问,并只向一小部分用户提交作业。

要启用服务级别授权,您需要在core-site.xml配置文件中添加以下选项:

<name>hadoop.security.authorization</name>
<value>true</value>

类似地,对于 MapReduce 队列权限,服务级别 ACL 在一个名为hadoop-policy.xml的单独文件中定义。CDH 在/etc/hadoop/conf目录中提供了这个文件的示例,默认情况下,它是完全开放的(所有用户都可以访问所有服务)。

服务级别授权和 HDFS 或 MapReduce 权限之间的区别在于执行这些检查的顺序。在用户开始与 HDFS 或 MapReduce 服务通信之前,会对服务级别执行权限检查。这对于完全阻止某些用户或组进入集群非常有用。

假设我们想将 HDFS 和 MapReduce 的访问权限限制在名为hadoopusers的 Linux 组。为此,我们需要在hadoop-policy.xml中设置以下选项:

<name>security.client.protocol.acl</name>
<value> hadoopusers</value>
<name>security.client.datanode.protocol.acl</name>
<value> hadoopusers</value>

上述选项将阻止hadoopusers组以外的用户与 HDFS 守护程序通信。这些值的格式与我们用于 MapReduce 权限的格式相同。请注意“hadoopuser”字符串前有一个空格字符。

要仅允许hadoopuser组的成员提交 MapReduce 作业,请指定以下选项:

<name>security.job.submission.protocol.acl</name>
<value> hadoopusers</value>

您可以在hadoop-policy.xml文件中指定更多可能的选项,基本上限制对任何 Hadoop 服务的访问,包括内部通信协议。例如,您可以只允许hdfs用户用于数据节点间通信,以及名称节点通信。所有这些选项都在示例hadoop-policy.xml文件中进行了概述,因此您可以在必要时进行调整。

Hadoop 和 Kerberos

正如您在前面几节中看到的那样, Hadoop 提供了限制对各种资源和服务的访问的所有组件。尽管如此,仍然有一块拼图不见了。由于 Hadoop 不维护任何内部用户数据库,它必须完全信任操作系统提供的用户身份。虽然基于 Linux 的操作系统使用密码或公钥/私钥对对用户进行身份验证,但一旦用户登录,Hadoop 就无法正确验证他/她的身份。在早期版本的 Hadoop 中,HDFS 和 MapReduce 客户端执行相当于whoami shell 命令来获取用户的身份。

这是一种非常不安全的方式,因为它允许一个流氓用户用一个自定义脚本替换whoami命令,该脚本将返回它喜欢的任何用户名。

在最新版本的 Hadoop 中,检索用户身份的代码被更改为使用 Java SecurityManager API,但这种方法仍然存在各种安全问题。您可以更改客户端源代码以使用任何身份,并使用此更改后的程序连接到群集。还有其他未经授权访问群集的可能性。攻击者可能会拦截并改变客户端和 Hadoop 服务之间的通信流量,因为它没有加密。

为了解决这个问题,Hadoop 支持通过外部 Kerberos 协议进行身份验证。Kerberos 是一种协议,旨在允许参与者通过不安全的网络安全地识别和验证自己。这个协议有不同的实现,但是我们将关注 MIT Kerberos

Kerberos 概述

在我们讨论用 Hadoop 实现 Kerberos 身份验证所需的步骤之前,值得简要概述一下该协议。Kerberos 是一种客户端-服务器协议。它由 重点配送中心 ( KDC )以及客户端程序组成。

反过来,KDC 由几个部分组成。认证服务器 ( AS )负责验证用户身份并签发赠票单 ( TGT )。 AS 有一个用户密码的本地副本,每个 TGT 都用这个密码加密。当客户端收到 TGT 时,它会尝试使用密码解密。如果用户提供的密码和 AS 存储的密码匹配,那么 TGT 就可以被成功解密和使用。解密后的 TGT 用于从出票服务 ( TGS )获取认证票。此票证用于针对所有需要的服务对用户进行身份验证。

在 Kerberos 术语中,用户被称为主体。主体由以下三部分组成:

  • 主要组件:它本质上是一个用户名。
  • 实例组件:可以用于为同一个用户识别不同的角色,或者在 Hadoop 的情况下识别不同服务器上的同一个用户。
  • 领域组件:可以把想象成 DNS 中的一个领域。

这里有一个 Kerberos 主体的例子:

alice/dn1.hadoop.test.com@HADOOP.TEST.COM

这就是从其中一个数据节点连接的用户如何向 KDC 展示自己。

以下是用户使用 KDC 执行身份验证并接收 TGT 的方式:

[alice@dn1]$ kinit
Password for alice@HADOOP.TEST.COM:
…

通过这种方式获得的票证将缓存在本地文件系统中,并且在 KDC 管理员指定的期限内有效。通常,这个时间范围是 8 到 12 个小时,因此用户不必为每个操作输入密码。为了能够正确识别领域,需要在服务器上安装 Kerberos 客户端程序,并且需要在/ etc/krb5.conf文件中提供配置。

Hadoop 中的 Kerberos

当 Hadoop 配置了 Kerberos 支持时,所有集群交互都需要首先通过 KDC 认证。这不仅适用于集群用户,也适用于所有 Hadoop 服务。启用 Kerberos 支持后,数据节点需要有一个合适的票证才能与名称节点通信。

这使初始部署变得复杂,因为您需要为每个 Hadoop 节点上的每个服务生成主体,并为每个集群用户创建主体。由于 Hadoop 服务不能交互提供密码,它们使用预生成的密钥表文件,这些文件放置在每台服务器上。

创建所有主体并在所有服务器上分发 keytab 文件后,您需要调整 Hadoop 配置文件以指定主体和 keytab 文件的位置。

此时,您应该决定是否需要在集群上实现 Kerberos。根据环境和集群中存储的数据类型,您可能会发现操作系统提供的基本身份验证在您的情况下已经足够。如果您有严格的安全要求,实现 Kerberos 支持是目前唯一可用的解决方案。请记住,启用后,Kerberos 会影响集群中的所有服务。比如说,只为外部用户实现部分支持是不可能的。

配置 Kerberos 客户端

我们将不回顾 KDC 的安装和配置,因为这本身就是一个巨大的话题。我们将假设您安装并配置了专用的麻省理工学院 Kerberos 版本 5,并且您拥有 KDC 管理员帐户权限。

您需要做的第一个任务是在所有服务器上安装和配置 Kerberos 客户端。要安装客户端程序,请运行以下命令:

# yum install krb5-workstation.x86_64

安装客户端后,您需要编辑/ etc/krb5.conf文件,并提供在 KDC 上配置的 Hadoop 领域。我们将在以下所有示例中使用HADOOP.TEST.COM领域。在这种情况下,领域的名称并不重要,如果您愿意,您可以选择不同的名称。在生产设置中,您可能希望对不同的集群使用不同的领域,例如生产和质量保证。

生成 Kerberos 主体

我们将为 HDFS、MapReduce 和 HTTP 服务生成主体和 keytab 文件。需要 HTTP 主体来支持作为 HDFS 和 MapReduce 守护进程一部分的内置 web 服务,并向用户公开一些状态信息。

我们将演示如何为一个数据节点生成这些主体,因为数据节点需要指定 HDFS、MapReduce 和 HTTP 主体。您需要对群集中的所有主机重复此过程。

类型

自动生成委托人

您可以轻松地编写命令脚本来创建 Kerberos 主体和生成 keytab 文件,并将它们应用于所有服务器。这将帮助你避免错别字和错误。

登录 KDC 服务器,切换到根用户,执行以下命令:

# kadmin.local
Authenticating as principal root/admin@HADOOP.TEST.COM with password.

省略了一些命令行输出。

# kadmin.local
Authenticating as principal root/admin@HADOOP.TEST.COM with password.
addprinc -randkey HTTP/dn1.hadoop.test.com@HADOOP.TEST.COM
addprinc -randkey hdfs/dn1.hadoop.test.com@HADOOP.TEST.COM
addprinc -randkey mapred/dn1.hadoop.test.com@HADOOP.TEST.COM

上述命令将生成三个带有随机密码的主体。我们还需要为hdfsmapred主体生成 keytab 文件。为此,在kadmin.local控制台中执行以下命令:

xst -norandkey -k hdfs.keytab hdfs/dn1.hadoop.test.com@HADOOP.TEST.COM HTTP/dn1.hadoop.test.com@HADOOP.TEST.COM
xst -norandkey -k mapred.keytab mapred/dn1.hadoop.test.com@HADOOP.TEST.COM HTTP/dn1.hadoop.test.com@HADOOP.TEST.COM

前面的命令将生成两个文件:hdfs.keytabmapred.keytab。将这些文件复制到适当的服务器,并将其放入/etc/hadoop/conf目录。要保护 keytab 文件,请相应地将文件所有权更改为hdfs:hdfsmapred:mapred。确保只允许这些用户读取文件的内容。

在进入下一步之前,您需要确保生成了所有节点的所有主体,并将 keytab 文件复制到所有服务器。

为 HDFS 启用 Kerberos

要启用 Kerberos 安全性,请将以下选项添加到core-site.xml 配置文件中:

<name>hadoop.security.authentication</name>
<value>kerberos</value>

该变量的默认值为simple,禁用 Kerberos 支持。确保将core-site.xml中的更改传播到群集中的所有服务器。

要为 HDFS 配置 Kerberos 支持,您需要在hdfs-site.xml文件中添加以下选项。将此文件复制到群集中的所有 HDFS 服务器非常重要。Kerberos 身份验证是双向的。这意味着,例如,数据节点需要知道名称节点通信的主体。

<name>dfs.block.access.token.enable</name>
<value>true</value>

<name>dfs.namenode.kerberos.principal</name>
<value>hdfs/_HOST@HADOOP.TEST.COM</value>

<name>dfs.datanode.kerberos.principal</name>
<value>hdfs/_HOST@HADOOP.TEST.COM</value>

<name>dfs.namenode.kerberos.internal.spnego.principal</name>
<value>HTTP/_HOST@HADOOP.TEST.COM</value>
<name>dfs.datanode.kerberos.http.principal</name>
<value>HTTP/_HOST@HADOOP.TEST.COM</value>

<name>dfs.journalnode.kerberos.principal</name>
<value>hdfs/_HOST@HADOOP.TEST.COM</value>

<name>dfs.journalnode.kerberos.internal.spnego.principal</name>
<value>HTTP/_HOST@HADOOP.TEST.COM</value>

上述选项指定了所有与 HDFS 相关的主体。此外,由于我们已经配置了名称节点高可用性,我们还为日志节点指定了主体。这些选项中的_HOST 令牌将在运行时被服务器的完全限定主机名替换。

接下来,我们需要为 HDFS 主体提供 keytab 文件的位置:

<name>dfs.namenode.keytab.file</name>
<value>/etc/hadoop/conf/hdfs.keytab</value>

<name>dfs.datanode.keytab.file</name>
<value>/etc/hadoop/conf/hdfs.keytab</value>

<name>dfs.journalnode.keytab.file</name>
<value>/etc/hadoop/conf/hdfs.keytab</value>

其中一个与 Kerberos 没有直接关系的安全要求是在特权端口上运行数据节点服务。特权端口是数字低于 1024 的端口。这样做是为了防止流氓用户编写复杂的 MapReduce 作业,将自己作为有效的数据节点呈现给集群。启用安全性后,您必须在配置文件中进行以下更改:

<name>dfs.datanode.address</name>
<value>0.0.0.0:1004</value>
<name>dfs.datanode.http.address</name>
<value>0.0.0.0:1006</value>

最后,您需要创建一个/etc/default/hadoop-hdfs-datanode文件,内容如下:

export HADOOP_SECURE_DN_USER=hdfs
export HADOOP_SECURE_DN_PID_DIR=/var/lib/hadoop-hdfs
export HADOOP_SECURE_DN_LOG_DIR=/var/log/hadoop-hdfs
export JSVC_HOME=/usr/lib/bigtop-utils/

为 MapReduce 启用 Kerberos

需要应用于mapred-site.xml的变化与我们已经为 HDFS 做的非常相似。我们需要为作业跟踪器、任务跟踪器和嵌入式网络服务器提供主体和键标签文件位置:

<name>mapreduce.jobtracker.kerberos.principal</name>
<value>mapred/_HOST@HADOOP.TEST.COM</value>

<name>mapreduce.jobtracker.kerberos.http.principal</name>
<value>mapred/_HOST@HADOOP.TEST.COM</value>

<name>mapreduce.tasktracker.kerberos.principal</name>
<value>HTTP/_HOST@HADOOP.TEST.COM</value>

<name>mapreduce.tasktracker.kerberos.http.principal</name>
<value>HTTP/_HOST@HADOOP.TEST.COM</value>

<name>mapreduce.jobtracker.keytab.file</name>
<value>/etc/hadoop/conf/mapred.keytab</value>

<name>mapreduce.tasktracker.keytab.file</name>
<value>/etc/hadoop/conf/mapred.keytab</value>

说到安全性,Hadoop 的 MapReduce 部分的一个特点是,用户代码是由 TaskTracker 在一个单独的 JVM 中启动的。默认情况下,这个单独的进程是在启动 TaskTracker 本身的用户下运行的。这可能会为用户提供他或她需要的更多权限。启用安全性后,任务跟踪器会将进程的所有权更改给不同的用户。这将是启动作业的用户。为了支持这一点,需要添加以下选项:

<name>mapred.task.tracker.task-controller</name>
<value>org.apache.hadoop.mapred.LinuxTaskController</value>

<name>mapreduce.tasktracker.group</name>
<value>mapred</value>

此外,需要在/etc/hadoop/conf中创建一个单独的taskcontroller.cfg文件。此文件将指定允许在此群集上启动任务的用户。以下是我们群集的文件内容:

mapred.local.dir=/dfs/data1/mapred,/dfs/data2/mapred,/dfs/data3/mapred,/dfs/data4/mapred,/dfs/data5/mapred,/dfs/data6/mapred  
hadoop.log.dir=/var/log/hadoop-0.20-mapreduce
mapreduce.tasktracker.group=mapred
banned.users=mapred,hdfs,bin
min.user.id=500

在安全模式下运行时,taskstracker 会在不同的用户下启动不同的作业。我们需要在taskcontroller.cfg中指定本地目录的位置,以允许任务跟踪器正确设置权限。我们还指定了不允许使用banned.users选项执行 MapReduce 任务的用户。这是为了避免特权用户绕过安全检查并访问本地数据。min.user.id 选项将基于同样的原因禁止任何 id 小于 500 的特权用户(特定于 CentOS)提交 MapReduce 作业。

在所有节点上传播完这些配置文件后,您需要重新启动群集中的所有服务。密切关注日志文件中的消息。正如您所看到的,配置一个安全的 Hadoop 集群并不是一项简单的任务,涉及到很多步骤。仔细检查所有服务是否正常工作是很重要的。

总结

在本章中,我们回顾了 Hadoop 中使用的身份验证和授权原则。我们已经讨论了 HDFS 权限模型,以及 MapReduce 访问控制列表。默认的 Hadoop 安全策略容易受到各种攻击。我们已经回顾了如何在 Hadoop 中配置 Kerberos 支持以符合企业级安全要求。

在下一章中,我们将重点关注 Hadoop 集群的运行状况和性能。

五、监控 Hadoop 集群

每个生产系统都需要一个计划周密的监控策略;因此,Hadoop 集群也需要它。考虑到所涉及的多个组件和组成集群的多台机器,这不是一项简单的任务。Hadoop 提供了关于其组件内部状态的各种各样的度量标准,但是还没有现成的工具来监控和警告这些度量标准。在本章中,我们将概述监控策略,以及您可以用来实现它的工具。

监控策略概述

Hadoop 监控策略不同于您可能用于传统数据库的策略。当您拥有数百台服务器的集群时,各种组件的故障成为常态。如果您将单个数据节点的故障视为紧急情况,您的监控系统很可能会因虚假警报而过载。

相反,重要的是概述哪些组件是关键的,哪些组件的故障是可以容忍的(在一定程度上)。对于关键组件,您需要定义规则,这些规则会立即提醒呼叫人员。对于非关键组件,定期报告整体系统状态就足够了。

您应该已经对 Hadoop 组件有了一个概念,这些组件的故障应该被视为紧急情况。名称节点或作业跟踪器的故障将使群集不可用,应立即进行调查。即使您为这些组件配置了高可用性,找出问题的根本原因仍然很重要。这将有助于您防止将来发生类似的问题。如果您已经按照我们的说明为名称节点设置了自动故障转移的高可用性,那么为所有相关组件提供适当的监控是非常重要的。

您需要确保足够多的日志节点启动并运行,为名称节点日志提供法定数量,并监控动物园管理员集群状态。除了给定服务的完全失败之外,您还需要监控一些健康指标,以便能够预防灾难。名称节点和日志节点上的可用磁盘空间,以及总群集容量和当前使用情况等都是您应该监控的最关键指标之一。

从监控的角度来看,工作节点是集群的非关键部分。Hadoop 可以容忍多个工作节点的故障,并且仍然保持集群可用。重要的是要监控数据节点和任务跟踪器的哪个部分可用,并根据此指标配置监控规则。例如,一个或两个工作节点的故障可能不需要运营团队立即关注。另一方面,30%的工作节点出现故障会影响集群可用性,这可能是更大问题的征兆。这可能是由硬件故障或网络中断引起的。

Hadoop 没有自带任何内置的监控系统。最常见的做法是使用开源监控系统(如 Nagios)来发出警报,使用 Ganglia 等工具来获取趋势和历史信息。在接下来的部分中,我们将回顾 Hadoop 服务揭示的指标以及如何访问它们。我们还将研究如何将这些指标与现有的监控系统相结合。

Hadoop 指标

大多数 Hadoop 组件通过度量子系统显示其内部组件的状态。这个想法是保留特定于给定 Hadoop 进程的计数器,并根据配置将它们重定向到适当的消费者。

Hadoop 度量子系统有几个版本。旧的称为 metrics1 (或者仅仅是 metrics),新的称为 metrics2。Metrics2 从 CHD4 开始提供,我们将重点关注这个版本。

Metrics2 有一个关于源、汇、和上下文的概念。一个是任何记录内部统计数据的组件,比如 NameNode 或 JobTracker。来源收集各种上下文中的指标。例如,NameNode 可以通过 jvm 上下文揭示它正在运行的 JVM 的信息,通过 DFS 上下文揭示 HDFS 状态的信息,以及通过 rpc 上下文揭示 RPC 的信息。 Sink 是度量的消费者。接收器可以是文本文件、特定监控系统的文件等等。

默认情况下,Hadoop 组件收集指标,但不提供给任何消费者。要启用特定的接收器,您需要编辑hadoop-metrics2.properties文件。你也可以注意到/etc/hadoop/conf有一个 hadoop-metrics.properties文件。度量子系统的早期版本使用这个。不过,我们将关注 metrics2。

默认情况下,metrics2 配置文件中启用了几个选项:

*.sink.file.class=org.apache.hadoop.metrics2.sink.FileSink
*.period=10

这些配置选项启用了文件接收器,这基本上意味着配置的源将把它们的输出写入文本文件。在这种情况下,指标将每 10 秒采样一次。

例如,要配置要写入文件的名称节点统计信息,您应该在hadoop-metrics2.properties文件中添加以下行:

namenode.sink.file.filename=/var/log/hadoop-hdfs/namenode-metrics.out

您需要重新启动 Hadoop 守护程序来应用这些更改。

一般来说,您不需要将指标写入纯文本文件,除非您计划开发一个自定义脚本来处理它们。相反,我们将使用 Hadoop 服务通过 Java 管理扩展(JMX)揭示的指标。

JMX 指标

大多数 Hadoop 组件都实现了 JMX 接口,以揭示一些关于其内部状态的信息。可以使用诸如 JConsole(http://docs . Oracle . com/javase/6/docs/technotes/guides/management/JConsole . html等工具来探索这些数据,但我们将重点关注获取这些指标的另一种方式——通过 HTTP 接口。

核心 Hadoop 组件有一个嵌入式网络服务器,用于提供一些用户友好的服务状态信息。例如,要查看名称节点状态页面,请访问以下网址— http://nn1.hadoop.test.com:50070。不同的服务使用不同的默认端口,下表提供了简要总结:

|

服务名称

|

HTTP 端口

|
| --- | --- |
| 名称节点 | Fifty thousand and seventy |
| 数据节点 | Fifty thousand and seventy-five |
| 日志节点 | Eight thousand four hundred and eighty |
| 工作跟踪者 | Fifty thousand and thirty |
| 任务跟踪器 | Fifty thousand and sixty |

除了一般状态信息,Hadoop 服务还在/jmx页面公开了 JMX 指标。例如,要获取数据节点指标,请前往http://dn1.hadoop.test.com:50075/jmx。这些指标类似于您将它们流式传输到文本文件时看到的情况,但是是以 JSON 格式提供的。JSON 不仅可读性更强,而且更容易在各种脚本中解析。

/jmx页面上展示的指标被组织在不同的上下文中。其中有相当多的指标,指标的总数令人生畏。但是,我们将只关注几个最重要的指标来进行监控。

以下是从活动名称节点获取的FSNamesystem 上下文的示例(此处未显示所有指标):

{
    "name" : "Hadoop:service=NameNode,name=FSNamesystem",
    "tag.Hostname" : "nn2.hadoop.test.com",
    "MissingBlocks" : 0,
    "CapacityTotalGB" : 62.0,
    "CapacityUsedGB" : 0.0,
    "CapacityRemainingGB" : 48.0,
    "BlocksTotal" : 19,
    "FilesTotal" : 44,
    "PendingReplicationBlocks" : 0,
    "UnderReplicatedBlocks" : 19,
    "CorruptBlocks" : 0,
    "BlockCapacity" : 2097152,
    "TotalFiles" : 44
  }

如您所见,JMX 公开了一些关于 HDFS 状态的重要信息,例如剩余磁盘空间、损坏和复制数据块不足。我们将依靠这些信息来构建我们的监控解决方案。

用 Nagios 监控 Hadoop

有几种方法可以实现 Hadoop 集群的操作监控。诸如 Cloudera、MapR 和 Hortonworks 等 Hadoop 发行版供应商提供了自己的集群监控和管理软件。在大多数情况下,该软件或其某些功能只能通过付费订阅获得。

如果您计划从其中一家供应商处购买支持,那么研究他们的监控系统所提供的功能是值得的。

另一种选择是使用免费的监控框架,如 Nagios。Nagios 检查是可插入的,您可以基于任何可用的度量来定义警报规则。Nagios 是最流行的开源监控系统之一,很有可能您已经在使用它来监控您的 it 基础架构的组件。如果没有,请参考 Nagios 文档了解在http://www.nagios.org/documentation的安装和配置细节。

监测 HDFS

我们可以将监控检查分为主机特定和 Hadoop 特定,以及关键和非关键。特定于主机的检查将包括您通常会在任何 Linux 服务器上检查的内容:磁盘空间、内存使用等。Hadoop 特定检查将基于 Hadoop 服务提供的指标。关键事件的一个例子是作业跟踪器完全失败。在这种情况下,运营团队的随叫随到成员应立即调查并解决问题。非关键检查可视为群集状态的每日报告。一个这样的报告的例子可以是可用数据节点服务器的百分比。

名称节点检查

应在名称节点服务器上配置以下操作系统和主机级检查:

  • 检查服务器是否可访问。这可以通过使用 http://nagiosplugins.org/ T2 的 Nagios 插件包中的 T0 插件很容易地实现。如果您正在为名称节点使用高可用性设置,检查主要和辅助名称节点非常重要。类型:关键
  • 检查名称节点文件系统和编辑日志目录以及操作系统卷的可用磁盘空间。为此,您可以使用 Nagios 插件中的check_disk。Nagios 允许您配置不同级别的警报。您可以将其配置为当检查结果超过一个阈值时进入WARNING状态,当达到另一个阈值时进入CRITICAL状态。类型:关键
  • 确保名称节点服务不会交换很重要。交换可以显著增加 RPC 调用的响应时间,并有效地停止集群。有一个check_swap插件可以做到这一点。类型:关键
  • 监控任何硬件故障警报,尤其是 RAID 运行状况。在上有各种特定于供应商的检查,如 Nagios 插件。类型:关键

一般来说,主机级监控的实现方式与您当前监控其他 Linux 服务器的方式相同。实现 Hadoop 特定的检查就不那么简单了。不同的 Hadoop 指标没有现成的实现。互联网上有几个开源脚本可以解析 JMX 网页的内容,并对不同的指标发出警告。这些脚本不够通用,不足以让您监控所有您可能想要的东西。

因为我们关注的是以 JSON 格式提供的 JMX 网络输出,所以使用您选择的语言编写一个脚本来解析它并提取您感兴趣的信息是很容易的。我们不会关注这些脚本的实现细节,因为它们对于不同的语言是不同的。相反,我们将列出应该监控哪些 JMX 指标。

以下列表描述了应在生产集群上监控的特定于 Hadoop 的检查:

服务级别检查是特定于 Hadoop 进程的检查。让我们看看可以对 HDFS 实施哪些检查:

  • 您可以通过查看名称节点 JMX 输出中的CapacityTotalGB/CapacityUsedGB/CapacityRemainingGB状态变量来监控可用的 HDFS 容量。对 HDFS 能力的监测应在警戒级别和定期报告级别同时进行。您需要知道长期磁盘空间消耗率,以便能够执行适当的容量规划。对这些指标进行警报检查也很重要,以防止失控的用户作业消耗所有群集磁盘空间。类型:关键型和常规型
  • 如果您正在存储大量较小的文件,则有可能在真正用完磁盘空间之前用完名称节点上的可用数据块插槽。为了避免这种情况,您需要监控BlocksTotalBlockCapacity状态变量。类型:关键型和常规型
  • 如果有一个数据块的副本全部损坏,它将被标记为损坏的数据块。群集中此类块的总量在CorruptedBlocks变量中报告。没有固定的阈值可以监控,但理想情况下这个数字应该接近 0。类型:关键
  • 没有任何副本可用的块数在MissingBlocks状态变量中报告。和前面的情况一样,这个数字应该很低。类型:关键
  • 监控集群中可用数据节点的百分比非常重要。这可以通过查看NumLiveDataNodesNumDeadDataNodes状态变量来完成。根据您的集群大小,您可以针对固定数量的死数据节点或活节点与死节点的比率发出警报。例如,您可以设置一个规则,在出现三个以上故障节点时向您发出警报。另一种方法是在不到 70%的节点处于活动状态时发出警报。为此设置常规检查和警报检查是一个好主意。类型:关键型和常规型
  • 当我们配置名称节点时,我们已经指定了这个进程可以消耗的最大内存量。要监控内存使用状态,需要查看HeapMemoryUsage.maxHeapMemoryUsage.used状态变量。如果使用的内存将超过最大名称节点内存限制,进程将因“内存不足”错误而崩溃。监控这些变量比较棘手,因为随着垃圾收集的发生,HeapMemoryUsage.used的值会上下浮动。您可能需要监控一段时间内的平均值,以准确了解当前的内存使用情况。类型:关键

日志节点检查

日志节点是特定于名称节点高可用性实现的服务。没有太多特定于服务的指标需要监控。您需要确保日志节点进程正在运行,不会耗尽内存或磁盘空间,等等。由于日志节点通常与其他服务并置,因此不需要重复已经存在的主机级检查。

以下是要在日志节点上监控的主机级资源列表:

  • 使用 ping 检查服务器是否可访问。类型:关键
  • 检查 editlog 卷上的磁盘空间。类型:关键
  • 检查服务器上的交换使用情况。类型:关键

以下检查特定于日志节点流程:

  • 确保服务正在运行:这可以通过从操作系统角度监控流程,或者确保 JMX 指标页面返回预期结果来实现。类型:关键
  • 监控内存使用情况:和 NameNode 的情况一样,需要查看的状态变量有HeapMemoryUsage.usedHeapMemoryUsage.max。类型:关键

动物园管理员检查

  • ZooKeeper 是一个独立的项目,在 Hadoop 部署中用于各种目的。我们在设置中使用它的原因之一是为了支持带有名称节点高可用性的故障转移过程。如果不跟踪哪个名称节点是主要的,哪个是次要的,可能会出现两个节点都试图更新文件系统状态而导致损坏的情况。

  • ZooKeeper is a distributed system, which is designed to tolerate failure of several nodes. It is critical to monitor how many nodes in ZooKeeper cluster are alive at any given moment.

    如果你想让你的 ZooKeeper 集群容忍 N 台机器的故障,你需要配置 2 * N + 1 台服务器。

  • 不幸的是,ZooKeeper 没有为其内部指标提供类似的 HTTP 接口。相反,您可以使用 telnet 等工具连接到服务端口,并执行特定的命令来打印服务状态指标:

    # telnet localhost 2181
    Trying ::1...
    Connected to localhost.
    Escape character is '^]'.
    mntr
    zk_version  3.4.5-cdh4.3.0--1, built on 05/28/2013 02:01 GMT
    zk_avg_latency  0
    zk_max_latency  196
    zk_min_latency  0
    zk_packets_received  28099
    zk_packets_sent  28097
    zk_num_alive_connections  1
    zk_outstanding_requests  0
    zk_server_state  leader
    zk_znode_count  10
    zk_watch_count  0
    zk_ephemerals_count  1
    zk_approximate_data_size  365
    zk_open_file_descriptor_count  30
    zk_max_file_descriptor_count  1024
    zk_followers  2
    zk_synced_followers  2
    zk_pending_syncs  0
    
    

mntr命令是【ZooKeeper 理解的命令之一,它基本上向你展示了服务状态。如果你连接到集群领导者,你会通过查看zk_synced_followers线看到活跃追随者的数量。如果该指标低于 ZooKeeper 冗余阈值,则应触发警报。

如果您使用专用的 ZooKeeper 服务器,您还需要实现基本的主机级检查。

监控 MapReduce

说到监控当前 Hadoop 实现中的 MapReduce 状态,所有需要的指标都可以在 JobTracker 级别获得。没有理由监视单个任务跟踪器,至少在警报级别上。应定期发送关于存活和死亡任务跟踪器数量的报告,以监控整体框架的运行状况。

作业跟踪器检查

以下是要在作业跟踪器上监控的主机级资源列表:

  • 使用 ping 检查服务器是否可到达 。类型:关键
  • 检查日志和系统卷上的磁盘空间。JobTracker 不会在本地文件系统上保留状态,但是由于磁盘空间不足而无法写入日志文件会导致问题。类型:关键
  • 检查服务器上的交换使用情况。 类型:临界

以下检查特定于作业跟踪器流程:

  • 监控内存使用情况。您可以通过检查HeapMemoryUsage.usedHeapMemoryUsage.max变量来监控作业跟踪器的内存使用情况。类型:关键
  • 检查SummaryJson.nodesSummaryJson.alive状态变量将让您了解在任何给定时刻任务跟踪器的哪个部分可用。该指标没有严格的阈值。即使只有一个任务跟踪器可用,您的作业也会运行,但是性能显然会显著下降。根据您的群集大小选择一个阈值,并根据故障趋势随时间进行调整。类型:关键

如果某些工作节点经常报告性能缓慢或经常失败,JobTracker 可以将它们列入黑名单。您应该通过查看SummaryJson.blacklisted指标来监控黑名单任务跟踪器的总数。类型:关键

用神经节监控 Hadoop

虽然 Nagios 或任何其他运营监控系统会在出现问题时发出警报,但能够绘制各种集群指标并探索趋势也非常有用。 Ganglia 是一个开源软件包,专门设计用于监控大型集群。它通过 web 界面提供对数据的访问,可以跨多台机器聚合度量,等等。

要启用发送到 Ganglia 统计信息收集守护程序的 Hadoop 指标,您需要在/etc/hadoop/conf/Hadoop-metrics2.properties中添加以下选项:

*.sink.ganglia.class=org.apache.hadoop.metrics2.sink.ganglia.GangliaSink31
*.sink.ganglia.period=10
*.sink.ganglia.supportsparse=true
*.sink.ganglia.slope=jvm.metrics.gcCount=zero,jvm.metrics.memHeapUsedM=both
*.sink.ganglia.dmax=jvm.metrics.threadsBlocked=70,jvm

此外,您需要将所有接收器指向您的 Ganglia 收集器服务器:

namenode.sink.ganglia.servers=gangliahost:8649
datanode.sink.ganglia.servers=gangliahost:8649
jobtracker.sink.ganglia.servers=gangliahost:8649
tasktracker.sink.ganglia.servers=gangliahost:8649
maptask.sink.ganglia.servers=gangliahost:8649
reducetask.sink.ganglia.servers=gangliahost:8649

总结

Hadoop 没有提供任何现成的监控功能,但它确实揭示了许多关于其组件内部状态的信息。您可以使用现有的开源工具来监控这些指标,并在关键事件发生时向您发出警报。与传统的数据库系统不同,不是每个组件故障都应该以相同的优先级来处理,在实现监控解决方案时,您应该记住这一点。将检查分为关键组和常规组将允许您以相当大的灵活性监控 Hadoop 集群。

到目前为止,我们一直在讨论如何构建和托管您自己的 Hadoop 集群。在许多使用案例中,拥有和维护完整的 Hadoop 基础架构并不是最佳选择。这种方法的替代方法是使用云基础设施。在下一章中,我们将回顾一下,如果您想在云中托管集群,您可以选择哪些选项。

六、将 Hadoop 部署到云

以前,我们专注于在真实的物理服务器上部署 Hadoop。这是使用 Hadoop 最常见也是普遍推荐的方式。当 Hadoop 集群能够充分利用可用的硬件资源时,它的性能最好。以前,将虚拟化服务器用于 Hadoop 并不被认为是一种好的做法。在过去的几年里,这种情况一直在改变。越来越多的人意识到,在云中运行 Hadoop 的主要好处不是性能,而是在资源调配方面的巨大灵活性。借助云,您可以在短时间内创建由数百个计算机节点组成的大型集群,执行所需的任务,然后在不再需要时销毁集群。在本章中,我们将描述您在云中部署 Hadoop 时的几种选择。我们将重点关注亚马逊 Web 服务 ( AWS )因为它是目前最受欢迎的公有云,同时也为 Hadoop 提供了一些高级功能。

亚马逊弹性 MapReduce

AWS 可能是目前最受欢迎的公共云之一。它允许用户按需快速调配虚拟服务器,并在不再需要时将其丢弃。虽然 Hadoop 最初不是为在这样的环境中运行而设计的,但在许多用例中,为特定任务创建大型集群的能力非常有吸引力。

想象一下,您需要处理应用日志文件并准备要加载到关系数据库中的数据。如果这个任务需要几个小时,并且一天只运行一次,那么没有理由让 Hadoop 集群一直运行,因为它大部分时间都是空闲的。在这种情况下,更实际的解决方案是使用弹性地图缩减 ( EMR )来调配虚拟集群,并在工作完成后将其销毁。

EMR 集群不必每次都被销毁和从头重新创建。您可以选择保持集群运行,并将其用于交互式 Hive 查询,等等。

现在,我们将带您完成使用 EMR 调配 Hadoop 集群的步骤。我们将假设您熟悉主要的 AWS 概念,如 EC2、实例类型、区域等。您可以随时在以下网站查阅 AWS 文档了解更多详细信息:

https://aws.amazon.com/documentation/

安装 EMR 命令行界面

您可以通过不同的方式与 EMR 进行交互。AWS 为其所有服务提供了一个很好的 web 控制台界面。这意味着您不必使用命令行来创建、启动和监控集群。这对于测试和探索来说可能没问题,但是当需要实现一个 EMR 作业作为生产 ETL 过程的一部分时,命令行就派上了用场。

虽然这是 EMR 功能的高级概述,但我们将重点关注使用命令行而不是 web 界面,因为这是您在生产环境中要做的事情。

要安装 EMR 命令行界面,您需要执行以下步骤:

  1. Download CLI and unpack the tools from the website.

    http://aws.amazon.com/developertools/2264

  2. 根据您的平台,您可能需要安装 Ruby。

  3. 创建一个 S3 桶来存储 Hadoop 产生的日志文件。因为在许多情况下,临时 EMR 集群是无人值守运行的,所以您需要一个日志文件的持久位置,以便能够查看状态或调试问题。

  4. 为了能够使用 EMR 命令行界面,您需要准备好您的 AWS 访问密钥标识,并生成密钥对。有关如何获取您的访问密钥的详细信息,请参考 AWS 文档,网址为

  5. 您需要将密钥对.pem文件的权限更改为仅所有者可读:chmod og-rwx emr-keys.pem

  6. 现在,您可以为 EMR CLI 创建一个配置。转到放置命令行界面文件的目录,编辑credentials.json文件,如下所示:

    {
    "access_id": "Your Access Key ID",
    "private_key": "Your AWS Secret Access Key",
    "keypair": "emr-keys",
    "key-pair-file": "/path/to/key-file/emr-keys.pem",
    "log_uri": "s3n://emr-logs-x123/",
    "egion": "us-east-1"
    }
    

此示例配置文件包含启动测试 EMR 集群所需的所有选项。要验证 CLI 是否正常工作,只需使用–version 选项运行即可:

# ./elastic-mapreduce --version
Version 2013-07-08

更多详情可参考的 EMR CLI 文档。

选择 Hadoop 版本

EMR 通过部署和配置 Hadoop 组件,使得启动 Hadoop 集群变得容易。您不必手动下载、安装和配置软件包。另一方面,电子病历提供了相当大的灵活性。您可以通过将参数传递给elastic-mapreduce CLI 来控制集群配置的不同方面。您可以指定的选项之一是使用哪个 Hadoop 版本。为此,您需要将–hadoop-version选项传递给命令行界面。目前,EMR 支持以下 Hadoop 版本:1.0.3、0.20.205、0.20 和 0.18。如果您没有明确指定 Hadoop 版本,EMR 集群将使用最新的 Hadoop 版本启动。

启动 EMR 集群

一旦安装并配置了 CLI 工具,启动一个新的 EMR 集群就非常容易了。以下命令将启动一个 3 节点 Hadoop 集群:

# ./elastic-mapreduce --create --alive --name "EMR Test" \
--num-instances 3 --instance-type m1.small
Created job flow j-2RNNYC3TUCZIO

该命令有几个重要选项。--alive选项告诉 EMR 启动集群,并使其可供用户通过 SSH 连接到服务器,并执行他们可能需要的任何任务。这种方法的替代方法是启动一个集群来执行一个指定的作业,并在完成后自动终止集群。我们将在后面更详细地探讨这个选项。我们还指定了集群的名称、要启动多少台服务器以及要使用哪种类型的 EC2 实例。

该命令将几乎立即执行,但这并不意味着您的集群可以立即使用。EMR 启动集群可能需要几分钟时间。EMR 使用作业流这个术语来描述集群。这背后的想法是,您可以设置许多步骤,例如启动集群、运行 Hive 脚本、保存数据和终止集群。这些步骤形成了作业流程,可以自动执行。在这种情况下,CLI 会打印出我们已经启动的集群的 ID。由于启动集群需要一些时间,您可以使用--describe 选项检查当前状态:

# ./elastic-mapreduce --jobflow j-2RNNYC3TUCZIO --describe

前面的命令提供了许多关于集群的有用信息。输出是一个 JSON 文档,这使得它很容易被各种自动化脚本使用。我们将查看显示集群当前状态的第一个部分:

"ExecutionStatusDetail": {
        "CreationDateTime": 1375748997.0,
        "ReadyDateTime": null,
        "EndDateTime": null,
        "StartDateTime": null,
        "State": "STARTING",
        "LastStateChangeReason": "Starting instances"
      }

您可以看到State 字段具有STARTING状态,这意味着集群尚未准备好使用。如果几分钟后重新运行该命令,您应该会看到State变为WAITING。这意味着您可以连接到集群并开始执行作业。

一旦 EMR 集群处于WAITING状态,您可以通过查看MasterPublicDnsName 字段来识别您的主实例:

"Instances": {
        "SlaveInstanceType": "m1.small",
        "HadoopVersion": "1.0.3",
        "Ec2KeyName": "emr-keys",
        "MasterPublicDnsName": "ec2-107-20-83-146.compute-1.amazonaws.com",
        "TerminationProtected": false,
        "NormalizedInstanceHours": 3,
        "MasterInstanceType": "m1.small",
        "KeepJobFlowAliveWhenNoSteps": true,
        "Ec2SubnetId": null,
        "Placement": {
          "AvailabilityZone": "us-east-1a"
        }

EMR 集群中的主实例是托管 Hadoop NameNode 和 JobTracker 的实例。它也是您访问集群的网关。您可以使用之前配置 CLI 工具时生成的密钥对登录到主实例。

检查集群状态和获取主实例地址的另一种方法是使用 EMR 网络控制台,该控制台位于

https://console.aws.amazon.com/elasticmapreduce/home?地区=美国-东部-1

一旦不再需要,您可以终止 EMR 集群:

# ./elastic-mapreduce --jobflow j-2RNNYC3TUCZIO --terminate
Terminated job flow j-2RNNYC3TUCZIO

临时电磁辐射簇

使用 EMR 的另一种方法是启动临时集群。在这种情况下,您需要准备输入和输出数据位置,以及带有 MapReduce 作业或 Hadoop 流脚本的.jar文件。完成后,您可以启动将处理数据的 EMR 集群(使用 MapReduce 作业提供),将输出写入指定位置,并在工作完成后终止集群。这种方法不需要任何人工交互(一旦准备好输入数据和 MapReduce 作业),并且可以很容易地安排定期运行。

准备输入和输出位置

对于临时 EMR 集群,需要记住的一点是,HDFS 存储也是临时的。这意味着您可以在群集运行时使用 HDFS,但是当 EMR 群集终止时,数据将被删除。EMR 依靠亚马逊 S3 存储服务解决了这个问题。您可以将 S3 桶指定为 EMR 集群的输入和输出源。

在启动 EMR 集群之前,您需要创建 S3 存储桶,用于存储集群的输入/输出数据。根据您的偏好,您可以使用 AWS 网络控制台创建桶或使用 AWS 命令行工具。有关更多详细信息,您可以参考 S3 文档

http://aws.amazon.com/documentation/s3/

对于我们的测试,我们将创建两个桶:emr-logs-x123emr-data-x123

在 S3 桶中,名称必须是全球唯一的。您可能需要调整存储桶名称以满足此规则。

我们将使用emr-data-x123存储桶来存储输入和输出数据,并为我们的 MapReduce 作业存储.jar文件。您需要为输入数据创建input目录,为.jar文件创建jobs目录。在 S3 大桶中创建目录的最简单方法是通过 S3 网络界面。您也可以使用相同的界面将示例文本文件上传到input目录中。

EMR 依赖于 S3,不仅存储输入输出数据,还保存 MapReduce 程序。您可以将.jar文件或流脚本放在 S3 上,并将您的 EMR 集群指向它。在这个例子中,我们将使用 Hadoop 发行版附带的 WordCount 程序。我们将在同一个 emr-data-x123 存储桶中创建目录,并将hadoop-examples-1.0.3.jar文件放在那里。

hadoop-examples.jar文件随所有 Hadoop 发行版一起提供。您需要确保此文件的版本与您计划启动的 EMR 集群的版本相匹配。

我们将使用emr-logs-x123 S3 桶来保存 EMR 作业尝试的日志文件。您可以随时参考这些文件来获取有关您工作的其他信息。

完成所有准备步骤后,您可以使用 EMR CLI 启动群集并执行作业:

# ./elastic-mapreduce --create --name "Word Count JAR Test" \
 --jar s3n://emr-data-x123/mapreduce-jobs/hadoop-examples-1.0.3.jar \
 --arg wordcount \
 --arg s3n://emr-data-x123/input/cont-test.txt \
 --arg s3n://emr-tests-x123/output/

前面命令的参数与在标准 Hadoop 集群上运行 MapReduce 作业时使用的参数非常相似。我们指定了 S3 上.jar文件的位置,要执行的类的名称,以及输入和输出数据目录的位置。此处未指定日志文件的 S3 存储桶的位置,但它是先前在安装 EMR 命令行界面一节中描述的credentials.json配置文件的一部分..

作业完成后,EMR 群集将自动终止,但 S3 目录仍然可用。

您可以在http://docs . AWS . Amazon . com/elastic cmapreduce/latest/developer guide/EMR-plan-file-systems . html上获得更多关于 EMR 和 S3 的详细信息

使用呼呼声

使用 EMR 并不是在云中部署 Hadoop 的唯一方法。如果您更喜欢对群集安装和配置过程进行更多控制,您可能希望探索其他选项。

Hurr是一个 Apache 项目,旨在自动设置和配置云中的 Hadoop 集群。与 EMR 不同,Whirr 不仅可以使用亚马逊 EC2,还可以使用其他云提供商来创建 Hadoop 集群。截至目前,Whirr 支持 EC2 和 Rackspace 云。

安装和配置 Whirr

Whirr 不是另一个 Hadoop 组件。它是一个 Java 程序的集合,帮助你在云中自动创建一个 Hadoop 集群。您可以从项目的网站下载 Whirr,网址为:

http://www.apache.org/dyn/closer.cgi/whirr/

Whirr 不需要安装任何特殊步骤。你可以下载档案,解压,开始使用whirr二进制,可以在bin目录下找到。

有几个配置文件你需要调优后才能使用 Whirr 启动集群:

  1. 首先,你需要在你的主目录中创建~/.whirr/credentials文件。此文件包含将用于使用云提供商调配实例的凭据。如果是亚马逊 EC2,这将是您的访问密钥 ID 和秘密访问密钥。如果您使用 Rackspace 云,您需要提供用户名和应用编程接口密钥。您必须从位于 Whirr 安装目录中的conf/credentials.sample复制模板文件。

  2. 接下来,您需要为集群创建一个配置文件。这里有一个样本test-hadoop.properties文件:

    whirr.cluster-name=testhadoop 
    whirr.instance-templates=1 hadoop-jobtracker 1 hadoop-namenode,5 hadoop-datanode+hadoop-tasktracker 
    whirr.provider=aws-ec2
    whirr.private-key-file=${sys:user.home}/.ssh/id_rsa
    whirr.public-key-file=${sys:user.home}/.ssh/id_rsa.pub
    
  3. 此配置使用 Amazon EC2 定义了一个 7 节点集群。Whirr 指定集群布局的方式非常简单;你只需要在whirr-instance-templates变量中指定你想要的实例数量和类型。您还需要生成一个专用密钥对,用于集群设置。要启动具有此配置的集群,请运行:

    #whirr launch-cluster --config test-hadoop.properties
    
    
  4. 当您完成集群后,您可以通过运行

    #whirr destroy-cluster --config test-hadoop.properties
    
    

    轻松地将其停用

有关可用的 Whirr 选项的更多信息,请参考项目的文档页面,网址为

http://whur . Apache . org/docs/0 . 8 . 1/configuration-guide . html # cloud-provider-config

总结

在本章中,我们回顾了通过使用 AWS 的弹性地图缩减服务以及 Apache Whirr 按需创建 Hadoop 集群的方法。在云中运行 Hadoop 允许用户在短时间内启动大型集群来处理海量数据。您不必维护自己的 Hadoop 基础架构,大多数集群配置步骤都是自动化的。

posted @ 2025-10-01 11:29  绝不原创的飞龙  阅读(42)  评论(0)    收藏  举报