MD5哈希分层存储策略

image
学习到了一种非常聪明的做法
哈希分层存储策略
它可以解决海量文件在文件系统中存储和读取性能瓶颈的问题

1. 解决的痛点

假设微信有 10 亿用户,每个用户都有一个头像。如果把这 10 亿张图片全部存放在同一个目录下:

HeadImage/user1.jpg
HeadImage/user2.jpg
...

会产生比较严重的后果:
大多数操作系统(如 Linux 的 Ext4 或 Windows 的 NTFS)在一个目录下存放超过几万甚至几十万个文件时,性能会急剧下降。当想要读取某张图片,操作系统需要在数百万个文件中进行查找,速度非常慢。

2. 原理

  • 计算哈希(MD5):
    首先拿到文件的唯一标识(比如用户名 tomato)。对这个标识进行 MD5 运算,生成 MD5 消息摘要/哈希值(如 006f87892f47ef9aa60fa5ed01a440fb)。
    注:MD5 最大的特点是生成的字符分布非常均匀,保证随机性。
  • 提取前缀(分桶):
    取消息摘要的前 2 位字符。这里 tomato 的哈希前两位是 00
  • 物理存储(建目录):
    系统建好以这 2 位字符命名的子目录。这里 tomato 的头像文件就被「扔」进了 HeadImage/00/ 目录🪣中。

3. 优势

A. 负载均衡好(均摊文件)

MD5 生成的消息摘要是 16 进制的(0-9, a-f)。取前 2 位字符,意味着一共有 16 * 16 = 256 种可能性(从 00ff)。MD5 的分布是非常均匀的。如果有 1000 万个头像,通过这种方式,每个子目录下大约只有 10,000,000 / 256 ≈ 39,000 个文件。

B. 寻址速度快(无需数据库查询)

当程序需要读取 tomato 的头像时,它不需要去查数据库。程序只需要在代码里跑一遍同样的逻辑:

  1. md5("tomato") -> 006f87892f47ef9aa60fa5ed01a440fb
  2. 截取前两位 00
  3. 拼接路径:HeadImage/00/ + 文件名
    这是一种“算法寻址”,无需额外的 I/O 开销,效率很高。

C. 可扩展(多级散列)

如果用户量进一步暴增,达到百亿级别,256 个文件夹不够用了怎么办?很简单,取 MD5 消息摘要的前4位,建成二级目录:HeadImage/00/6f/文件名... 。这样就有了 256 * 256 = 65,536 个桶,足以容纳天文数字级的文件,而每个文件夹里的文件数量依然很少。

posted @ 2025-12-09 20:49  南岳云雾茶  阅读(0)  评论(0)    收藏  举报