[译] 如何搭建一个易于维护的 Hadoop 集群?

Posted by Deadline on August 29, 2016

15 年 3 月份翻译的文章,最近才校稿发布的 :joy:。那时候也差不多刚开始翻译,错误也蛮多的。

本文由 伯乐在线 - 光光头去打酱油 翻译,hoa33 校稿。未经许可,禁止转载! 英文出处:cloudera。欢迎加入翻译组

学习如何搭建一个易于维护的hadoop集群。

之前,关于部署Apache Hadoop的硬件选择上,我们发表了一些推荐规范。那篇文章就集群规划和部署方面提出了一些不错的想法。比如工作负载分析,CPU、磁盘、内存分配相关的建议。这篇文章我们将对下一实施步骤提供最佳的实践指导:等机器一到,我们就能开始配置机器了。通过这两篇文章,你就可以向着部署一个完美Hadoop生产坏境的目标迈出一大步了。

具体的说,我们会讨论一些比较重要的决定,你必须保证你的网络,磁盘和hosts配置正确。我们还将介绍根据数据集规模如何正确配置磁盘、服务,让资源高效利用以及问题最小化。

Networking: May All Your SYNs Be Forgiven

Hadoop的Java进程,如DataNode得到其所在运行主机的主机名,然后查询这个主机名以确定IP地址。再根据这个IP来确定存储在DNS或/ etc/ hosts中的规范名称。每个主机必须保证其主机名能够进行正向解析,使用其IP地址进行反向解析。此外,集群中的所有主机要能够解析到其他主机。可以使用Linux命令来验证正向和反向解析配置是否正确。

$ host `hostname`
bp101.cloudera.com has address 10.20.195.121
$ host 10.20.195.121
121.195.20.10.in-addr.arpa domain name pointer bp101.cloudera.com

Cloudera Manager使用Python命令来测试配置是否正确。

$ python -c 'import socket; print socket.getfqdn(), socket.gethostbyname(socket.getfqdn())'

这一步配置/etc/hosts文件很容易就能达到目的,但是我们推荐使用DNS。DNS和hosts文件相比,前者更不容易出错,而且修改起来也很方便。主机名应该使用全称域名(FQDN)。启用像TLS加密和Kerberos等安全功能时要注意,使用Kerberos需要用到FQDNs。你可以用下面的命令进行验证

$ hostname --fqdn
bp101.cloudera.com

如果你使用/etc/hosts,那么要确保是正确的顺序。

192.168.2.1 bp101.cloudera.com bp101 master1
192.168.2.2 bl102.cloudera.com bp102 master2

名称缓存服务

Hadoop中使用了大量的网络服务,像DNS、NIS和LDAP。以帮助解决网络问题,缓解共享基础设备的压力,改善名称解析的延迟,有助于守护名称缓存服务进程(NSCD)。NSCD将本地和远程查询的结果缓存在内存中,来减少潜在的网络传输成本。大多数情况下,你可以启用NSCD,让它一直工作着,不用管它。但是如果你运行了Red Hat SSSD,那就需要修改NSCD配置。启动SSSD后,不要用NSCD缓存密码、组或者网络组信息。

链路聚合

也被称为NIC绑定或NIC聚合,这指的是结合网络接口,以提高吞吐量和冗余。具体的设置取决于你的实际环境。

有许多不同的绑定接口的方法。通常情况下,我们建议结合吞吐量来考虑,而不是可用性,但实际上很大程度上取决于接口的数量和内部网络策略。NIC绑定是Cloudera对错误配置的最终武器之一。我们建议在启用绑定之前先验证集群的状态,这将有助于定位到您可能遇到的任何问题。

多连接网络

另一个常被问到的问题是Hadoop能否处理不同网络层的接口。HDFS文档上有一些帮助信息,将Hadoop节点网络从“管理”网络分离出来,从逻辑上来说是有意义的。然后以我们的经验来看,多连接网络在配置和技术支持方面是十分棘手的。痛苦源于Hadoop集成的组件是一个大的生态系统,它们都有自己的网络和绑定端口的设置。新的组件可能无法根据你的设置绑定到特定的网络或者通用的地址上。首先设置你的网络不使用多连接可以避免很多麻烦,并能让你的集群保持在同一个网络中,这是十分有利的。如果你确定一切都设置正确了,然后再回头加入“管理”网络。

VLAN

VLANs不是必须的,但从网络角度看,它们可以使事情变得简单。建议将生产环境部署到专用交换基础设备上,与网络上其他业务通信更加便利。然后确保所有Hadoop业务在一个VLAN中,便于故障诊断和隔离。

Operating System (OS)

Cloudera Manager能够很好的识别操作系统配置中一些常见的问题,但请仔细检查以下配置:

IPTables

一些用户在初始化集群设置时会完全禁用IPTables。在管理方面看这么做无疑使得一些操作变得简单了,但是也增加了一些风险。根据集群中数据的敏感度,适当启用IPTables。Hadoop中的组件占用了许多端口来进行通信,不过我们的文档将有助于定位具体是哪些端口。

SELinux

在Hadoop生态系统中控制所有不同版本的组件,构造一个SELinux策略是具有挑战性的。所以大部分用户都禁用SELinux。如果你对SELinux有兴趣的话,一定要确认你使用的版本是一个受支持的操作系统版本。开始我们建议使用permissive模式,这样就可以捕获输出,定义一个满足需求的策略。

Swappiness

传统方案是将工作节点的swappiness (vm.swappiness)设置为0。不过这个设置在新的内核中有所改变,我们现在建议将其设置为1。(这个帖子里有更多的细节。)

$ sysctl vm.swappiness=1
$ echo "vm.swappiness = 1" >> /etc/sysctl.conf

Limits

默认文件句柄范围(又名ulimit)设置为1024,对大多数发行版可能设置的不够高。Cloudera Manager将会解决这个问题,但是如果你没有使用Cloudera Manager,也要注意这个问题。Cloudera Manager不会改变Hadoop默认设置以外的用户设置。然后,将全局限制提高到64k是有益的。

Transparent Huge Pages (THP)

大部分Linux平台都支持CDh3 中一个名叫Transparent Huge Page压缩的特性,其在Hadoop工作负载方面交互很差,会严重影响性能。Red Hat声称过去在6.4版本中修复了这个bug,但是仍有余留问题会影响到性能。我们建议禁用磁盘碎片整理,除非bug被真正解决。

Red Hat/CentOS: /sys/kernel/mm/redhat_transparent_hugepage/defrag

Ubuntu/Debian, OEL, SLES: /sys/kernel/mm/transparent_hugepage/defrag

$ echo 'never' > defrag_file_pathname

记住将这行命令添加到/etc/rc.local 文件中,使机器重启后仍然有效。

Time

确保所有的主机启用了NTP。

Storage

为集群配置适当的存储层是初始化最重要的一步。配置不当的话后期修改配置会是十分痛苦的,还可能被入侵,通常需要完全重做存储层。

OS, Log Drives and Data Drives

传统的2U服务器配置了16-24个专用的数据磁盘扩展槽,还有一些(通常是两个)扩展槽留给系统盘和日志存储盘。Hadoop的设计有一个简单的原则:“硬件容错。”因此就算一个磁盘一个节点甚至一个机柜发生故障,它也能正常运行。(这一原则真的适合这种大规模的集群,不过让我们面对事实吧。如果你正在阅读这篇文章,你肯定不在Google或者Facebook工作。)

即使正常规模(少于4000个节点),Hadoop也能在硬件故障中很好的维持正常运行,但是仍应该设计一些冗余来减少这些硬件错误。作为一般准则,我们建议对系统盘使用 RAID-1(备份),这样即使数据节点失去系统盘也能很快的恢复。虽然这一步不是绝对必要的,在较小的集群中失去一个节点可能导致计算能力显著的下降。

其他磁盘应该部署为一个JBOD(Just a Bunch Of Disks,磁盘簇),使用ext4分区,操作系统为RHEL6+、Debian 7.x、 或 SLES11+。在某些硬件配置文件,RAID控制器是为一些特定机器构建的,那么RAID-0卷必须使用。这种方法和增加磁盘作为单个spindles具有相同的效果。

有一些安装选项是十分有用的,这些选项在Alex Moundalexis的_Hadoop Operations一书中详细进行了介绍,这就不再重复了。_

Root Reserved Space

默认情况下,ext3、ext4文件系统都会有5%的预留空间给root用户。这对于HDFS数据目录来说是不需要的,不过你可以在创建分区的时候把它调整为0,或者使用mkfs、tune2fs命令将其调整为0。

$ mkfs.ext4 -m 0 /dev/sdb1
$ tune2fs -m 0 /dev/sdb1

文件访问时间

Linux文件系统会维护文件访问记录的元数据,每当一个文件被访问,甚至读取结果等记录都会被写入到磁盘上。这种时间戳被称为atime,Hadoop中应该禁用这项功能。通过修改/etc/fstab中的配置可以设置:

/dev/sdb1 /data1    ext4    defaults,noatime       0

无需重启即可生效。

mount -o remount /data1

目录权限

这是一个小问题,但是还是要注意,在挂载数据磁盘之前将目录的权限设置为700。这样的话一旦数据磁盘被卸载了,没有被操作系统装载的情况下还是可以写入到这个目录的。

LVM, RAID or JBOD

经常有人询问 JBOD 、RAID或者LVM是否必须的。记住整个Hadoop生态系统随着JBOD一起创建的。HDFS是专为大文件顺序读取设计的不可变文件系统。这个目标已经基本达到了,在独立的SATA硬盘上取得了顺序读取的最优性能。总之,RAID通常用来为现有系统增加冗余,HDFS已经内建该特性。实际上在Hadoop上使用RAID反而会降低系统的性能。

RAID-5和RAID-6都增加了奇偶校验的功能。这给标准读/写操作带来显著的开销。独立的SATA硬盘可以连续读/写不用担心奇偶校验,因为它没有这项功能。相比之下,HDFS利用其众多单独挂载点,可以允许单个驱动器/卷在节点故障前出现错误——HDFS不那么神秘的并行I / O武器。在硬盘上设置RAID-5或RAID-6阵列时,会创建一个或几个拥有许多挂载点的巨大硬盘阵列,具体取决于硬盘设置。这些RAID阵列会削弱HDFS原生的数据保护功能,降低顺序读性能,破坏Map tasks的数据局部性。

RAID也会影响在众多挂载点上的其他系统。举个例子,Impala会在每个系统中的spindle 进行线程加速,JBOD环境VS单个巨大的RAID阵列组,哪个环境更适合呢。同样的原因,在Hadoop中使用LVM既不需要也不推荐。

部署环境硬件种类多样化

许多用户定期的采购新的硬件,因为随着数据量和工作量的增长,增加新一代的计算机硬件资源是有意义的。对于含有异构磁盘、内存或CPU配置这样的环境中,Cloudera Manager允许管理员为每个节点或节点组指定内存,YARN容器和Cgroup设置的角色组。

虽然Hadoop能够在硬件规格不一的环境上运行,如果可以的话,我们还是建议工作节点上的配置保持一致。在分布式计算环境中,工作负载分布在各个节点,本地数据优先访问是比较好的。计算资源较少的节点可能会成为瓶颈,而采用混合硬件配置可能会导致SLA窗口期变宽。下面这些值得去思考的:

  • 混合spindle配置—HDFS默认block会已循环的方式放入由dfs.data.dir指定的目录中。例如,有6个1.2T的磁盘,6个600G的磁盘,较小的磁盘最快被填满,导致剩余容量不平衡。使用可用空间策略需要额外配置,并且在这种情况下I / O密集型工作负载可能会受到影响,可能全部被写入到磁盘的一个子集。预先了解这种情况下部署磁盘带来的影响。此外,如果你要部署更加全面的存储节点,记住HDFS的剩余空间是按照百分比算的。

  • 混合内存配置-混合工作节点的可用内存可能会有问题,因为它需要额外的配置。

  • 混合CPU配置-同样的概念;作业可能受到最慢的那个CPU影响,使用新的CPU或者多核CPU的优势完全发挥不出来。

弄清上述几点是很重要的,但是记住Cloudera Manager可以帮助将资源分配到不同的主机,让您轻松地管理和优化配置。

Cloudera Manager Like A Boss

我们强烈建议使用Cloudera Manager来管理Hadoop集群。Cloudera Manager提供了许多有价值的功能,使得管理更加便利。Cloudera Manager文档中关于这块的描述已经很清楚了,但是为了杜绝任何含糊之处,下面就是用 Cloudera Manager部署一个生产Hadoop环境的主要步骤。

  1. 建立外部数据库和预创建需要部署的模式。
create database amon DEFAULT CHARACTER SET utf8;
grant all on amon.* TO 'amon'@'%' IDENTIFIED BY 'amon_password';
create database rman DEFAULT CHARACTER SET utf8;
grant all on rman.* TO 'rman'@'%' IDENTIFIED BY 'rman_password';
create database metastore DEFAULT CHARACTER SET utf8;
grant all on metastore.* TO 'metastore'@'%' IDENTIFIED BY 'metastore_password';
create database nav DEFAULT CHARACTER SET utf8;
grant all on nav.* TO 'nav'@'%' IDENTIFIED BY 'nav_password';
create database sentry DEFAULT CHARACTER SET utf8;
grant all on sentry.* TO 'sentry'@'%' IDENTIFIED BY 'sentry_password';
(记得把上面例子中的密码改掉!)
  1. 安装cloudera-manager-server和cloudera-manager-daemons包/文档。

          yum install cloudera-manager-server cloudera-manager-daemons
    
  2. 根据你的数据类型选择对应的 scm_prepare_database.sh 脚本运行。

    /usr/share/cmf/schema/scm_prepare_database.sh mysql -h cm-db-host.cloudera.com -utemp -ptemp --scm-host cm-db-host.cloudera.com scm scm scm
    
  3. 启动Cloudera Manager服务,并按照提示进行下一步操作。

启动Cloudera Manager服务,并按照提示进行下一步操作。

这是安装 Cloudera Manager最简单的方法,能够让你在20分钟内就绪生产环境部署。

You Play It Out: Services Layout Guide

基于Cloudera Manager的部署,下图展现了一种比较合理的跨集群配置方式。

(点击查看大图)

在较大的集群(50个节点以上)中,可能需要5个管理节点,还有为ResourceManager和NameNode服务提供专用的节点。 此外,为Cloudera Manager、Hive Metastore等等部署外部数据库的情况并不少见,并且额外的HiveServer2或者HMS服务也能部署好。

我们建议每个管理节点分配128GB ,每个工作节点分配256-512GB。内存比较便宜,计算引擎越来越依赖于在内存中执行,额外的内存将被善加利用。

更加深入一些,下面的图表描述磁盘如何适当的映射到各种服务存储组件。

我们特意给Cloudera Manager的数据库使用了LVM,不过RAID 0也是一个不错的选择。

总结

具备了相应的知识再去搭建一个Hadoop集群还是相对简单的。花一些时间去采购合适的基础设施,一开始就正确的配置。按照上述的指导方针部署Hadoop,可以避免那些众多且复杂的配置项,而且最后基本上都能成功。这也能让你像个大牛一样,将时间集中在解决实际业务问题。


There are no comments on this post.