Router
在HDFS中Router可以有多个,且Router之间相互独立,如果一个Router不可用不会影响其他Router提供服务。Router主要实现了
State Store有两种存储方式,本地存储和Zookeeper,我们选择的是Zookeeper,它主要维护两种信息:Membership和Mount Table
经过一段时间的准备工作,在用户无感知情况下,我们完成了RBF搭建、配置、数据迁移工作,解决了当前的痛点。
在RBF落地的过程中,我们遇到过一些问题,有些问题社区高版本已经解决。这里,我们列举一些典型的问题做简要说明。
在HDFS集群中,在哪个用户下执行rm操作,数据会被移动到/user/用户/.Trash目录下,默认的该目录挂载在Namespace1中,因此Namespace2中执行rm会报错rm失败。解决方法:将Trash挂载到两个集群。
以hadoop用户为例,当/user/hadoop/.Trash 多集群挂载到 hdfs://ns1:/user/hadoop/.Trash 和 hdfs://ns2:/user/hadoop/.Trash 并且挂载策略为LOCAL时 ,执行 rm 操作有一定概率失败。失败的原因在于多集群挂载策略的选择。多集群挂载策略有五种:HASH_ALL,RANDOM, SPACE,LOCAL,HASH。
这里解释下这五种策略:
当执行rm操作时,会顺序调用 mkdirs 和 rename,而mkdirs,create,setPermission,setOwner,delete,getFileInfo 这几个方法在router 中进行了重写,策略HASH_ALL,RANDOM 和 SPACE 会调用rpcClient.invokeConcurrent(locations, method)并行的去所有集群执行,其他策略HASH,LOCAL 会调用 rpcClient.invokeSequential(locations, method) 顺序的去执行,当第一个返回后就返回了,也就是说HASH_ALL ,RANDOM 和 SPACE会在所有集群创建目录,而HASH,LOCAL只会在一个集群创建目录。
当多集群挂载策略是LOCAL时,mkdirs 会以 rpcClient.invokeSequential(locations, method) 的方式执行,只要有一个子集群执行成功就返回true。这样两个集群中,就会有一个集群mkdir失败。所以对应的后续在这个集群上执行rename操作就会失败
解决方式:将多集群挂载设置为HASH_ALL ,RANDOM, SPACE中的一种,为了负载均衡我们最终选择RANDOM策略。
该问题是由多集群挂载时包含EC路径引起的,目前社区已经修复,因此,我们的解决方式是将该issue合并到我们的Hadoop 3.1.3中。http://issues.apache.org/jira/browse/HDFS-14224
Hive会以绝对路径的方式存储元数据,因此如果修改fs.defaultFS则需要大批量修改Hive元数据,因此,我们决定保留fs.defaultFS的设置,在HDFS中更改该nameservice的映射关系,即由原来的映射NameNode修改为映射到LVS和Router。
Hadoop 3.1.3版本的RBF是不支持kerberos的,社区修复了这一问题。http://issues.apache.org/jira/browse/HDFS-13358
但由于目前集群涉及的安全认证链路较少,因此我们暂时没有将它合并到我们的Hadoop 3.1.3版本。
首先,明确一点 Router 是无状态服务,可以通过负载均衡的方式来保证多个Router 处理的请求平均一些。需要在 Client 配置文件中声明dfs.client.failover.random.order = true,并且,每次新增或者更改Router ,都需要刷Client 配置。但是该参数在当前2.7 Client 不支持,2.9 之后支持. 因此我们的解决方案是通过LVS实现负载均衡。
当前的RBF不支持集群间的cp,采用distcp的方式迁移数据效率较低,对于集群迁移而言,fastcp是个不错的加速跨集群数据迁移的工具,因此未来我们会朝着这个方向进一步发展。此外,集群的安全认证功能需要完善,我们需要将kerberos安全的代码合并到我们的版本中。后续我们也会继续跟进社区和其他公司的发展,使RBF能够在公司有很好的落地。
原文链接HDFS RBF 在车好多的应用
本博客文章除特别声明,全部都是原创!