HDFS的NameNode堆內存估算


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字節的內存

節 = 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需要的內存相應的也變小了。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM