HDFS 支持写入由数据节点管理的堆外内存。数据节点将异步地将内存中的数据刷新到磁盘,从而从对性能敏感的 IO 路径中移除昂贵的磁盘 IO 和校验和计算,因此我们将此类写入称为延迟持久化写入。HDFS 为延迟持久化写入提供尽力而为的持久性保证。在副本持久化到磁盘之前,如果节点重新启动,则可能会丢失少量数据。应用程序可以选择使用延迟持久化写入,以牺牲一些持久性保证来降低延迟。
此功能从 Apache Hadoop 2.6.0 开始提供,并在 Jira HDFS-6581 下开发。
目标用例是受益于以低延迟写入相对较少的数据量(从几 GB 到几十 GB,具体取决于可用内存)的应用程序。内存存储适用于在集群内运行且与 HDFS 数据节点并置的应用程序。我们观察到,网络复制的延迟开销抵消了写入内存的好处。
使用延迟持久化写入的应用程序将继续工作,如果内存不足或未配置,则会回退到磁盘存储。
本节列举了应用程序在集群中开始使用该功能之前所需的管理步骤。
首先决定用于存储在内存中的副本的内存量。在 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 磁盘可以提高数据节点进程重启期间的数据持久性。以下设置适用于大多数 Linux 发行版。目前不支持在其他平台上使用 RAM 磁盘。
tmpfs
(相对于 ramfs
)Linux 支持使用两种 RAM 磁盘 - tmpfs
和 ramfs
。tmpfs
的大小受 Linux 内核限制,而 ramfs
会增长以填满所有可用系统内存。tmpfs
有一个缺点,即其内容在内存压力下可以交换到磁盘。但是,许多对性能敏感的部署在禁用交换的情况下运行,因此我们预计这在实践中不会成为问题。
HDFS 目前支持使用 tmpfs
分区。正在进行添加 ramfs
的支持(参见 HDFS-8584)。
使用 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
分区进行延迟持久化写入。
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
卷视为非易失性存储,并且数据不会保存到持久性存储。你将在节点重启时丢失数据。
确保已启用用于开启存储策略的全局设置,如此处所述。此设置默认启用。
应用程序指示 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);