HDFS中的内存存储支持

简介

HDFS支持将数据写入由数据节点管理的堆外内存。数据节点会异步将内存中的数据刷新到磁盘,从而从性能敏感的IO路径中移除昂贵的磁盘IO和校验和计算,因此我们称这种写入为延迟持久化写入。HDFS为延迟持久化写入提供尽力而为的持久性保证。在副本被持久化到磁盘之前若发生节点重启,可能会出现罕见的数据丢失情况。应用程序可以选择使用延迟持久化写入,以牺牲部分持久性保证为代价来换取更低的延迟。

该功能从Apache Hadoop 2.6.0版本开始提供,是在Jira HDFS-6581下开发的。

Lazy Persist Writes

目标用例是那些可以从低延迟写入相对少量数据(从几GB到几十GB不等,具体取决于可用内存)中受益的应用程序。内存存储适用于在集群内运行并与HDFS数据节点共置的应用程序。我们观察到,网络复制的延迟开销抵消了写入内存的优势。

Applications that use Lazy Persist Writes will continue to work by falling back to DISK storage if memory is insufficient or unconfigured.

管理员配置

本节列举了在集群中应用程序开始使用该功能之前所需的管理步骤。

限制内存中副本使用的RAM

首先确定要分配给内存中存储副本的内存量。在hdfs-site.xml中相应设置dfs.datanode.max.locked.memory。这与集中式缓存管理功能使用的设置相同。数据节点将确保惰性持久化写入和集中式缓存管理使用的总内存不超过dfs.datanode.max.locked.memory中配置的数值。

例如:为内存中的副本预留32 GB

    <property>
      <name>dfs.datanode.max.locked.memory</name>
      <value>34359738368</value>
    </property>

这部分内存并非由Data Node在启动时分配。

在类Unix系统上,还需要增加数据节点用户的"锁定内存大小"ulimit限制(ulimit -l)以匹配此参数(参见OS Limits相关章节)。设置此值时,请记住您还需要为其他内容预留内存空间,例如数据节点和应用程序JVM堆以及操作系统页面缓存。如果YARN节点管理器进程与数据节点运行在同一节点上,您还需要为YARN容器预留内存。

在数据节点上设置RAM磁盘

在每个数据节点上初始化一个RAM磁盘。选择RAM磁盘可以在数据节点进程重启时提供更好的数据持久性。以下设置适用于大多数Linux发行版。目前不支持在其他平台上使用RAM磁盘。

选择 tmpfs (对比 ramfs)

Linux系统支持使用两种RAM磁盘 - tmpfsramfstmpfs的大小受Linux内核限制,而ramfs会增长直至占用所有可用系统内存。tmpfs存在一个缺点,即在内存压力下其内容可能被交换到磁盘。不过许多对性能敏感的部署环境都会禁用交换功能,因此我们预计这在实际应用中不会成为问题。

HDFS 目前支持使用 tmpfs 分区。添加 ramfs 的支持正在进行中(参见 HDFS-8584)。

挂载RAM磁盘

使用Unix的mount命令挂载RAM磁盘分区。例如,要在/mnt/dn-tmpfs/下挂载一个32GB的tmpfs分区

    sudo mount -t tmpfs -o size=32g tmpfs /mnt/dn-tmpfs/

建议您在/etc/fstab中创建一个条目,以便在节点重启时自动重建RAM磁盘。另一种选择是使用/dev/shm下的子目录,这是大多数Linux发行版默认提供的tmpfs挂载点。请确保挂载点的大小大于或等于您的dfs.datanode.max.locked.memory设置,否则请在/etc/fstab中覆盖该设置。不建议为延迟持久化写入在每个数据节点上使用多个tmpfs分区。

tmpfs卷标记RAM_DISK存储类型

通过hdfs-site.xml中的dfs.datanode.data.dir配置设置,将tmpfs目录标记为RAM_DISK存储类型。例如,在一个具有三个硬盘卷/grid/0/grid/1/grid/2以及tmpfs挂载点/mnt/dn-tmpfs的数据节点上,dfs.datanode.data.dir必须按如下方式设置:

    <property>
      <name>dfs.datanode.data.dir</name>
      <value>/grid/0,/grid/1,/grid/2,[RAM_DISK]/mnt/dn-tmpfs</value>
    </property>

这一步至关重要。如果没有RAM_DISK标签,HDFS会将tmpfs卷视为非易失性存储,数据将不会被保存到持久存储中。节点重启时您将丢失数据。

确保存储策略已启用

确保已启用全局设置以开启存储策略 如文档所述。该设置默认处于开启状态。

应用使用情况

使用LAZY_PERSIST存储策略

应用程序表明,HDFS可以对具有LAZY_PERSIST存储策略的文件使用延迟持久化写入。设置此策略不需要管理员权限,可以通过以下三种方式之一进行设置。

对目录调用hdfs storagepolicies命令

在目录上设置策略将使其对该目录中的所有新文件生效。可以使用hdfs storagepolicies命令来设置策略,具体操作详见存储策略文档

    hdfs storagepolicies -setStoragePolicy -path <path> -policy LAZY_PERSIST

为目录调用setStoragePolicy方法

从Apache Hadoop 2.8.0开始,应用程序可以通过FileSystem.setStoragePolicy以编程方式设置存储策略。例如:

    fs.setStoragePolicy(path, "LAZY_PERSIST");

为新文件传递 LAZY_PERSIST CreateFlag

应用程序可以在使用FileSystem#create API创建新文件时传递CreateFlag#LAZY_PERSIST参数。例如:

    FSDataOutputStream fos =
        fs.create(
            path,
            FsPermission.getFileDefault(),
            EnumSet.of(CreateFlag.CREATE, CreateFlag.LAZY_PERSIST),
            bufferLength,
            replicationFactor,
            blockSize,
            null);