省掉千余台机器:广告索引压缩实战

2020 年是广告系统成本优化最激进的一年。我负责的索引压缩项目累计节省了数百G内存(千余台物理机)。这篇文章聊具体怎么做。


成本分析:内存花在哪了?

广告系统的数据分两类:

数据类型 占比 特点
倒排索引 55% 稀疏结构,可高度压缩
正排数据 35% 稠密字段,压缩空间小
模型/特征 10% 基本不可压缩

倒排索引是压缩的头号目标。


压缩策略

1. 倒排链用 PForDelta + SIMD

原始的倒排链存完整 int32 docID,一条链可能有几十万条。改用差值编码后大部分差值能用 4-8 bit 表示。

// 解码时用 SIMD 一次性解压 128 个值
__m128i block = _mm_loadu_si128((__m128i*)compressed_data);
__m128i decoded = _mm_add_epi32(base, block);

SIMD 解压比标量解压快 3-5x,刚好抵消解压开销。

2. 正排字段按需加载

正排(广告标题、描述、落地页 URL 等)占用 35% 内存。但不是所有字段在每次请求中都用得到。

我们把正排拆成三层:

  • L1(热数据):质量分、出价、预算——每次请求必用,全内存
  • L2(温数据):标题、描述——召回时用,按需从共享内存加载
  • L3(冷数据):完整素材——仅在确定要展示时加载

L2/L3 用 mmap 映射,操作系统来管理换入换出。

3. 字段级去重

大量广告主会批量创建相似广告(改个标题再投一次)。相同落地页、相同行业的广告,描述文本高度重复。

我们做了字段级全局去重:相同内容的字段(如落地页 URL)只存一份,索引里存指针。

效果:减少了约 15% 的正排内存。


整体效果

优化项 内存节省
倒排 PForDelta + SIMD 约30%
正排分层按需加载 约25%
字段级去重 约15%
其他 约10%
合计 显著

千余台物理机撤下来后,季度成本明显下降。