《Hadoop 3 实战指南》(https://book.douban.com/subject/35469504/)是一本很好的 Hadoop 书。Hadoop Logo
1. Hadoop 发展(HDFS)
在Hadoop 1.0时代(包括Hadoop 0.x 和Hadoop 1.x),Hadoop由两部分组成,一部分是作为分布式文件系统的HDFS,另一部分是作为分布式计算引擎的MapReduce(**这里不讨论 MapReduce**)。<br /> HDFS在Hadoop 1.0时代的架构和在后两个时代的基础架构没什么区别,都是采用主/从架构,其中 NameNode为主节点,DataNode 为从节点。Hadoop 的研发团队在研发初期就意识到了 NameNode 的重要性,故将其部分功能拆离出来作为 Secondary NameNode。Secondary NameNode 作为 NameNode 的一个冷备节点,定期将 NameNode 的操作日志合并成集群的状态快照,这样在NameNode重启时可以加快启动速度。HDFS的整体架构如下所示。<br />![图片.png](https://cdn.nlark.com/yuque/0/2021/png/616312/1640139924433-ab727b71-2a5c-4f16-b42f-97b1bacf6cd5.png#clientId=uad86228e-8f30-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=248&id=u849a843a&margin=%5Bobject%20Object%5D&name=%E5%9B%BE%E7%89%87.png&originHeight=496&originWidth=1000&originalType=binary&ratio=1&rotation=0&showTitle=true&size=114670&status=done&style=none&taskId=ub9eca5b1-dd35-4dfd-9e28-1bf5da6b666&title=1.0%20%E6%9E%B6%E6%9E%84&width=500 "1.0 架构")<br /> 在Hadoop 2.0中,支持用两个 NameNode 提供HA功能,这两个 NameNode 分别为 Active NameNode 和StandbyNameNode,前者负责对外提供服务,后者则作为前者的热备节点,它们通过一个共享的存储结构——通常是 QJM(Quorum Journal Manager)实现数据同步。Active NameNode 会将操作日志实时写入QJM中,Standby NameNode 则会从QJM中实时拉取操作日志进行操作回放,并定期生成集群的状态快照,然后同步给Active NameNode。此时因为 Active NameNode 和 Standby NameNode 的数据是实时同步的,所以当Active NameNode发生故障无法提供服务时,Standby NameNode 就能快速进行状态转换,变为 Active NameNode对外提供服务,从而实现故障转移,增强 NameNode 的可用性。<br /> 虽然NameNode的稳定性通过HA得到了增强,但是随着集群规模的扩大,NameNode的内存逐渐成为影响其扩容的主要因素,而Federation为其提供了横向扩展的能力。在Federation中,一个大HDFS集群会被分为N个小HDFS集群,这些小集群既可以共享DataNode的存储空间,也可以对其进行物理隔离。viewfs负责提供N个小集群的整体视图,对普通用户屏蔽内部架构细节,这样也方便集群管理员管理集群。Federation的整体架构如图1-3所示。<br /> ![图片.png](https://cdn.nlark.com/yuque/0/2021/png/616312/1640140032457-0f9a42a5-c912-4432-b591-3515c1b274c3.png#clientId=uad86228e-8f30-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=247&id=u888250e3&margin=%5Bobject%20Object%5D&name=%E5%9B%BE%E7%89%87.png&originHeight=494&originWidth=1000&originalType=binary&ratio=1&rotation=0&showTitle=true&size=160347&status=done&style=none&taskId=uc0be7743-9717-4a22-be27-a142e40b44e&title=2.0%20%E6%9E%B6%E6%9E%84&width=500 "2.0 架构")<br /> Hadoop 3.0 为YARN提供了 Federation,使其集群规模可以达到上万台。此外,它还为 NameNode 提供了多个 Standby NameNode,这使得 NameNode 又多了一份保障。<br /> Hadoop 3.0 对 HDFS 和 YARN 都做了调整。HDFS 增加了纠删码副本策略,与原先的副本策略相比,该策略可以提高存储资源的利用率,用户可以针对具体场景选择不同的存储策略。YARN作为一个资源管理平台,当然重视资源的利用率,它增加了很多新功能。例如,为了更好地区分集群中各机器的特性,新增了Node Attribute功能,此功能与NodeLabel不同。由于越来越多的框架运行在YARN上,为了更好地进行资源隔离,YARN丰富了原先的container放置策略等,具体可以参考官网。<br /> Hadoop 3.0中还新增了两个成员,分别是 Hadoop Ozone 和 Hadoop Submarine。Hadoop Ozone 是一个对象存储方案,在一定程度上可以缓解HDFS集群中小文件的问题。Hadoop Submarine 是一个机器学习引擎,可使 TensorFlow 或者 PyTorch 运行在 YARN 中。
2. HDFS
2.1 文件存储过程
在HDFS中,文件以数据块(逻辑块)的形式存储,一个文件根据数据块的大小被切分为n个数据块。HDFS将元数据信息存储在NameNode中,具体的文件数据块存储在DataNode中。元数据信息包括文件的inode信息、文件和数据块的映射信息、数据块和DataNode的映射信息,这些信息将常驻在NameNode内存中。为了容错,将文件数据块的3个副本冗余存储在多个DataNode中,存储规则为如果当前客户端(发起与HDFS进行交互请求的程序所在的服务器)是DataNode,则将第一个副本写入本机;如果当前客户端不是DataNode,则从集群中随机选一台DataNode(优先从与客户端相同机架上选)存储第一个副本;选好第一个副本的位置之后,其余两个就容易了,第二个副本放在另一个机架上,第三个副本放在与第二个副本同一个机架的另一个DataNode上。
NameNode(NN)是HDFS中的主节点,其主要作用为:
- 负责管理HDFS的命名空间、集群信息和数据块;
- 维护整个HDFS的文件目录树、文件目录的元信息和每个文件对应的数据块列表;
- 接收客户端的操作请求;
-
2.2 HA方案
HDFS提供了两套NameNode的HA方案。这两套方案的主要区别在于共享数据的存储介质不同,一种是基于QJM(Quorum Journal Manager)的,另一种是基于NFS的。在实际生产环境中,第一种用的比较多,功能也较为完善。本节也主要介绍基于QJM的HA。
HA框架包含一些NameNode、ZooKeeper集群和JournalNode集群。在众多NameNode中,只有一个是Active NameNode,其他的都是StandbyNameNode。在正常情况下,只有Active NameNode可以对外提供读写服务,Standby NameNode则通过JournalNode集群实时地同步Active NameNode的最新状态,以及随时准备替代Active NameNode。ZooKeeper集群为Active NameNode的选举提供支撑和记录Active NameNode的信息。2.3 Federation
NameNode需随着集群规模的扩大以及文件量的增加而逐步增加内存,但是机器的内存大小是有上限的,不能一直满足扩展需要,所以只能部署多个HDFS集群。部署多个HDFS集群虽然可以解决NameNode的内存瓶颈问题,但是各个集群之间的数据无法共享,核心数据只能在各个集群中被冗余存储,这就浪费了存储资源,而且多个集群也不利于维护。由于部署多个HDFS集群存在着诸如上述的各种弊端,因此社区提供了Federation(联邦模式)方案。
HDFS Federation将一个高负载的命名空间切分为多个容量较小的命名空间,这些容量较小的命名空间组成了一个HDFS集群,从而缓解了NameNode的内存压力,使NameNode也能向DataNode那样进行横向扩展。
HDFS Federation是将一个大的HDFS集群拆分为多个小HDFS集群,这些小HDFS集群由各自相互独立的NameNode控制,这样就将压力分摊到了多个NameNode上,又由于这些NameNode是相互独立的,因此某个NameNode出现故障并不会影响其他NameNode提供服务。在HDFS Federation模式中,只有DataNode的存储是共享的,每个DataNode都会向所有的命名空间汇报并执行所有命名空间发送的命令。HDFSFederation集群使用clusterId作为集群标识,集群中的多个NameNode通过命名空间进行隔离,一个命名空间对应一个block pool。block pool是数据块的集合,每个blockpool跟命名空间一样,都是单独管理的,这样命名空间每次为新的数据块生成blockId时,均不需要与其他命名空间进行交互。集群中的DataNode上存储了所有block pool里的数据块,这样某个NameNode的故障并不会影响DataNode继续服务于集群中的其他NameNode。2.4 Federation 的实现
HDFS Federation虽然有诸多优点,但用户看到的依然是多个集群,访问不同集群的数据时需要使用不同的绝对路径,因此使用起来极不方便。针对这个问题,社区采用了一种类似于Linux挂载目录的viewfs方案。
viewfs(view file system)可管理多个HDFS的命名空间,因此常被用来与 HDFS Federation 配合使用,除了可以为 Federation 集群提供全局统一的命名空间视图,还可为多个单独的 HDFS 集群提供统一的命名空间视图。基于 viewfs 的 Federation 架构如下所示。
基于viewfs的Federation是以客户端为核心的解决方案,对Hadoop客户端影响较大,在落地应用时有较多的限制,对上层应用模式有较强的依赖。于是社区在Hadoop 3.0中提出了新的用于解决统一命名空间问题的方案:基于Router的Federation。 对用户访问完全透明,访问数据时不需要将schema改变为viewfs,直接访问Router即可。
- 此时 Router 就是 NameNode 的一个代理,用于将请求转发到合适的子集群中。
- 对负载均衡透明,子集群之间可以像在集群内那样对数据进行负载均衡。
对现有代码架构透明,Router和State Store都是完全独立的,HDFS中原组件的代码无须任何修改。
Router 在所有子集群之上新增一个拦截转发层,架构如图2-6所示。拦截转发层新增的两个组件分别为Router和State Store。其中State Store存储远程挂载表(与viewfs相似,但是在客户端之间共享)和有关子集群的负载、空间使用信息。Router实现了与NameNode相同的接口,根据StateStore的元数据信息将客户端请求转发给正确的子集群。
2.5 HDFS EC(纠删码)
HDFS EC是由 Intel 和 Cloudera 提出的一种在不牺牲数据可靠性的情况下大大降低存储开销的方案。在默认的三副本模式下,磁盘的冗余率为200%,其实除了这个,还有一些网络带宽也是200%,而EC的磁盘冗余率最多为50%,同理网络带宽等资源的冗余率也降低了,只是需要一些CPU计算资源作为代价,对于某些场景来说这种代价是值得的。下面看看EC在HDFS中的整体架构。
HDFS EC以插件的模式存在,其架构设计也是采用的主/从结构。主模块为ECManager,是一个管理对象,负责管理BlockGroup、健康检测和协调数据恢复工作,存在于NameNode中。从模块为ECWorker,存在于DataNode中,主要用来监听ECManager发送的请求,例如块的恢复和转变。HDFS EC的架构图如下所示。3. YARN
YARN(Yet Another Resource Negotiator) 是一个通用的资源管理平台,是Hadoop的一个核心项目,能够管理分布式应用以及合理地调度集群资源,可以在保证应用正常运行的前提下,尽可能提高资源利用率。另外,YARN还可以为其他应用提供服务,例如Spark和HBase。
3.1 架构
YARN采用的整体架构也是主/从结构,如图3-1所示。其中,主节点为ResourceManager(RM),主要负责调度整个集群的资源,以及管理运行在YARN上的分布式应用,集群总资源是各个从节点通过心跳进行汇报的。从节点为NodeManager(NM),这也是集群中的计算节点,主要负责管理每个container的生命周期、监控container使用的资源、跟踪节点的健康状态与资源使用情况、执行分配给它的任务以及与ResourceManager保持同步。
在部署过程中只需要指定ZooKeeper的地址,然后在 ResourceManager 服务器上直接启动 ResourceManager 服务本身就可以了,它根据自身特点将这些功能进行了裁剪,将相关功能嵌入到了 ResourceManager 的自身服务中。3.2 故障转移
首先发现故障,其次确定新节点来提供服务。
ResourceManager 通过与 ZooKeeper 之间的心跳来确认服务的健康状态,这点相当于发现故障,后续的主节点选举流程和 NameNode 的流程类似,都是通过 ActiveStandbyElector 实现的。3.3 数据恢复
EmbeddedElector 服务完成 ResourceManager 的状态转换后,原 Active ResourceManager 中的数据并没有同步给新的 Active ResourceManager,这些数据包括集群节点的信息、应用的调度情况以及资源的使用情况。StandbyResourceManager 刚转换为 Active ResourceManager 时,相当于一个刚启动的 Active ResourceManager,对集群信息一无所知,这时各个 NodeManager 会向它注册,这样它就收集到了集群节点的信息以及资源的使用情况。
ResourceManager提供了一个RMStateStore服务,用来保存应用的元数据信息和运行结果信息,例如运行成功、运行失败、应用被杀掉以及一些简短的诊断信息。如果是在安全模式下,还会保存一些安全认证信息。前面这些信息支持多种持久化的存储方式,包括文件系统(HDFS或本地文件系统)、LevelDb和ZooKeeper,其中默认使用的是文件系统,使用较多的是ZooKeeper。
当ResourceManager 发生故障转移或者重启,NodeManager 向新 Active ResourceManager 同步自己的container 信息时,Active ResourceManager 并不会命令 NodeManager 将其上的 container 杀掉,而是让它继续管理container并向自己发送container的状态,ResourceManager会通过这些信息重新构建先前集群运行的整个状态,包括中心调度的状态,这样故障转移或者重启时未完成的应用就可以继续执行,而无须重新提交。3.4 Federation
虽然YARN的扩展性比HDFS好(不需要在内存中保存大量信息),但是并不意味着能够无限扩展(各服务之间的心跳会激增),其扩展性受 ResourceManager 的调度性能和 NodeManager 个数的限制。
YARN Federation将一个超大规模集群(上万台机器)切分为多个子集群,虽然这些子集群在物理上相互独立、互不影响,但在逻辑上是一个整体,向外提供的是一个规模超大的集群。用户不会感知到在 YARN Federation 模式下提交应用与在普通 YARN 集群中提交应用的不同,并且应用还可以在当前子集群资源不足的情况下,进行跨子集群资源调度。
Federation 服务层架构在YARN子集群之上,主要由 Router、Policy Store、State Store 和 AMRMProxy 组成。把应用从普通集群提交到 Federation 集群时,不需要更改任何代码,只需要管理员更改一下客户端上的配置文件,将 ResourceManager 地址改为 Router 的即可。
Router 是一个单独的守护进程,可以部署在任意节点上。此外,我们也可以通过部署多个 Router 实现负载均衡或者HA功能。Router 主要用来将应用分发到不同子集群中,是 YARN Federation 集群的网关。
当一个子集群资源不足时,可以跨节点申请资源。3.5 中央调度器
YARN 是一个资源管理平台,由 ResourceManager 负责资源调度。调度由 YarnScheduler 实现,它主要负责资源的分配和回收。具体的调度策略是一个插件式的服务,有多种实现。各种调度策略旨在使集群在多用户的情况下既能让各种应用共享资源,又能有效隔离资源,使集群资源得到最大化的利用,提升集群的吞吐量和资源利用率,从而为公司降本提效。
ResourceManager支持的调度策略有FIFO、Capacity和Fair。FIFO是Hadoop早期版本默认的调度策略,它根据任务的提交顺序进行调度,任务之间并没有太多的隔离,缺点是容易导致重要任务无法被及时调度。目前,Hadoop已经放弃FIFO策略,采用的主流策略是Capacity和Fair。Capacity是Apache Hadoop版本默认的调度策略,支持多用户,能够做到对资源的精准限制,保证每个用户的容量。Fair是CDH版本默认的调度策略,同样支持多用户,对资源能够做到更精细的调度,在保证各个用户容量的同时还可以使用其他队列未使用的资源,提高集群的利用率。4. 配置文件和部署
https://hadoop.apache.org/releases.html 下载最新的文件,并且解压缩。假设文件目录时 /home/bigdata/hadoop-3.3.1/。
详细配置说明,请查看 https://hadoop.apache.org/docs/r3.3.1/hadoop-project-dist/hadoop-common/ClusterSetup.html。4.1 配置文件
在 /home/bigdata/hadoop-3.3.1/etc/hadoop 目录下能看到多个配置文件。
[bigdata@localhost hadoop]$ ls -al
总用量 180
drwxr-xr-x. 3 bigdata bigdata 4096 12月 23 14:12 .
drwxr-xr-x. 3 bigdata bigdata 20 6月 15 2021 ..
-rw-r--r--. 1 bigdata bigdata 9213 6月 15 2021 capacity-scheduler.xml
-rw-r--r--. 1 bigdata bigdata 1335 6月 15 2021 configuration.xsl
-rw-r--r--. 1 bigdata bigdata 2567 6月 15 2021 container-executor.cfg
-rw-r--r--. 1 bigdata bigdata 774 6月 15 2021 core-site.xml
-rw-r--r--. 1 bigdata bigdata 3999 6月 15 2021 hadoop-env.cmd
-rw-r--r--. 1 bigdata bigdata 16693 12月 23 14:12 hadoop-env.sh
-rw-r--r--. 1 bigdata bigdata 3321 6月 15 2021 hadoop-metrics2.properties
-rw-r--r--. 1 bigdata bigdata 11765 6月 15 2021 hadoop-policy.xml
-rw-r--r--. 1 bigdata bigdata 3414 6月 15 2021 hadoop-user-functions.sh.example
-rw-r--r--. 1 bigdata bigdata 683 6月 15 2021 hdfs-rbf-site.xml
-rw-r--r--. 1 bigdata bigdata 775 6月 15 2021 hdfs-site.xml
-rw-r--r--. 1 bigdata bigdata 1484 6月 15 2021 httpfs-env.sh
-rw-r--r--. 1 bigdata bigdata 1657 6月 15 2021 httpfs-log4j.properties
-rw-r--r--. 1 bigdata bigdata 620 6月 15 2021 httpfs-site.xml
-rw-r--r--. 1 bigdata bigdata 3518 6月 15 2021 kms-acls.xml
-rw-r--r--. 1 bigdata bigdata 1351 6月 15 2021 kms-env.sh
-rw-r--r--. 1 bigdata bigdata 1860 6月 15 2021 kms-log4j.properties
-rw-r--r--. 1 bigdata bigdata 682 6月 15 2021 kms-site.xml
-rw-r--r--. 1 bigdata bigdata 13700 6月 15 2021 log4j.properties
-rw-r--r--. 1 bigdata bigdata 951 6月 15 2021 mapred-env.cmd
-rw-r--r--. 1 bigdata bigdata 1764 6月 15 2021 mapred-env.sh
-rw-r--r--. 1 bigdata bigdata 4113 6月 15 2021 mapred-queues.xml.template
-rw-r--r--. 1 bigdata bigdata 758 6月 15 2021 mapred-site.xml
drwxr-xr-x. 2 bigdata bigdata 24 6月 15 2021 shellprofile.d
-rw-r--r--. 1 bigdata bigdata 2316 6月 15 2021 ssl-client.xml.example
-rw-r--r--. 1 bigdata bigdata 2697 6月 15 2021 ssl-server.xml.example
-rw-r--r--. 1 bigdata bigdata 2681 6月 15 2021 user_ec_policies.xml.template
-rw-r--r--. 1 bigdata bigdata 10 6月 15 2021 workers
-rw-r--r--. 1 bigdata bigdata 2250 6月 15 2021 yarn-env.cmd
-rw-r--r--. 1 bigdata bigdata 6329 6月 15 2021 yarn-env.sh
-rw-r--r--. 1 bigdata bigdata 2591 6月 15 2021 yarnservice-log4j.properties
-rw-r--r--. 1 bigdata bigdata 690 6月 15 2021 yarn-site.xml
有 30多个配置文件,为了方便,去除 log4j.properties(日志文件)、.example (示例文件)、.cmd (windows 运行文件)之后。
-rw-r--r--. 1 bigdata bigdata 9213 6月 15 2021 capacity-scheduler.xml
-rw-r--r--. 1 bigdata bigdata 1335 6月 15 2021 configuration.xsl
-rw-r--r--. 1 bigdata bigdata 2567 6月 15 2021 container-executor.cfg
-rw-r--r--. 1 bigdata bigdata 774 6月 15 2021 core-site.xml
-rw-r--r--. 1 bigdata bigdata 16654 6月 15 2021 hadoop-env.sh
-rw-r--r--. 1 bigdata bigdata 3321 6月 15 2021 hadoop-metrics2.properties
-rw-r--r--. 1 bigdata bigdata 11765 6月 15 2021 hadoop-policy.xml
-rw-r--r--. 1 bigdata bigdata 683 6月 15 2021 hdfs-rbf-site.xml
-rw-r--r--. 1 bigdata bigdata 775 6月 15 2021 hdfs-site.xml
-rw-r--r--. 1 bigdata bigdata 1484 6月 15 2021 httpfs-env.sh
-rw-r--r--. 1 bigdata bigdata 620 6月 15 2021 httpfs-site.xml
-rw-r--r--. 1 bigdata bigdata 3518 6月 15 2021 kms-acls.xml
-rw-r--r--. 1 bigdata bigdata 1351 6月 15 2021 kms-env.sh
-rw-r--r--. 1 bigdata bigdata 682 6月 15 2021 kms-site.xml
-rw-r--r--. 1 bigdata bigdata 1764 6月 15 2021 mapred-env.sh
-rw-r--r--. 1 bigdata bigdata 758 6月 15 2021 mapred-site.xml
-rw-r--r--. 1 bigdata bigdata 10 6月 15 2021 workers
-rw-r--r--. 1 bigdata bigdata 6329 6月 15 2021 yarn-env.sh
-rw-r--r--. 1 bigdata bigdata 690 6月 15 2021 yarn-site.xml
其中常用的 XML 文件包括负责通用配置的 core-site.xml、负责 HDFS 的 hdfs-site.xml、负责 YARN 的yarn-site.xml 和负责 MapReduce 的 mapred-site.xml,最后还有一个存放队列调度配置的文件 capacity-scheduler.xml/fair-scheduler.xml。
对于shell文件,管理员经常用到的是hadoop-env.sh,可以在这里修改Hadoop相关进程所需的环境变量;也可以在yarn-env.sh中修改YARN相关的环境变量和在mapred-env.sh中修改MapReduce相关的环境变量。在不同的shell文件中修改同一个变量的生效优先级是hadoop-env.sh小于mapred-env.sh或者yarn-env.sh。
core-site.xml | 通用配置 |
---|---|
hdfs-site.xml | HDFS配置 |
yarn-site.xml | YARN配置 |
mapred-site.xml | MapReduce配置 |
capacity-scheduler.xml/fair-scheduler.xml | 存放队列调度配置 |
hadoop-env.sh | hadoop 环境 |
yarn-env.sh | YARN 环境 |
mapred-env.sh | MapReduce 环境 |
4.2 部署 Zookeeper
YARN 的高可用需要使用 ZooKeeper。<br /> 下载 zookeeper,[https://zookeeper.apache.org/releases.html](https://zookeeper.apache.org/releases.html),解压缩,编辑 **conf/zoo.cfg。**
tickTime=2000
dataDir=/var/lib/zookeeper
clientPort=2181
启动 zookeeper。
# 启动
bin/zkServer.sh start
# 查看状态
bin/zkServer.sh status
如果需要启动多个副本,zoo.cfg 中指定机器和端口。
tickTime=2000
dataDir=/var/lib/zookeeper
clientPort=2181
initLimit=5
syncLimit=2
server.1=zoo1:2888:3888
server.2=zoo2:2888:3888
server.3=zoo3:2888:3888
在zoo1/zoo2/zoo3 的 dataDir 目录下,创建一个 myid 文件,内容分别是1/2/3,对应 server.1/server.2/server.3。
然后在这三台机器上分别启动项目。
bin/zkServer.sh start
详细内容请参考:https://zookeeper.apache.org/doc/r3.7.0/zookeeperStarted.html