HDFS 提供的存储

提供的存储允许将存储在 HDFS 之外的数据映射到 HDFS 并从中寻址。它基于异构存储构建,通过向数据节点中的介质集引入新的存储类型 PROVIDED 来实现。访问 PROVIDED 存储中的数据的客户端可以在本地介质中缓存副本,强制执行 HDFS 不变性(例如,安全性、配额),并寻址比群集可以在连接到 DataNode 的存储中保留更多的数据。此架构在 HDFS 群集短暂(例如,云场景)和/或需要读取驻留在其他存储系统(例如,Blob 存储)中的数据的情况下特别有用。

提供的存储是 HDFS 中的一项实验性功能。

简介

在撰写本文时,将外部存储挂载为 PROVIDED 块的支持仅限于创建实现 org.apache.hadoop.fs.FileSystem 接口的远程命名空间的只读映像,并启动一个 NameNode 来提供该映像。具体来说,支持从远程命名空间的快照中读取。在本版本中,无法将远程命名空间添加到现有/正在运行的名称节点、刷新远程快照、卸载和写入。可以使用 ViewFsRBF 将带有 PROVIDED 存储的命名空间集成到现有部署中。

使用 PROVIDED 存储创建 HDFS 集群

可以使用 fs2img 工具创建远程命名空间的快照。给定远程 FileSystem 的路径,该工具会创建一个镜像命名空间的映像和一个别名映射,该映射将生成的映像中的块 ID 映射到远程文件系统中的 FileRegionFileRegion 包含足够的信息来寻址远程 FileSystem 中的固定字节序列(例如,文件、偏移量、长度)和一个随机数,以验证自生成映像以来该区域未更改。

创建 NameNode 映像和别名映射后,必须配置 NameNode 和 DataNode 以一致地引用此地址空间。当 DataNode 注册到附加的 PROVIDED 存储时,NameNode 会认为所有外部块都可以通过该 DataNode 寻址,并可能开始将客户端定向到它。对称地,DataNode 必须能够将 PROVIDED 存储中的每个块映射到远程数据。

部署详细信息因配置的别名映射实现而异。

PROVIDED 配置

每个 NameNode 支持一个别名映射。启用 PROVIDED 存储时,在 NameNode 和 DataNode 上配置的存储 ID 必须匹配。所有其他详细信息都是别名映射实现的内部信息。

启用 PROVIDED 存储的配置如下。别名映射实现可用的配置选项如下所示。

<configuration>

  <property>
    <name>dfs.namenode.provided.enabled</name>
    <value>true</value>
    <description>Enabled provided storage on the Namenode</description>
  </property>

  <property>
     <name>dfs.datanode.data.dir</name>
     <value>[DISK]/local/path/to/blocks/, [PROVIDED]remoteFS://remoteFS-authority/path/to/data/</value>
  </property>

  <property>
      <name>dfs.provided.storage.id</name>
      <value>DS-PROVIDED</value>
      <description>The storage ID used for provided storages in the cluster.</description>
  </property>

  <property>
    <name>dfs.provided.aliasmap.class</name>
    <value>org.apache.hadoop.hdfs.server.common.blockaliasmap.impl.TextFileRegionAliasMap</value>
  </property>

</configuration>

fs2img 工具

fs2img 工具通过递归枚举远程 URI 的子项来“遍历”远程命名空间,以生成 FSImage。某些属性可以通过插件控制,例如从远程文件系统到 HDFS 的所有者/组映射以及文件到 HDFS 块的映射。

运行该工具时可用的各种选项是

选项 属性 默认值 说明
-o, --outdir dfs.namenode.name.dir file://${hadoop.tmp.dir}/dfs/name 输出目录
-b, --blockclass dfs.provided.aliasmap.class NullBlocksMap 块输出类
-u, --ugiclass hdfs.image.writer.ugi.class SingleUGIResolver UGI 解析器类
-i, --blockidclass hdfs.image.writer.blockresolver.class FixedBlockResolver 块解析器类
-c, --cachedirs hdfs.image.writer.cache.entries 100 最大活动目录项
-cid--clusterID 集群 ID
-bpid--blockPoolID 块池 ID

示例

分配所有文件归“rmarathe”所有,写入 gzip 压缩文本

hadoop org.apache.hadoop.hdfs.server.namenode.FileSystemImage \
  -Dhdfs.image.writer.ugi.single.user=rmarathe \
  -Ddfs.provided.aliasmap.text.codec=gzip \
  -Ddfs.provided.aliasmap.text.write.dir=file:///tmp/
  -b org.apache.hadoop.hdfs.server.common.blockaliasmap.impl.TextFileRegionAliasMap \
  -u org.apache.hadoop.hdfs.server.namenode.SingleUGIResolver \
  -o file:///tmp/name \
  hdfs://afreast/projects/ydau/onan

在 LevelDB 中根据自定义 UGIResolver 分配所有权

hadoop org.apache.hadoop.hdfs.server.namenode.FileSystemImage \
  -Ddfs.provided.aliasmap.leveldb.path=/path/to/leveldb/map/dingos.db \
  -b org.apache.hadoop.hdfs.server.common.blockaliasmap.impl.LevelDBFileRegionAliasMap \
  -o file:///tmp/name \
  -u CustomResolver \
  hdfs://enfield/projects/ywqmd/incandenza

别名映射实现

使用 dfs.provided.aliasmap.class 参数配置要使用的别名映射实现。目前,支持以下两种类型的别名映射。

InMemoryAliasMap

这是一个基于 LevelDB 的别名映射,作为 NameNode 中的独立服务器运行。可以使用 fs2img 工具创建别名映射本身,使用选项 -Ddfs.provided.aliasmap.leveldb.path=file:///path/to/leveldb/map/dingos.db -b org.apache.hadoop.hdfs.server.common.blockaliasmap.impl.LevelDBFileRegionAliasMap,如上例所示。

数据节点使用 org.apache.hadoop.hdfs.server.aliasmap.InMemoryAliasMapProtocol 协议联系此别名映射。

配置

<configuration>
  <property>
    <name>dfs.provided.aliasmap.inmemory.batch-size</name>
    <value>500</value>
    <description>
      The batch size when iterating over the database backing the aliasmap
    </description>
  </property>

  <property>
    <name>dfs.provided.aliasmap.inmemory.dnrpc-address</name>
    <value>namenode:rpc-port</value>
    <description>
      The address where the aliasmap server will be running
    </description>
  </property>

  <property>
    <name>dfs.provided.aliasmap.inmemory.leveldb.dir</name>
    <value>/path/to/leveldb/map/dingos.db</value>
    <description>
      The directory where the leveldb files will be kept
    </description>
  </property>

  <property>
    <name>dfs.provided.aliasmap.inmemory.enabled</name>
    <value>true</value>
    <description>Enable the inmemory alias map on the NameNode. Defaults to false.</description>
  </property>

  <property>
    <name>dfs.provided.aliasmap.class</name>
    <value>org.apache.hadoop.hdfs.server.common.blockaliasmap.impl.InMemoryLevelDBAliasMapClient</value>
  </property>
</configuration>

TextFileRegionAliasMap

此别名映射实现将 blockIDFileRegion 的映射存储在分隔文本文件中。此格式对于测试环境(尤其是单节点)很有用。

配置

<configuration>
  <property>
    <name>dfs.provided.aliasmap.text.delimiter</name>
    <value>,</value>
    <description>
        The delimiter used when the alias map is specified as
        a text file.
    </description>
  </property>

  <property>
    <name>dfs.provided.aliasmap.text.read.file</name>
    <value>file:///path/to/aliasmap/blocks_blocPoolID.csv</value>
    <description>
        The path specifying the alias map as a text file,
        specified as a URI.
    </description>
  </property>

  <property>
    <name>dfs.provided.aliasmap.text.codec</name>
    <value></value>
    <description>
        The codec used to de-compress the alias map. Default value is empty.
    </description>
  </property>

  <property>
    <name>dfs.provided.aliasmap.text.write.dir</name>
    <value>file:///path/to/aliasmap/</value>
    <description>
        The path to which the alias map should be written as a text
        file, specified as a URI.
    </description>
  </property>
</configuration>