前言
最近一段时间,笔者在业余时间继续对HDFS的扩展性内容进行学习。一句话来概括,越往里深入,越发现里面可以讲的东西越多,涉及到的点也越多。社区在这个方面确实做了很多的讨论。本文所讲述的主题源自于社区JIRA HDFS-7844(Create an off-heap hash table implementation),大意是利用堆外内存(off-heap)来进行元数据的存储。之前我们总是提到的NameNode内存空间使用过大,指的是JVM中的堆内存。而堆外内存是不受JVM管理的,它由操作系统来管理。如果将Block、INode中的数据从堆内移到堆外存储,无疑将会巨大减轻NameNode压力。在下文中,笔者会花一定篇幅介绍此内容,并同时介绍HDFS块优化相关的内容。
堆外内存概述
堆外内存,通俗地理解,就是不受JVM控制的内存。堆外内存在使用上能支持更大空间的内存存储。还有一点好处是堆外内存可以在JVM间共享,减少对象的复制。
在现有JDK中,有2种可以对堆外内存进行使用的API。
第一种,nio包中的ByteBuffer相关的API。如下代码示例:
ByteBuffer buffer = ByteBuffer.allocateDirect(10 * 1024 * 1024);
第二种,调用Unsafe方法进行堆外内存的使用,示例代码如下:
Unsafe.allocateMemory(1024 * 1024 * 20);
以上2种方法的使用类似于C语言中的malloc方法。
关于堆外内存更多的资料大家可以自行查找资料进行学习。
HDFS堆外内存哈希存储的设计
在了解完堆外存储的基本概念之后,我们重新回到本文的主题。在HDFS-7844中,以off-heap的方式实现了一个哈希存储表。作者在设计此存储表的目的是为了将来存Block块数据、INode文件数据做使用的。
在原设计中,作者并不是直接在哈希表上对内存做直接管理,而是先定义内存管理器类,此内存管理器类是可配的,在这里它有可能就是off-heap的。在内存管理器内部,才是对数据进行直接存入、取出的操作。
相比于off-heap的内存管理器&#