目录
- 介绍
- 配置
- 存储副本的内存限制
- 在DataNode上配置使用RAM disk
- 选择tmpfs(与ramfs相比)
- 挂载RAM disk
- 使用 RAM_DISK 存储类型标记 tmpfs 卷
- 确保启用了存储策略
- 应用程序的使用
- 为目录调用 hdfs storagepolicies 命令
- 为目录调用setStoragePolicy 方法
- 为新文件传递创建标记LAZY_PERSIST
- 参考
介绍
HDFS支持将数据写入到由DataNode管理的堆外内存中。数据节点会异步的将内存中的数据flush到磁盘,从而从性能敏感的IO路径中删除高开销的磁盘IO和checksum 计算,因此将这种写入称为Lazy Persist 写入。HDFS为Lazy Persist Writes提供了最大努力(best-effort)的持久化保证。在将副本持久化到磁盘之前如果有节点重启,可能会有罕见的数据丢失。应用程序可以选择使用Lazy Persist Writes 以牺牲一些持久性保证换取更低的延迟。
HDFS的这个特性是从 Apache Hadoop 2.6.0 开始支持,详情参考 HDFS-6581。
下图是 Lazy Persist的原理图:
目标用例是一些应用程序,它们将在写入较少数据量的时候(基于可用内存,从几GB到几十GB)受益较低的延迟。内存存储用于在运行在集群内并与HDFS 数据节点搭配的应用程序。我们已经观察到网络复制的延迟开销抵消了写入内存的好处。
如果内存不足或未配置,则使用Lazy Persist 写入的应用程序将通过回滚到磁盘存储来继续工作。
配置
存储副本的内存限制
在使用内存来存储副本时,首先需要决定需要使用的内存总量。通过在hdfs-site.xml中设置dfs.datanode.max.locked.memory 参数指定。这和集中式内存管理的设置是同一个设置。数据节点会确保Lazy persist Write 和 集中式内存管理使用的内存总量不超过该配置项设置的值。
如下示例,设置使用32GB内存
<property>
<name>dfs.datanode.max.locked.memory</name>
<value>34359738368</value>
</property>
注意:该内存并不会在DataNode启动时分配。
在类UNIX系统中,还需要设置 DataNode 上用户的locked-in-memory size 限制(ulimit -l)来匹配该参数值。另外设置这个值的时候,还需要综合考虑其他的内存需求,如DataNode和应用程序的JVM内存以及操作系统的page cache,如果有yarn NodeManager也运行在同一节点上,还要考虑container使用的内存。
在DataNode上配置使用RAM disk
初始化每个数据节点上的RAM disk。RAM disk的选择允许跨DataNode进程重启的更好的数据持久性。以下设置适用于大多数Linux发行版。目前不支持在其他平台上使用RAM磁盘。
选择tmpfs(与ramfs相比)
Linux支持使用两种 RAM disk —— tmpfs 和 ramfs。tmpfs的大小会受到Linux内核的限制,而ramfs会一直增长到填满所有可用的系统内存。tmpfs有一个缺点,就是在内存压力下它的内存会被交换到disk中。但是许多性能敏感的部署会在禁用交换的情况下运行,因此我们不希望这在实践中成为问题。
HDFS目前只支持使用tmpfs分区,ramfs的支持还在开发中(见HDFS-8584)。
挂载RAM disk
RAM disk的挂载和普通磁盘的挂载一样,都是使用mount命令,如下,将32GB的ramfs挂载到 /mnt/dn-tmfs/下
sudo mount -t tmpfs -o size=32g tmpfs /mnt/dn-tmpfs/
建议将挂载命令添加到 /etc/fstab中,这样在节点重启时可以自动重建RAM disk。另一个选择是使用/dev/shm下的一个子目录,这是在大多数Linux发行版下默认可以使用tmpfs挂载。确保挂载的大小大于或等于dfs.datanode.max.locked.memory的设置,否则会在 /etc/fstab 中覆盖它。不建议为每个DataNode设置多个tmpfs分区来进行Lazy Persist Writes。
使用 RAM_DISK 存储类型标记 tmpfs 卷
通过hdfs-site.xml文件中的 dfs.datanode.data.dir 配置项来使用 RAM_DISK 存储类型标记 tmpfs 卷。如,在一个有3块磁盘(/grid/0, /grid/1 和 /grid/2 )和一个tmpfs disk(挂载到/mnt/df-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 卷当做 non-volatile 存储,数据就不会保存到持久化存储中。这样数据会在节点重启时丢失。
确保启用了存储策略
确保HDFS的设置中启用了存储策略(Storage Policies)。该特性默认是开启的。
应用程序的使用
应用程序可以指明HDFS使用 LAZY_PERSIST 存储策略对一个文件使用 Lazy Persist Writes。策略设置不需要管理权限,通过以下三种方式之一进行设置。
为目录调用 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
应用程序在创建新文件时使用FileSystem#create API传递CreateFlag#LAZY_PERSIST
FSDataOutputStream fos =
fs.create(
path,
FsPermission.getFileDefault(),
EnumSet.of(CreateFlag.CREATE, CreateFlag.LAZY_PERSIST),
bufferLength,
replicationFactor,
blockSize,
null);