原文:https://tech.ebayinc.com/engineering/enabling-hdfs-federation-having-1b-file-system-objects
作者:Ruchir Shah
翻译:咕噜咕噜大数据
为具有10亿文件系统对象的HDFS启用联邦
在这篇博文中,我们将讨论如何为具有4000多个节点、10亿文件系统对象和170PB存储的集群启用NameNode联邦。
当今成功的组织都是数据驱动的。在eBay,我们有成千上万的工程师、分析师和数据科学家每天处理PB级的数据,以提供无缝的用户体验。通过使用数据,我们可以大规模地执行与连接全球电商的数百万用户。
Apache Hadoop已经成为eBay使用的最流行的大数据分析框架之一。我们使用Hadoop来从数据中产生价值、改善搜索体验、识别和优化相关广告。它的价值还能帮助我们丰富我们的产品目录,并进行点击流分析以了解eBay客户如何利用我们的市场。eBay的分析数据基础设施(ADI)团队负责为所有客户提供高可用性和可靠的Hadoop集群。目前,团队维护着十多个Hadoop集群,范围从数百个节点到数千个节点不等。在这篇博文中,我们探讨了如何在一个拥有4000多个节点、10亿文件系统对象和170PB存储空间的超大Hadoop集群上启用联邦——所有这些都是为了改善我们的客户体验。
问题描述
我们最大的Hadoop集群的文件系统对象数量达到了神奇的10亿。NameNode进程运行要使用200GB内存。一旦文件系统对象的数量超过9亿5千万,我们就开始观察到了各种伸缩性问题。
-
NameNode进程运行使用了内存的几乎90%,导致频繁的Full GC。考虑到我们运行已经使用了200GB内存,几乎已经到达了企业级节点的物理内存限制,没有进一步增加内存的余地。
-
如下图所示,由于GC活动频繁,我们每隔一天就面临一次NameNode故障转移。我们在7天内观察到了6次故障转移,集群变得不稳定。
-
NameNode的总体RPC处理时间显著增加,导致各种SLA作业变慢。
-
NameNode上的RPC线程快用完了,这阻碍了我们向集群添加更多数据节点的能力。
在这种情况下,我们无法提供高可用性和可靠的集群。这迫使我们考虑通过为集群启用联邦,来扩展name service解决方案。下面,我们将讨论视图文件系统(View FileSystem)、命名空间(namespace)选择(最重要的设计决策)以及NameNode联邦的基本思想和成果。最后,我们总结了一些经验和未来的计划。
NameNode联邦
Hadoop NameNode联邦允许name service的水平扩展。它包含几个NameNode或命名空间,每个命名空间的行为相互独立。这些独立的NameNode是联邦的,这意味着它们不需要相互协调。所有的NameNode都使用DataNode作为公共存储,而每个DataNode都注册到集群中的所有NameNode。有关NameNode联邦设计的更多信息,请点击这里。
视图文件系统
视图文件系统(ViewFs)提供了一种管理多个Hadoop文件系统命名空间(或命名空间卷)的方法。它对于具有多个NameNode的集群特别有用,因此在HDFS联邦中有多个命名空间。ViewFs类似于某些Unix/Linux系统中的客户端挂载表。ViewFs可以用来创建个性化的命名空间视图,也可以用于每个集群的通用视图。团队对使用viewFS特别感兴趣,因为它使我们的客户能够在联邦集群上使用现有代码,仅需修改下配置。有关viewFS的更多信息,请点击这里。
选择命名空间
启用联邦的重要决策之一是选择命名空间。如下表所示,我们有两个文件夹可以作为单独的命名空间。其中一个明显的选择是“/PathA”文件夹,它具有最高的存储利用率。然而,NameNode的性能(就RPC处理时间、GC活动等而言)直接取决于它需要存储在内存中的文件系统对象的数量,以及为这些对象执行的操作的数量。如下所示,“/PathB”文件夹仅使用了13.6PB的存储,但它具有最高数量的文件系统对象和正在执行的操作。因此,我们决定创建“/PathB”作为单独的命名空间,并将所有其他剩余的文件夹放在另一个命名空间下。
联邦成果
NameNode堆内存使用情况
联邦最重要的好处是,从内存使用的角度来看,整个NameNode的元数据将会减少。如下图所示,在联邦上线后,现有NameNode的内存使用量从146GB减少到了88-95GB。
NameNode元数据大小
随着堆内存使用量的减少,它能够为每个NameNode进程存储更多的元数据,而对内存的需求却更少。下面的表格和图表显示,目前新的联邦集群与旧集群保存的元数据信息量几乎相同,或是稍微多一点点。
尽管新集群的文件系统对象总数略高于旧集群,但总体堆使用量几乎只有一半。如下图所示,联邦Namenode的堆使用量分别为85GB和96GB。
对于旧的集群,即使在Full GC之后也是182GB。
根据当前的度量标准,我们可以轻松地将新集群的文件系统对象数量增加一倍,而不会影响性能。
每次循环的GC时间
每次GC花费的时间量也影响应用程序的性能。如下图所示,联邦NameNode的GC时间大约为100 ms。
对于旧的集群,时间大约是200 ms。
平均操作时间
对NameNode的平均操作时间有直接影响。Namenode执行的最重要和最昂贵的操作之一是“GetBlocks”。如下图所示,对于联邦Namenode,此操作需要大约50ms到125ms的时间。
对于我们旧集群中的类似操作,它花费了300ms到400ms。
FS Image大小
FS Image包含在NameNode重新启动时使用的所有元数据信息。在NameNode重新启动时,整个Image被加载到内存中,并生成块报告。NameNode保持在安全模式,在此期间不允许进行写操作。这个FS Image大小完全取决于元数据信息。与旧的集群相比,我们现在为联邦NameNode提供了几乎只有一半的FS Image大小,这减少了NameNode的启动时间。
学习
在启用集群联邦时,我们遇到了四个主要问题:
-
在viewFs中默认的移动操作是非常严格的。默认情况下,viewFs不允许跨挂载点对同一个命名空间执行mv操作。这导致了Hive/Spark查询的问题。解决方法是应用HADOOP-14455补丁。
-
Spark/Hive作业执行失败,因为在viewFs上ORC格式写入错误。使用HIVE-10790补丁解决了这个问题。
-
我们观察到由“du”命令引起的更高的iowait,因为HDFS需要扫描两个256* 256的块池,导致更高的系统负载。
-
所有在Hive Metastore中现有的Hive/Spark表的位置必须进行更新。在上线期间,我们将所有位置从hdfs://修改为viewfs://。
如果您的系统中有防火墙,那么请确保为新添加的联邦NameNode解决了所有连接问题。
在启用NameNode联邦之后,我们能够为我们的客户提供一个更加可靠和高性能的集群。我们对命名空间的选择近乎完美,因此我们能够将两个NameNode的堆使用、RPC处理时间和GC时间减少一半。现在,我们有信心在未来添加更多的联邦NameNode,以将集群容量增加到超过5,000个节点。
附录
在eBay,我们使用Kubernetes在同化模式下自定义设计硬件(ODM),在大约5000多个节点上运行Hadoop 2.7.3的自定义构建。