HDFS 的内存存储是什么?

引言

HDFS 的定位就是一个文件系统,用于存储文件,而 HDFS 对于文件的存储方式有两种:

  • 内存存储

  • 异构存储

内存存储

什么是内存存储?

首先,我们来了解一下到底什么是 “内存存储”?

那还用说嘛,当然就是使用内存来存储数据的方式咯!是的,在 HDFS 中,“内存存储” 就是我们常听到的 " LAZY_PERSIST "。

我们可以在 HDFS 上创建某个文件时设定它的存储模式为 "LAZY_PERSIST" 模式,如此一来,后续在这个文件上所追加的所有数据都会被直接保存在对应数据节点的内存上。而使用内存来作为数据的存储介质的好处想必就不用我多说了,但同时在内存上保存数据的坏处也很让人头疼啊。内存的容量小、掉电数据尽数丢失,无论哪一个问题都能让相关人员头皮炸裂。但又不能为了避免这些风险而完全放弃内存存储,毕竟它的好处也实在是太诱人了。

那怎么办呢?尽可能地去解决它的缺点呗!最合适的解决方案就是 “异步持久化” 了。

什么是 “异步持久化”?

说白了就是对于使用内存存储模式的那些文件数据,再另外开一个线程,在后台将一些老旧的数据持久化到磁盘上去,在系统正常停服时,可能只需要很短的时间就能将剩余的在内存中的数据全部持久化到磁盘中去了,而对于服务器掉电、宕机等情况,可能也只是损失一小部分数据而已,工程师们是能够容忍一小部分数据丢失的情况的 。而这个 “异步持久化” 过程对于终端用户而言是透明的。也正是由于这种延时落地数据到磁盘的机制,才使得内存存储得到一个 "LAZY_PERSIST" 的英文名称。

如何使用内存存储模式?

那前面我们了解了内存存储的基本概念以后,在日常开发过程中又要如何来使用内存存储模式呢?

其实可以有两种方式来设置使用内存存储模式:

命令行设置

使用命令行设置的方式,可以使用如下命令

复制代码
hdfs storagepolicies -setStoragePolicy -path <path> -policy <policy>

但是一定要注意,只能给目录设置。下面是一条使用命令设置内存存储模式的实例

复制代码
[root@hdp-01 ~]$ hdfs storagepolicies -setStoragePolicy -path lemontea2 -policy LAZY_PERSIST
Set storage policy LAZY_PERSIST on lemontea2

上面的命令表示我在 . 目录下创建了一个 lemontea2 目录,并将这个目录设置成 LAZY_PERSIST 模式,后续所有在这个目录下创建的文件都会以内存存储模式来保存。

Java 代码设置

使用 Java 代码来设置的方式也是发生在文件创建时。我们可以发现在 org.apache.hadoop.fs.FileSystem 抽象类中有这样一个方法

复制代码
public FSDataOutputStream create(Path f,
      FsPermission permission,
      EnumSet<CreateFlag> flags,
      int bufferSize,
      short replication,
      long blockSize,
      Progressable progress) throws IOException {
    return create(f, permission, flags, bufferSize, replication,
        blockSize, progress, null);
  }

这个方法中的参数 flags 就是用于设置存储模式的,这个 flags 所支持的所有模式有如下所示

复制代码
CreateFlag specifies the file create semantic. Users can combine flags like: 
EnumSet.of(CreateFlag.CREATE, CreateFlag.APPEND) 

Use the CreateFlag as follows: 
1. CREATE - to create a file if it does not exist,else throw FileAlreadyExists.
2. APPEND - to append to a file if it exists,else throw FileNotFoundException.
3. OVERWRITE - to truncate a file if it exists,else throw FileNotFoundException.
4. CREATE|APPEND - to create a file if it does not exist,else append to an existing file.
5. CREATE|OVERWRITE - to create a file if it does not exist,else overwrite an existing file.
6. SYNC_BLOCK - to force closed blocks to the disk device.In addition Syncable.hsync() should be called after each write,if true synchronous behavior is required.
7. LAZY_PERSIST - Create the block on transient storage (RAM) ifavailable.
8. APPEND_NEWBLOCK - Append data to a new block instead of end of the lastpartial block.

我们在 Java 代码中创建某个文件时使用这个方法来创建就可以设置了。

内存存储模式在 DataNode 中如何运转?

在 DataNode 中有三种角色共同参与到内存存储模式的 “日常运维” 过程中去。

  • RamDiskReplicaLruTracker:它是一个大管家,负责整理整个内存中所有的数据信息。

  • LazyWriter:它是一个监督员,它的任务就是不断地从数据块列表中取出数据,好将它扔给第三个角色来将数据持久化到磁盘中去。

  • RamDiskAsyncLazyPersistService:它本质上是一个线程池,但是专门负责将数据持久化到磁盘中去。

开发过程中如何使用内存存储模式?

我们知道,内存存储模式是将数据保存在内存上的,但我们的 HDFS 的数据文件说白了还是在我们的物理机器的本地文件系统上。HDFS 的数据不能真的在接收到以后直接就缓存在电脑内存中。

那有什么办法可以让 HDFS 在做了这种写出数据到本地文件系统,实际上又还是在内存上保存的方法呢?

答案就是 Linux 的虚拟硬盘。

虚拟硬盘其实就是将内存映射成硬盘,像访问硬盘一样来访问内存。那关于 Linux 虚拟硬盘的设置这里也不详说了,总之就是将 /dev/shm 节点以 tmpfs 的模式挂载到某个目录下,然后再将这个目录填到 hdfs-site.xml 中去。

总的来说,要想使用内存存储模式,得满足以下三个条件:

  1. 确保本地文件系统中有虚拟硬盘的存在,并将它填写在 hdfs-site.xml 中的 dfs.datanode.data.dir 配置项中,以逗号分隔开。虚拟硬盘的前面要加上标识符 [RAM_DISK]。
复制代码
<property>
  <name>dfs.datanode.data.dir</name>
  <value>/var/data/1,/var/data/2,[RAM_DISK]/mnt/mytmpfs/0</value>
</property>
  1. 确保 HDFS 的异构存储策略是打开状态的,即配置项 dfs.storage.policy.enabled

  2. 确保内存值设置的正确性,即配置项 dfs.datanode.max.locked.memory

posted @   Binge-和时间做朋友  阅读(495)  评论(0编辑  收藏  举报
编辑推荐:
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
阅读排行:
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· C#/.NET/.NET Core优秀项目和框架2025年2月简报
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 【杭电多校比赛记录】2025“钉耙编程”中国大学生算法设计春季联赛(1)
点击右上角即可分享
微信分享提示