HDFS 内存存储支持——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);

参考

https://hadoop.apache.org/docs/r3.1.1/hadoop-project-dist/hadoop-hdfs/MemoryStorage.html
https://blog.csdn.net/androidlushangderen/article/details/51514216

发布了57 篇原创文章 · 获赞 3 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/CPP_MAYIBO/article/details/97621141