HDFS 中的内存存储支持

简介

HDFS 支持写入由数据节点管理的堆外内存。数据节点将异步地将内存中的数据刷新到磁盘,从而从对性能敏感的 IO 路径中移除昂贵的磁盘 IO 和校验和计算,因此我们将此类写入称为延迟持久化写入。HDFS 为延迟持久化写入提供尽力而为的持久性保证。在副本持久化到磁盘之前,如果节点重新启动,则可能会丢失少量数据。应用程序可以选择使用延迟持久化写入,以牺牲一些持久性保证来降低延迟。

此功能从 Apache Hadoop 2.6.0 开始提供,并在 Jira HDFS-6581 下开发。

Lazy Persist Writes

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

使用延迟持久化写入的应用程序将继续工作,如果内存不足或未配置,则会回退到磁盘存储。

管理员配置

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

限制用于内存中副本的 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>

此内存不会在启动时由数据节点分配。

在类似 Unix 的系统上,数据节点用户的“锁定在内存中的大小”ulimit(ulimit -l)也需要增加以匹配此参数(请参阅 操作系统限制 上的相关部分)。设置此值时,请记住,您还需要内存空间用于其他内容,例如数据节点和应用程序 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/ 下挂载 32 GB 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 分区进行延迟持久化写入。

使用 RAM_DISK 存储类型标记 tmpfs

通过 hdfs-site.xml 中的 dfs.datanode.data.dir 配置设置,使用 RAM_DISK 存储类型标记 tmpfs 目录。例如,在一个具有三个硬盘卷 /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);