由于由inode(文件和目录)和文件块组成的元数据开销,Datanode心跳数和HDFS RPC客户端请求数,NameNode具有可伸缩性限制。常见的解决方案是将文件系统拆分为较小的子群集HDFS联合,并提供联合视图ViewFs。问题在于如何维护子集群的拆分(例如,命名空间分区),这迫使用户连接到多个子集群并管理向其分配的文件夹/文件。
对这个分区的联合会的自然扩展是添加一个负责联合命名空间的软件层。这个额外的层允许用户透明地访问任何子集群,让子集群独立地管理自己的块池,并在以后支持跨子集群的数据重新平衡(请参阅HDFS-13123中的更多信息)。RBF中的子集群不需要是独立的HDFS集群,也可以是普通联合集群(具有多个块池)或具有联合和独立集群的混合集群。为了实现这些目标,联合层将块访问定向到适当的子集群,维护名称空间的状态,并提供数据重新平衡的机制。该层必须是可伸缩的,高度可用的并且具有容错能力。
该联合层包括多个组件。该路由器组件具有相同的接口作为NameNode的,并转发客户端请求到正确的子集群的基础上,从国家商店地面实况信息。该状态存储结合了远程安装台(在风味ViewFs,但客户端之间共享)和利用(加载/容量)有关子群集信息。此方法与YARN联合具有相同的体系结构。
最简单的配置是在每台NameNode计算机上部署一个路由器。路由器监视本地NameNode并将状态心跳到状态存储。当常规DFS客户端联系任何路由器以访问联合文件系统中的文件时,路由器将检查状态存储(即本地缓存)中的挂载表,以找出包含该文件的子集群。然后,它检查状态存储区(即本地缓存)中的Membership表,以查找负责该子群集的NameNode。在确定正确的NameNode之后,路由器将代理该请求。客户端直接访问Datanode。
系统中可以有多个处于软状态的路由器。每个路由器都有两个角色:
路由器接收到一个客户端请求,检查状态存储中是否有正确的子集群,并将请求转发到该子集群的活动NameNode。然后,来自NameNode的答复将沿相反方向流动。路由器是无状态的,可以位于负载均衡器之后。对于运行状况检查,可以将/ isActive端点用作运行状况探测器(例如,http:// ROUTER_HOSTNAME:ROUTER_PORT / isActive)。为了提高性能,路由器还缓存远程装载表条目和子群集的状态。为确保已将更改传播到所有路由器,每个路由器会将其状态发送到状态存储。
路由器和状态存储之间的通信被缓存(具有过期时间,以确保更新)。这样可以提高系统的性能。
对于此角色,路由器会定期检查NameNode的状态(通常在同一服务器上),并将其高可用性(HA)状态和负载/空间状态报告给状态存储。请注意,这是一个可选角色,因为路由器可以独立于任何子集群。为了提高NameNode HA的性能,路由器使用状态存储中的高可用性状态信息将请求转发到最有可能处于活动状态的NameNode。请注意,可以将该服务嵌入NameNode本身以简化操作。
路由器在多个级别上均出现故障。
联合接口HA:路由器是无状态的,元数据操作在NameNode上是原子的。如果路由器不可用,则任何路由器都可以接管它。客户端将其DFS HA客户端(例如,ConfiguredFailoverProvider或RequestHedgingProxyProvider)配置为联盟中的所有路由器作为端点。
不可用的状态存储:如果路由器无法联系状态存储,它将进入安全模式状态,从而禁止其处理请求。客户端将以安全模式对待路由器,因为它是一个备用NameNode,然后尝试另一个路由器。有一种手动方法可以管理路由器的安全模式。
可以使用以下命令来管理安全模式状态:
[hdfs] $ $ HADOOP_HOME / bin / hdfs dfsrouteradmin -safemode输入| 离开 得到
NameNode心跳HA:为了实现高可用性和灵活性,多个路由器可以监视同一个NameNode并将心跳到状态存储中。如果路由器发生故障,这将增加客户端对过时信息的弹性。每个路由器都通过仲裁来解决状态存储中有冲突的NameNode信息。
不可用的NameNode:如果路由器无法联系活动的NameNode,则它将尝试子群集中的其他NameNode。它将首先尝试报告为备用的那些,然后尝试不可用的那些。如果路由器无法访问任何NameNode,则它将引发异常。
过期的NameNode:如果在状态存储中没有记录NameNode心跳超过心跳间隔的倍数,则监视路由器将记录NameNode已过期,并且没有路由器将尝试访问它。如果随后为NameNode记录了更新的心跳,则监视路由器将把NameNode从过期状态恢复。
为了与用户和管理员进行交互,路由器公开了多个接口。
RPC:路由器RPC实现了客户端用于与HDFS交互的最常用接口。当前的实现已通过使用以普通MapReduce,Spark和Hive(在Tez,Spark和MapReduce上)编写的分析工作负载进行了测试。快照,加密和分层存储等高级功能留给以后的版本。所有未实现的函数都将引发异常。
管理员:管理员可以通过RPC查询群集中的信息并从安装表中添加/删除条目。此界面也通过命令行公开,以从联合身份验证中获取和修改信息。
Web UI:路由器公开一个Web UI,以可视化联盟的状态,模仿当前的NameNode UI。它显示有关安装表的信息,有关每个子集群的成员资格信息以及路由器的状态。
WebHDFS:除RPC之外,路由器还提供HDFS REST接口(WebHDFS)。
JMX:它通过模仿NameNode的JMX公开指标。Web UI使用它来获取集群状态。
一些操作在基于路由器的联合中不可用。路由器为此抛出异常。用户可能遇到的示例包括以下内容。
联合会在安装表级别支持和控制全局配额。出于性能原因,路由器会缓存配额使用情况并定期更新。这些配额使用值将在RouterRPCSever中调用的每个WRITE RPC调用期间用于配额验证。有关配额的详细信息,请参见《HDFS配额指南》。
(在逻辑上集中但在物理上分散)状态存储区维护:
状态存储的后端是可插入的。我们利用后端实现的容错能力。存储在状态存储中的主要信息及其实现:
成员资格:成员资格信息编码联盟中NameNode的状态。这包括有关子集群的信息,例如存储容量和节点数。路由器会定期对有关一个或多个NameNode的信息进行心跳检测。假设有多个路由器可以监视单个NameNode,则将存储每个路由器的心跳。当从状态存储中查询此信息时,路由器将应用数据的仲裁。路由器丢弃早于某个阈值(例如,十个路由器心跳周期)的条目。
安装表:此表托管文件夹和子群集之间的映射。它类似于ViewFs中的安装表,在该表中它指定联合文件夹,目标子群集和该文件夹中的路径。
默认情况下,路由器准备接受请求并监视本地计算机中的NameNode。它需要通过设置dfs.federation.router.store.driver.class来了解State Store端点。其余选项记录在hdfs-rbf-default.xml中。
一旦配置了路由器,就可以启动它:
[hdfs] $ $ HADOOP_PREFIX / bin / hdfs --daemon启动dfsrouter
并停止它:
[hdfs] $ $ HADOOP_PREFIX / bin / hdfs --daemon停止dfsrouter
装载表条目与ViewFs几乎相同。简化管理的一个好习惯是使用与目标名称空间相同的名称来命名联合名称空间。例如,如果要在联合名称空间中挂载/ data / app1,建议使用与目标名称空间相同的名称。
联合管理工具支持管理装载表。例如,创建三个挂载点并列出它们:
[hdfs] $ $ HADOOP_HOME / bin / hdfs dfsrouteradmin -add / tmp ns1 / tmp [hdfs] $ $ HADOOP_HOME / bin / hdfs dfsrouteradmin -add / data / app1 ns2 / data / app1 [hdfs] $ $ HADOOP_HOME / bin / hdfs dfsrouteradmin -add / data / app2 ns3 / data / app2 [hdfs] $ $ HADOOP_HOME / bin / hdfs dfsrouteradmin -ls
它还支持不允许写入的安装点:
[hdfs] $ $ HADOOP_HOME / bin / hdfs dfsrouteradmin -add / readonly ns1 / -readonly
如果未设置安装点,则路由器会将其映射到默认名称空间dfs.federation.router.default.nameserviceId。
安装表具有类UNIX的权限,该权限限制了哪些用户和组有权访问安装点。写入权限允许用户添加,更新或删除安装点。读取权限允许用户列出安装点。执行权限未使用。
可以通过以下命令设置装入表权限:
[hdfs] $ $ HADOOP_HOME / bin / hdfs dfsrouteradmin -add / tmp ns1 / tmp -owner root -group supergroup -mode 0755
选项模式是安装表的UNIX样式权限。权限以八进制指定,例如0755。默认情况下,此设置为0755。
基于路由器的联合支持在装入表级别支持全局配额。装入表条目可能会分散多个子集群,并且将在这些子集群中考虑全局配额。
联邦管理工具支持为指定的安装表条目设置配额:
[hdfs] $ $ HADOOP_HOME / bin / hdfs dfsrouteradmin -setQuota / path -nsQuota 100 -ssQuota 1024
上面的命令意味着我们允许路径最多包含100个文件/目录,并最多使用1024个字节的存储空间。ssQuota的参数支持多个大小单位后缀(例如1k为1KB,5m为5MB)。如果未指定后缀,则假定为字节。
ls命令将为每个装入表条目显示以下信息:
源目标所有者组模式配额/用法 / path ns0-> / path根超级组rwxr-xr-x [NsQuota:50/0,SsQuota:100 B / 0 B]
挂载点还支持映射多个子群集。例如,创建一个将点存储在子集群ns1和ns2中的安装点。
[hdfs] $ $ HADOOP_HOME / bin / hdfs dfsrouteradmin -add / data ns1,ns2 / data -order空格
列出/ data时,它将显示两个子群集中的所有文件夹和文件。为了确定要在哪里创建新文件/文件夹,它使用了order参数,它目前支持以下方法:
对于基于散列的方法,不同之处在于HASH将使文件夹中的所有文件/文件夹都属于同一子群集,而HASH_ALL将在安装点下散布所有文件。例如,假设我们有一个用于/ data / hash的HASH挂载点,则/ data / hash / folder0下的文件和文件夹将全部位于同一子群集中。另一方面,/ data / hash_all的HASH_ALL挂载点将在/ data / hash_all / folder0下的文件分布在该挂载点的所有子集群中(子文件夹将创建到所有子集群)。
RANDOM可用于从不同的子集群读取数据或将数据写入不同的子集群。此方法的常见用法是在多个子群集中具有相同的数据,并平衡各个子群集中的读取。例如,如果成千上万个容器需要读取相同的数据(例如,一个库),则可以使用RANDOM从任何子群集中读取数据。
请注意,路由器无法保证子群集之间数据的一致性。
为了防止访问名称服务(子级),可以从联合身份验证中将其禁用。例如,可以禁用ns1,将其列出并再次启用:
[hdfs] $ $ HADOOP_HOME / bin / hdfs dfsrouteradmin -nameservice disable ns1 [hdfs] $ $ HADOOP_HOME / bin / hdfs dfsrouteradmin -getDisabledNameservices [hdfs] $ $ HADOOP_HOME / bin / hdfs dfsrouteradmin -nameservice enable ns1
在停用子集群或一个子集群行为异常(例如,性能低下或不可用)时,这很有用。
为了使客户端使用联合名称空间,他们需要创建一个指向路由器的新名称空间。例如,具有4个名称空间ns0,ns1,ns2,ns3的集群可以向hdfs-site.xml中添加一个名为ns-fed的新名称,该名称指向两个路由器:
<配置> <属性> <name> dfs.nameservices </ name> <value> ns0,ns1,ns2,ns3,ns-fed </ value> </ property> <属性> <name> dfs.ha.namenodes.ns-fed </ name> <value> r1,r2 </ value> </ property> <属性> <name> dfs.namenode.rpc-address.ns-fed.r1 </ name> <value> router1:rpc-port </ value> </ property> <属性> <name> dfs.namenode.rpc-address.ns-fed.r2 </ name> <value> router2:rpc-port </ value> </ property> <属性> <name> dfs.client.failover.proxy.provider.ns-fed </ name> <value> org.apache.hadoop.hdfs.server.namenode.ha.ConfiguredFailoverProxyProvider </ value> </ property> <属性> <name> dfs.client.failover.random.order </ name> <value> true </ value> </ property> </ configuration>
设置为true的dfs.client.failover.random.order允许在路由器之间平均分配负载。
通过此设置,用户可以与ns-fed作为常规名称空间进行交互:
$ $ HADOOP_HOME / bin / hdfs dfs -ls hdfs:// ns-fed / / tmp /数据
也可以使用fs.defaultFS在core-site.xml将此联合名称空间设置为默认名称空间。
可以将基于路由器的联合的配置添加到hdfs-site.xml中。主要选项记录在hdfs-rbf-default.xml中。配置值在本节中描述。
RPC服务器从客户端接收连接。
属性 | 默认 | 描述 |
---|---|---|
dfs.federation.router.default.nameserviceId | 要监视的默认子集群的名称服务标识符。 | |
dfs.federation.router.rpc.enable | 真正 | 如果为true,则启用用于处理路由器中客户端请求的RPC服务。 |
dfs.federation.router.rpc地址 | 0.0.0.0:8888 | 处理所有客户端请求的RPC地址。 |
dfs.federation.router.rpc-bind-host | 0.0.0.0 | RPC服务器将绑定到的实际地址。 |
dfs.federation.router.handler.count | 10 | 路由器处理来自客户端的RPC请求的服务器线程数。 |
dfs.federation.router.handler.queue.size | 100 | 队列的大小,用于处理RPC客户端请求的处理程序数。 |
dfs.federation.router.reader.count | 1个 | 路由器处理RPC客户端请求的读取器的数量。 |
dfs.federation.router.reader.queue.size | 100 | 队列大小,用于路由器处理RPC客户端请求的读取器数量。 |
管理服务器来管理装载表。
属性 | 默认 | 描述 |
---|---|---|
dfs.federation.router.admin.enable | 真正 | 如果为true,则启用用于处理路由器中客户端请求的RPC管理服务。 |
dfs.federation.router.admin地址 | 0.0.0.0:8111 | 处理管理请求的RPC地址。 |
dfs.federation.router.admin-bind-host | 0.0.0.0 | RPC管理服务器将绑定到的实际地址。 |
dfs.federation.router.admin.handler.count | 1个 | 路由器处理来自admin的RPC请求的服务器线程数。 |
HTTP服务器,用于为客户端提供Web UI和HDFS REST接口(WebHDFS)。默认URL为“ http:// router_host:50071 ”。
属性 | 默认 | 描述 |
---|---|---|
dfs.federation.router.http.enable | 真正 | 如果为true,则启用用于处理路由器中客户端请求的HTTP服务。 |
dfs.federation.router.http地址 | 0.0.0.0:50071 | 处理对路由器的Web请求的HTTP地址。 |
dfs.federation.router.http-bind-host | 0.0.0.0 | HTTP服务器将绑定到的实际地址。 |
dfs.federation.router.https地址 | 0.0.0.0:50072 | 处理对路由器的Web请求的HTTPS地址。 |
dfs.federation.router.https-bind-host | 0.0.0.0 | HTTPS服务器将绑定到的实际地址。 |
与状态存储的连接以及路由器的内部缓存。
属性 | 默认 | 描述 |
---|---|---|
dfs.federation.router.store.enable | 真正 | 如果为true,则路由器连接到状态存储。 |
dfs.federation.router.store.serializer | org.apache.hadoop.hdfs.server.federation.store.driver.impl.StateStoreSerializerPBImpl | 用于序列化State Store记录的类。 |
dfs.federation.router.store.driver.class | org.apache.hadoop.hdfs.server.federation.store.driver.impl.StateStoreZooKeeperImpl | 实现State Store的类。 |
dfs.federation.router.store.connection.test | 60000 | 检查与状态存储的连接的频率(以毫秒为单位)。 |
dfs.federation.router.cache.ttl | 60000 | 刷新状态存储缓存的频率(以毫秒为单位)。 |
dfs.federation.router.store.membership.expiration | 300000 | 成员资格记录的到期时间(以毫秒为单位)。 |
将客户端请求转发到正确的子集群。
属性 | 默认 | 描述 |
---|---|---|
dfs.federation.router.file.resolver.client.class | org.apache.hadoop.hdfs.server.federation.resolver.MountTableResolver | 将文件解析为子类的类。 |
dfs.federation.router.namenode.resolver.client.class | org.apache.hadoop.hdfs.server.federation.resolver.MembershipNamenodeResolver | 用于解析子群集的namenode的类。 |
监视子群集中的名称节点以转发客户端请求。
属性 | 默认 | 描述 |
---|---|---|
dfs.federation.router.heartbeat.enable | 真正 | 如果为true,则路由器心跳进入状态存储。 |
dfs.federation.router.heartbeat.interval | 5000 | 路由器应每隔多长时间心跳一次进入状态存储区(以毫秒为单位)。 |
dfs.federation.router.monitor.namenode | 要监视和检测信号的名称节点的标识符。 | |
dfs.federation.router.monitor.localnamenode.enable | 真正 | 如果为true,则路由器应监视本地计算机中的namenode。 |
注意:建议配置dfs.nameservice.id来配置是否启用dfs.federation.router.monitor.localnamenode.enable。这将允许路由器直接查找本地节点。否则,它将通过将namenode RPC地址与本地节点地址匹配来找到nameservice Id。如果多个地址匹配,路由器将无法启动。此外,如果本地节点处于HA模式,则建议配置dfs.ha.namenode.id。