HDFS NFS 网关

概述

NFS 网关支持 NFSv3,并允许将 HDFS 挂载为客户端本地文件系统的一部分。目前,NFS 网关支持并启用了以下使用模式

  • 用户可以通过 NFSv3 客户端兼容操作系统在其本地文件系统上浏览 HDFS 文件系统。
  • 用户可以将文件从 HDFS 文件系统下载到其本地文件系统。
  • 用户可以将文件从其本地文件系统直接上传到 HDFS 文件系统。
  • 用户可以通过挂载点将数据直接传输到 HDFS。支持文件追加,但不支持随机写入。

NFS 网关计算机需要与 Hadoop JAR 文件、HADOOP_CONF 目录等运行 HDFS 客户端相同的内容。NFS 网关可以与 DataNode、NameNode 或任何 HDFS 客户端位于同一主机上。

配置

NFS 网关使用代理用户来代理所有访问 NFS 挂载的用户。在非安全模式下,运行网关的用户是代理用户,而在安全模式下,Kerberos 密钥表中的用户是代理用户。假设代理用户是“nfsserver”,并且属于组“users-group1”和“users-group2”的用户使用 NFS 挂载,那么在 NameNode 的 core-site.xml 中,必须设置以下两个属性,并且在配置更改后只需要重新启动 NameNode(注意:将字符串“nfsserver”替换为集群中的代理用户名)

<property>
  <name>hadoop.proxyuser.nfsserver.groups</name>
  <value>root,users-group1,users-group2</value>
  <description>
         The 'nfsserver' user is allowed to proxy all members of the 'users-group1' and
         'users-group2' groups. Note that in most cases you will need to include the
         group "root" because the user "root" (which usually belonges to "root" group) will
         generally be the user that initially executes the mount on the NFS client system.
         Set this to '*' to allow nfsserver user to proxy any group.
  </description>
</property>

<property>
  <name>hadoop.proxyuser.nfsserver.hosts</name>
  <value>nfs-client-host1.com</value>
  <description>
         This is the host where the nfs gateway is running. Set this to '*' to allow
         requests from any hosts to be proxied.
  </description>
</property>

以上是 NFS 网关在非安全模式下唯一必需的配置。对于经过 Kerberos 认证的 Hadoop 集群,需要将以下配置添加到网关的 hdfs-site.xml 中(注意:将字符串“nfsserver”替换为代理用户名,并确保密钥表中包含的用户也是相同的代理用户)

  <property>
    <name>nfs.keytab.file</name>
    <value>/etc/hadoop/conf/nfsserver.keytab</value> <!-- path to the nfs gateway keytab -->
  </property>

  <property>
    <name>nfs.kerberos.principal</name>
    <value>nfsserver/[email protected]</value>
  </property>

其余 NFS 网关配置对于安全和非安全模式都是可选的。

  • AIX NFS 客户端有一些已知问题,这些问题导致它无法通过 HDFS NFS 网关正常工作。如果您希望能够从 AIX 访问 HDFS NFS 网关,则应设置以下配置设置以启用针对这些问题的解决方法

    <property>
      <name>nfs.aix.compatibility.mode.enabled</name>
      <value>true</value>
    </property>
    

    请注意,常规非 AIX 客户端不应启用 AIX 兼容模式。AIX 兼容模式实施的解决方法实际上会禁用保障措施,以确保通过 NFS 列出目录内容会返回一致的结果,并且可以确保发送到 NFS 服务器的所有数据都已提交。

  • HDFS 超级用户是与 NameNode 进程本身具有相同标识的用户,超级用户可以在该权限检查中执行任何操作,超级用户永远不会失败。如果配置了以下属性,NFS 客户端上的超级用户可以访问 HDFS 上的任何文件。默认情况下,网关中未配置超级用户。请注意,即使配置了超级用户,“nfs.exports.allowed.hosts” 仍然有效。例如,如果 NFS 客户端主机在“nfs.exports.allowed.hosts”中没有写入访问权限,则超级用户将无法通过网关写入 HDFS 文件。

    <property>
      <name>nfs.superuser</name>
      <value>the_name_of_hdfs_superuser</value>
    </property>
    

强烈建议用户根据其用例更新一些配置属性。所有以下配置属性都可以在 hdfs-site.xml 中添加或更新。

  • 如果客户端在允许更新访问时间的情况下挂载导出,请确保未在配置文件中禁用以下属性。此属性更改后,只需要重新启动 NameNode。在某些 Unix 系统上,用户可以通过使用“noatime”挂载导出,来禁用访问时间更新。如果导出使用“noatime”挂载,则用户无需更改以下属性,因此无需重新启动名称节点。

    <property>
      <name>dfs.namenode.accesstime.precision</name>
      <value>3600000</value>
      <description>The access time for HDFS file is precise upto this value.
        The default value is 1 hour. Setting a value of 0 disables
        access times for HDFS.
      </description>
    </property>
    
  • 用户应更新文件转储目录。NFS 客户端经常重新排序写入,特别是当导出未使用“sync”选项挂载时。顺序写入可以随机顺序到达 NFS 网关。此目录用于在写入 HDFS 之前临时保存无序写入。对于每个文件,无序写入在累积超过内存中的特定阈值(例如 1MB)后被转储。需要确保目录有足够的空间。例如,如果应用程序上传 10 个文件,每个文件有 100MB,建议此目录有大约 1GB 的空间,以防最坏情况下的写入重新排序发生在每个文件上。此属性更新后,只需要重新启动 NFS 网关。

      <property>
        <name>nfs.dump.dir</name>
        <value>/tmp/.hdfs-nfs</value>
      </property>
    
  • 默认情况下,任何客户端都可以挂载导出。为了更好地控制访问,用户可以更新以下属性。值字符串包含机器名称和访问权限,由空格字符分隔。机器名称格式可以是单个主机、“*”、Java 正则表达式或 IPv4 地址。访问权限使用 rw 或 ro 来指定机器对导出的读/写或只读访问。如果未提供访问权限,则默认为只读。条目由“;”分隔。例如:“192.168.0.0/22 rw ; \\w*\\.example\\.com ; host1.test.org ro;”。更新此属性后,只有 NFS 网关需要重新启动。请注意,这里的 Java 正则表达式与 Linux NFS 导出表中使用的正则表达式不同,例如,使用“\\w*\\.example\\.com”代替“*.example.com”,使用“192\\.168\\.0\\.(11|22)”代替“192.168.0.[11|22]”等。

    <property>
      <name>nfs.exports.allowed.hosts</name>
      <value>* rw</value>
    </property>
    
  • HDFS 超级用户是与 NameNode 进程本身具有相同标识的用户,超级用户可以在该权限检查中执行任何操作,超级用户永远不会失败。如果配置了以下属性,NFS 客户端上的超级用户可以访问 HDFS 上的任何文件。默认情况下,网关中未配置超级用户。请注意,即使配置了超级用户,“nfs.exports.allowed.hosts” 仍然有效。例如,如果 NFS 客户端主机在“nfs.exports.allowed.hosts”中没有写入访问权限,则超级用户将无法通过网关写入 HDFS 文件。

    <property>
      <name>nfs.superuser</name>
      <value>the_name_of_hdfs_superuser</value>
    </property>
    
  • 指标。与其他 HDFS 守护进程一样,网关公开运行时指标。它作为 JSON 文档在 http://gateway-ip:50079/jmx 中提供。NFS 处理程序相关指标以“Nfs3Metrics”名称公开。可以通过将以下属性添加到 hdfs-site.xml 文件中来启用延迟直方图。

    <property>
      <name>nfs.metrics.percentiles.intervals</name>
      <value>100</value>
      <description>Enable the latency histograms for read, write and
         commit requests. The time unit is 100 seconds in this example.
      </description>
    </property>
    
  • JVM 和日志设置。您可以在 HDFS_NFS3_OPTS 中导出 JVM 设置(例如,堆大小和 GC 日志)。可以在 hadoop-env.sh 中找到更多与 NFS 相关的设置。要获取 NFS 调试跟踪,您可以编辑 log4j.property 文件以添加以下内容。请注意,调试跟踪(尤其是 ONCRPC)可能会非常详细。

    更改日志级别

        log4j.logger.org.apache.hadoop.hdfs.nfs=DEBUG
    

    获取 ONCRPC 请求的更多详细信息

        log4j.logger.org.apache.hadoop.oncrpc=DEBUG
    
  • 导出点。可以指定 HDFS 的 NFS 导出点。只支持一个导出点。配置导出点时需要完整路径。默认情况下,导出点是根目录“/”。

    <property>
      <name>nfs.export.point</name>
      <value>/</value>
    </property>
    

启动和停止 NFS 网关服务

提供 NFS 服务需要三个守护进程:rpcbind(或 portmap)、mountd 和 nfsd。NFS 网关进程同时具有 nfsd 和 mountd。它将 HDFS 根“/”共享为唯一的导出。建议使用 NFS 网关包中包含的 portmap。即使 NFS 网关与大多数 Linux 发行版提供的 portmap/rpcbind 协同工作,但某些 Linux 系统(例如 RHEL 6.2 和 SLES 11)需要包含 portmap 的包,前者是由于 rpcbind bug。可以在 HDFS-4763 中找到更详细的讨论。

  1. 停止平台提供的 nfsv3 和 rpcbind/portmap 服务(命令在不同的 Unix 平台上可能不同)

    [root]> service nfs stop
    [root]> service rpcbind stop
    
  2. 启动 Hadoop 的 portmap(需要 root 权限)

    [root]> $HADOOP_HOME/bin/hdfs --daemon start portmap
    
  3. 启动 mountd 和 nfsd。

    此命令不需要 root 权限。在非安全模式下,NFS 网关应由本用户指南开头提到的代理用户启动。而在安全模式下,只要用户具有对“nfs.keytab.file”中定义的 Kerberos 密钥表的读取访问权限,任何用户都可以启动 NFS 网关。

    [hdfs]$ $HADOOP_HOME/bin/hdfs --daemon start nfs3
    
  4. 停止 NFS 网关服务。

    [hdfs]$ $HADOOP_HOME/bin/hdfs --daemon stop nfs3
    [root]> $HADOOP_HOME/bin/hdfs --daemon stop portmap
    

如果以 root 身份启动 NFS Gateway,则可以选择放弃运行 Hadoop 提供的 portmap 守护进程,而是在所有操作系统上使用系统 portmap 守护进程。这将允许 HDFS NFS Gateway 规避上述错误,并仍使用系统 portmap 守护进程进行注册。为此,只需像往常一样启动 NFS 网关守护进程,但务必以“root”用户身份执行此操作,并将“HDFS_NFS3_SECURE_USER”环境变量设置为非特权用户。在此模式下,NFS Gateway 将以 root 身份启动以执行其与系统 portmap 的初始注册,然后在 NFS Gateway 进程的剩余生命周期内将特权降级回由 HDFS_NFS3_SECURE_USER 指定的用户。请注意,如果您选择此路径,则应跳过上述步骤 1 和 2。

验证 NFS 相关服务的有效性

  1. 执行以下命令以验证所有服务是否已启动并正在运行

    [root]> rpcinfo -p $nfs_server_ip
    

    您应该看到类似于以下内容的输出

           program vers proto   port
    
           100005    1   tcp   4242  mountd
    
           100005    2   udp   4242  mountd
    
           100005    2   tcp   4242  mountd
    
           100000    2   tcp    111  portmapper
    
           100000    2   udp    111  portmapper
    
           100005    3   udp   4242  mountd
    
           100005    1   udp   4242  mountd
    
           100003    3   tcp   2049  nfs
    
           100005    3   tcp   4242  mountd
    
  2. 验证 HDFS 命名空间是否已导出且可以挂载。

    [root]> showmount -e $nfs_server_ip
    

    您应该看到类似于以下内容的输出

            Exports list on $nfs_server_ip :
    
            / (everyone)
    

挂载导出“/”

目前 NFS v3 仅使用 TCP 作为传输协议。不支持 NLM,因此需要挂载选项“nolock”。强烈建议使用挂载选项“sync”,因为它可以最大程度地减少或避免重新排序写入,从而产生更可预测的吞吐量。在上传大文件时,不指定 sync 选项可能会导致行为不可靠。建议使用硬挂载。这是因为,即使客户端将所有数据发送到 NFS 网关后,当 NFS 客户端内核重新排序写入时,NFS 网关可能还需要一些额外时间才能将数据传输到 HDFS。

如果必须使用软挂载,则用户应给予它一个相对较长的超时(至少不低于主机上的默认超时)。

用户可以如下所示挂载 HDFS 命名空间

 [root]>mount -t nfs -o vers=3,proto=tcp,nolock,noacl,sync $server:/  $mount_point

然后,用户可以访问 HDFS 作为本地文件系统的一部分,除了硬链接和随机写入尚未得到支持。为了优化大文件 I/O 的性能,可以在挂载期间增加 NFS 传输大小(rsize 和 wsize)。默认情况下,NFS 网关支持 1MB 作为最大传输大小。对于更大的数据传输大小,需要在 hdfs-site.xml 中更新“nfs.rtmax”和“nfs.wtmax”。

允许非特权客户端挂载

在客户端计算机上通常无法获得 root 访问权限的环境中,可以通过确保仅源自特权端口的 NFS 客户端可以连接到 NFS 服务器来获得一定程度的安全性。此功能称为“端口监视”。此功能在 HDFS NFS 网关中默认未启用,但可以通过在 NFS 网关计算机上的 hdfs-site.xml 中设置以下配置来选择性地启用

<property>
  <name>nfs.port.monitoring.disabled</name>
  <value>false</value>
</property>

用户身份验证和映射

此版本中的 NFS 网关使用 AUTH_UNIX 样式身份验证。当 NFS 客户端上的用户访问挂载点时,NFS 客户端将 UID 传递给 NFS 网关。NFS 网关执行查找以从 UID 查找用户名,然后将用户名连同 HDFS 请求一起传递给 HDFS。例如,如果 NFS 客户端的当前用户为“admin”,当用户访问挂载目录时,NFS 网关将以用户“admin”的身份访问 HDFS。要以用户“hdfs”的身份访问 HDFS,需要在访问挂载目录时将客户端系统上的当前用户切换为“hdfs”。

系统管理员必须确保 NFS 客户端主机上的用户与 NFS 网关主机上的用户具有相同的名称和 UID。如果在 HDFS 节点和 NFS 客户端节点上使用相同的用户管理系统(例如,LDAP/NIS)来创建和部署用户,则通常不会出现问题。如果在不同的主机上手动创建用户帐户,则可能需要修改 NFS 客户端或 NFS 网关主机上的 UID(例如,执行“usermod -u 123 myusername”),以便在双方使其相同。可以在 RPC 规范 中找到 RPC AUTH_UNIX 的更多技术详细信息。

或者,系统管理员可以配置自定义静态映射文件,以防希望从具有完全不同的 UID/GID 集的系统访问 HDFS NFS 网关。默认情况下,此文件位于“/etc/nfs.map”,但可以通过将“static.id.mapping.file”属性设置为静态映射文件的路径来配置自定义位置。静态映射文件的格式类似于 exports(5) 手册页中描述的格式,但大致如下

# Mapping for clients accessing the NFS gateway
uid 10 100 # Map the remote UID 10 the local UID 100
gid 11 101 # Map the remote GID 11 to the local GID 101