2026-10-31·by Sijie Wang

block-size-and-metadata-math

Block size 128 MB, metadata about 150 bytes per object, Cloudera examples, seek amortisation, and the heap rule of 1 GB per million blocks.

块大小与元数据算术:决定内存的是文件个数,不是数据量

默认值是经验值,不是算出来的。 HDFS 块大小默认 128MB,可用 dfs.blocksize 配置。它是权衡各项成本后定的经验默认值,不是从方程里解出来的。历史:GFS 是 64MB,早期 Hadoop 是 64MB,Hadoop 2 起默认 128MB,存超大文件的集群有用 256MB 的。

算术只有一条规则。 每个元数据对象——一个文件节点、一个块——在 NameNode 里大约占 150 字节。这个数是近似的、随版本在 150–200 字节量级浮动。只作量级估算,绝不当精确堆大小。

objects=files+blocksobjects = files + blocks metadata≈objects×150 bytesmetadata \approx objects \times 150\ \text{bytes}

Cloudera 官方例子。 同样的数据,切法不同,元数据代价天差地别。192MB 文件是 2 块加 1 个文件节点,共 3 个对象:

3×150=450 bytes3 \times 150 = 450\ \text{bytes}

同样 1GB 写成一个大文件,是 8 块加 1 个文件节点,共 9 个对象:

9×150=1350 bytes9 \times 150 = 1350\ \text{bytes}

同样 1GB 切成 1024 个 1MB 文件,是 1024 个文件节点加 1024 个块,共 2048 个对象:

2048×150=307200 bytes2048 \times 150 = 307200\ \text{bytes}

同样 1GB 数据,这是大文件情形的约 228 倍:

307200/1350≈228307200 / 1350 \approx 228

放大到 1TB。 写成 8192 个 128MB 文件,是 8192 个文件节点加 8192 个块,共 16384 个对象,元数据约 2.3MiB。写成 1048576 个 1MB 文件,是 2097152 个对象,元数据 300MiB。同样的数据,128 倍元数据:

2097152/16384=1282097152 / 16384 = 128

为什么是 128MB:寻道摊销。 机械盘寻道约 10ms,顺序读约 100MB/s。传 128MB 要 1.28s,寻道占不到 1%;传 1MB 约 10ms,寻道约占 50%。块必须大到寻道相对读数据可以忽略。但块太大也有代价:并行度下降(能同时读的片变少)、恢复粒度变粗(丢一块要补拷的数据更多)。

绝不能把 150×对象数当堆大小报。 副本只是位置,不是新的块对象,但块映射等额外开销使 Cloudera 的实践规则是每 100 万个唯一块约 1GB 堆:3600 万块约需 36GB 堆,远高于 150 字节乘对象数。150 字节算的是账本,堆规则算的是机器。

决定内存的是文件个数,不是数据量。 10PB 存成大文件约 8000 万块、几十 GB 元数据,一台大内存服务器装得下;10PB 全是 10KB 小文件约 10 亿个文件、几百 GB 元数据,一台机器装不下。大堆还有自己的代价:GC 停顿随堆增大而变长。HA 里的 standby 只是把同一本账在内存里再抄一份,并不提高容量。超出单机就得拆账本,见 federation;这个病本身见 small-files。

about this entry

One of sijie's wiki entries. The AI on this site is grounded in the same corpus and answers in sijie's voice, with citations back to entries like this one — answering costs sijie money, so it waits behind a code: enter an access code →