NameNode堆内存估算
在HDFS中,数据和元数据是分开存储的,数据文件被分割成若干个数据块,每一个数据块默认备份3份,然后分布式的存储在所有的DataNode上,元数据会常驻在NameNode的内存中,而且随着数据量的增加,在NameNode中内存的元数据的大小也会随着增加,那么这个时候对NameNode的内存的估算就变的非常的重要了。

这里说的内存就是指NameNode所在JVM的堆内存

NameNode内存数据结构非常丰富,除了我们前面讲到的Namespace tree和BlocksMap外,其实还包括如LeaseManager/SnapShotManager/CacheManager/NetworkTopology等管理的数据,但是这些管理数据占用的内存非常的小,我们在估算NameNode内存的时候一般都忽略这些数据所占内存大小。所以在NameNode内存中,主要的内存分别被Namespace tree和BlocksMap占有,那么我们现在只要估算Namespace tree和BlocksMap所占内存即可。

我们在Namespace tree中估算了假设HDFS目录和文件数分别为1亿,Block总量在1亿情况下,整个Namespace在JVM中内存使用情况:

Total(Directory) = (8 + 72 + 80) ∗ 100M + 8 ∗ num(total children)
Total(Files) = (8 + 72 + 56) ∗ 100M + 8 ∗ num(total blocks)
内存总大小是:Total(Directory) + Total(Files) = (8 + 72 + 80) ∗ 100M + 8 * 200M + (8 + 72 + 56) ∗ 100M + 8 * 100M = 31.25G
我们在BlocksMap中估算了假设集群中共1亿Block,NameNode可用内存空间固定大小128GB,则BlocksMap占用内存情况:

BlocksMap直接内存大小 + (Block直接内存大小 + BlockInfoContiguous直接内存大小) * 100M + LightWeightGSet直接内存大小
28字节 + (40字节 + 136字节) * 100M + 60字节 + (2%*128G) = 19.7475GB
那么综上,假设整个HDFS集群中目录和文件数分别为1亿,Block总量在1亿情况下,NameNode可用内存空间固定大小128GB,总共占用的内存为:

Namespace tree所占内存大小 + BlocksMap所占内存大小 = 31.25G + 19.7475GB = 50.9975GB
我们上面已经提供了估算NameNode内存的方式,接下来我们再站在Files和Blocks的粒度上来估算NameNode需要的内存

Files和Blocks在NameNode内存其实主要的就是存储着两种类型的对象,一个是File对象,一个是Block对象。

从Namespace tree中我们可以得到:

一个File对象的大小大概为:8 + 72 + 56 = 136字节
一个Directory对象的大小大概为:8 + 72 + 80 = 160字节
从BlocksMap中我们可以得到:

一个Block对象的大小大概为:40字节 + 136字节 = 176字节
为了方便计算,我们现在假设不管是File对象还是Block对象,他们每一个占用的内存大约为150字节。

假设现在有一个192MB的文件,数据块的大小是默认的128M,那么这个192MB的文件会被切分成两个数据块,一个数据块的大小是128MB,另一个数据块的大小是64MB。就会有3个对象(1个File对象和2个Block对象)存在于NameNode的内存中,占用的内存的大小大约为 3 * 150字节 = 450字节。

大文件被切分成的数据块越少,那么占用NameNode的内存就越少。比如一个128MB大小文件被切分成一个数据块的时候占用的内存大约是300字节(一个File对象和一个Block对象);相反,128个1MB的文件在NameNode的内存中会产生256个对象(128个File对象 + 128个Block对象),这样的话则会占用256 * 150字节 = 38400字节的内存

Replication(备份)
我们知道HDFS的数据块的默认的备份数是3,我们需要知道的是备份数的设置会影响磁盘容量而不会影响NameNode中内存容量。

如果我们现在设置备份数为1,数据块的大小是128MB。那么一个192MB的文件需要集群的192MB大小的磁盘容量和450字节的内存容量;假设有192TB的数据,这些数据包括了一百万文件和两百万数据块,那么需要集群的192TB磁盘容量和(一百万File对象 + 两百万Block对象) * 150字节 = 450MB的内存容量。

当我们设置备份数为默认备份数(即3)的时候,对于192TB的数据,需要集群的192 TB * 3 = 576 TB的磁盘容量,但是需要的NameNode中的内存容量还是450MB。所以说NameNode中的内存大小和备份数多少关系并不是太大

例子
接下来我们看下两个估算NameNode内存的例子,在看这两个例子之前,我们先记住一个经验值:每一百万个Block需要NameNode的1G内存。

上面的是一个经验值,你可以按照一百万个Block伴随着有一百万个文件和一百万个目录来进行估算下,不管怎么样,这个是一个比较靠谱的经验者,我们可以使用这个经验值进行估算我们的集群需要多少NameNode的内存

例子一
假设有1GB(1024MB)的数据,我们将它切分成不同数量文件和数据块(数据块大小为128M),然后分别来看下NameNode需要消耗多少内存:

一个 1GB 的文件
1个File对象
8个Block对象(1024MB / 128M)
Total = 9个对象 * 150字节 = 1350 bytes

8个文件,每个文件128MB
8个File对象
8个Block对象
Total = 16个对象 * 150字节 = 2400字节

1024个1MB的文件
1024个File对象
1024个Block对象
Total = 2048个对象 * 150字节 = 307200字节

例子二
在这个例子中,我们假设有两个HDFS集群,两个集群的总磁盘容量都是4800 TB。其中集群A的数据块的备份数设置为1,集群B的数据块的备份数设置为3;两个集群的数据块大小都是128M。那么两个集群的NameNode分别需要的最大的堆内存是多少呢?

集群A:200台主机,每台主机的磁盘容量是24 TB,总共的磁盘容量大小是4800 TB
数据块大小是128M,备份数是1
集群的磁盘容量:200 * 24,000,000 MB = 4,800,000,000 MB (4800 TB)
每一个数据块需要的磁盘容量是:128 MB per block * 1 = 128 MB
集群可以容纳的数据块的数量:4,800,000,000 MB / 128 MB = 36,000,000 blocks
我们上面提到,一般情况下,一百万的数据块需要1G的内存,那么36,000,000的数据块就需要36GB的内存

集群B:200台主机,每台主机的磁盘容量是24 TB,总共的磁盘容量大小是4800 TB
数据块大小是128M,备份数是3
集群的磁盘容量:200 * 24,000,000 MB = 4,800,000,000 MB (4800 TB)
每一个数据块需要的磁盘容量是:128 MB per block * 3 = 384 MB
集群可以容纳的数据块的数量:4,800,000,000 MB / 384 MB = 12,000,000 blocks
一般情况下,一百万的数据块需要1G的内存,那么12,000,000的数据块就需要12GB的内存

集群A和集群B的磁盘存储容量都是一样的,但是集群B因为备份数的增加,使得可以存储的数据块的数量变少了,所以集群B的NameNode需要的内存相应的也变小了。

NameNode堆内存估算相关推荐

  1. Linux堆内存管理深入分析(上)

    Linux堆内存管理深入分析 (上半部) 作者:走位@阿里聚安全   0 前言 近年来,漏洞挖掘越来越火,各种漏洞挖掘.利用的分析文章层出不穷.从大方向来看,主要有基于栈溢出的漏洞利用和基于堆溢出的漏 ...

  2. 调整JVM堆内存解决OutOfMemoryError

    今天在用 processing(http://zh.wikipedia.org/wiki/Processing) 编写处理 midi 文件的程序的时候,遇到了一个问题.程序主要是读取分析 midi , ...

  3. java虚拟机内存比例,【Java虚拟机】堆内存分配策略总结

    1 一般情况 对象出生在Eden区. 第一次MinorGC之后仍然存活,并且能被Survivor容纳,则被移动到Survivor空间中,并将年龄设为1. 对象在Survivor区中每熬过一次Minor ...

  4. JVM运行时数据区---堆(堆内存)

    运行时数据区-堆 JVM 堆的对象分配过程 堆中TLAB为对象分配内存 堆-逃逸分析与代码优化 堆的核心概念 <Java虚拟机规范>中对Java堆的描述是:所有的对象实例以及数组都应当在运 ...

  5. jvm from space 很小_JVM真香系列:堆内存详解

    前面的文章中已经有所提到过堆,只是大致介绍了一下.本文就来详细聊聊JVM中的堆. 在 JVM中,堆被划分成两个不同的区域:新生代 ( Young ).老年代 ( Old ). 新生代 ( Young ...

  6. was修改堆内存_C语言内存泄露很严重,如何应对?

    摘要:通过介绍内存泄漏问题原理及检视方法,希望后续能够从编码检视环节就杜绝内存泄漏导致的网上问题发生. 1. 前言 最近部门不同产品接连出现内存泄漏导致的网上问题,具体表现为单板在现网运行数月以后,因 ...

  7. 栈和堆存储在计算机RAM中,堆内存和栈内存及C++内存分配

    1.现代操作系统内存管理主流的操作系统(Windows,Linux)都采用虚拟内存管理的方式,具体说就是:页式管理.段式管理.段页式管理. 操作系统分配资源的单位是进程,所以,内存管理的过程也是以进程 ...

  8. Java基础-Java中的堆内存和离堆内存机制

    Java基础-Java中的堆内存和离堆内存机制 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 转载于:https://www.cnblogs.com/yinzhengjie/p/9 ...

  9. 面性对象中栈内存和堆内存的理解

    栈和堆都是Java用来在RAM(随机只读存储器)中存放数据的地方,Java自动管理栈和堆,程序员不能直接地设置栈和堆. Java堆是运行时数据区,通过new关键字从中分配内存空间,在堆内存中产生的垃圾 ...

最新文章

  1. YOLOv4:目标检测(windows和Linux下Darknet 版本)实施
  2. hashlib模式和hmac模式
  3. hibernate延迟加载lazy的原理,以及为什么session关闭会报错
  4. 关于Java栈与堆的思考
  5. 【转】Memcached管理与监控工具----MemAdmin
  6. openstack-5:安装rabbitmq
  7. linux 安装apache http server
  8. 飞鸽传书也具有五华石乡特色
  9. openpyxl 列 插入_python3对excel读写openpyxl
  10. 使用devops的团队_具有DevOps心态的团队的蓝图
  11. JMETER HTTP 请求
  12. azure云数据库_将Azure SQL数据库警报集成到Slack
  13. 我安装java了_我安装了JAVA为什么.......
  14. mac 安装php7.4
  15. mybatis--面向接口编程
  16. 过VMP加壳程序的自效验
  17. 应用程序“xxx“不能打开,怎么解决?
  18. 爬虫--爬取雪球网数据
  19. phpnow升级mysql版本_phpnow1.5.6-1升级phpmyadmin,php及mysql版本
  20. ant-design-vue导航菜单a-menu的详细使用

热门文章

  1. 【WangEditor】使用富文本编辑器 WangEditor 实现用户自定义图片大小(改js源码)
  2. SWFObject.js入门
  3. API是用来干什么的
  4. GPS卫星的导航电文和卫星信号
  5. GNSS原理与应用(五)——GPS卫星信号
  6. 基于微信平台的电影购票系统设计与实现(程序+论文)
  7. 原子操作 - linux内核锁(一)
  8. iOS UITextView 纯英文排版换行出错的解决方案
  9. RGB值和RGBA值
  10. java正则表达式练习