IPinfo 作为 IP 地址数据提供商,开发了一种缩小 MMDB 文件体积的方法。MMDB 文件广泛用于快速查询地理位置和 ASN 信息等 IP 元数据。MMDB 格式由两个主要部分组成:搜索树(基于 IP 地址位数的二进制前缀树)和数据部分(实际记录所在的区域)。虽然数据部分已经支持记录共享,但搜索树通常不支持。标准的写入程序通常为树中的每个位置生成一个新的节点,当多个 IP 前缀指向相同的数据记录时,会导致显著的体积膨胀。

此图展示了第一段中提到的 MMDB 格式的主要组成部分。
为了解决这个问题,IPinfo 实施了一种称为 hash-consing 的技术。该方法涉及从叶节点向上遍历现有树,并使用哈希表来识别结构相同的节点。如果一对子节点已经被处理过,该工具将重用现有的规范节点,而不是创建重复节点。这使得搜索树转变为有向无环图(DAG),其中多个父节点可以指向同一个共享子树。由于 MMDB 格式已经支持此类共享,因此该优化不需要对文件格式或读取库进行任何更改;生成的优化文件仍与现有工具完全兼容。

此视觉效果解释了第二段中描述的 hash-consing 机制和生成的 DAG 结构。
在生产测试中,这一优化使 IPinfo 的 89 个数据库目录的总大小减少了 31%,其中某些特定数据库的缩减比例高达 80%。由于 MMDB 文件是内存映射的,这些节省直接转化为更小的内存占用和在查询过程中更少的缺页中断。虽然主要的节省来自搜索树,但数据部分保持不变。IPinfo 已将此优化作为 `mmdbshrink` 开源,允许其他开发者在保持相同的查询结果和性能的同时,缩小他们自己的 MMDB 文件体积。
目前仍有一个技术考量涉及 MMDB 标头中的 `record_size` 字段。由于 hash-consing 显著减少了搜索树中的节点数量,可能存在减少分配给记录大小的位数的机会,这可能带来额外的 12-25% 的空间节省。然而,此类更改将需要修改文件的内部元数据结构,而当前的 `mmdbshrink` 工具在不改变底层数据格式的任何一个字节的情况下就实现了其优化效果。