在计算广告系统中,广告召回是流量分发的首道关卡。面对千万级广告池、百亿级日流量,系统需在 10~20ms 内完成精准广告筛选。头部广告引擎的高性能核心,是一套离线倒排索引固化规则、在线后缀表达式动态编译、位图位运算求值的动静分离架构。本文精简拆解这套工业级核心原理与工程优化。
一、核心架构:动静分离解耦
广告召回的核心冲突是广告规则静态固定与用户请求动态多变,行业标准解法为三层动静分离架构:
- 离线静态层:预处理广告定向条件,构建内存倒排索引,规避在线重复计算;
- 在线动态层:基于实时用户画像,编译生成专属布尔检索表达式;
- 高速计算层:通过集合栈+CPU位运算,线性完成广告过滤匹配。
整套架构完全规避全量遍历、磁盘IO、字符串比对等低效操作,全程内存整型位运算,适配高并发低延迟的广告场景。
二、离线构建:无歧义广告倒排索引
倒排索引是广告召回的数据基石,重点解决定向语义歧义与集合运算效率两大问题。
1. 标准化Term消除歧义
系统统一采用维度_值拼接规则生成唯一特征Term,如 age_25、os_ios,彻底解决单一数值多维度语义混淆问题,实现定向条件标准化。
2. Bitmap位图存储广告集合
索引核心结构:Term Key → Bitmap Value
- Key:标准化组合特征;
- Value:Bitmap位图,每一位对应一条广告,位值为1代表广告匹配该特征。
相比传统ID列表,Bitmap内存占用极低,且原生支持CPU交、并、差位运算,为极速检索提供硬件级支撑。
三、在线编译:用户特征转后缀表达式
为适配机器线性执行,系统将复杂嵌套的中缀布尔表达式,通过调度场算法转为无分支、无括号的后缀表达式(RPN) 。
1. 核心规则
广告布尔检索存在固定优先级:NOT > AND > OR。该顺序并非人为定义,而是适配布尔语义与机器执行的工业级标准,也是调度场算法栈匹配的核心依据。
2. 布尔优先级底层原理
布尔算子的优先级排序,核心由算子属性与业务语义决定,完全匹配广告定向的真实匹配逻辑:
1)NOT 优先级最高(单目算子特性)
NOT 是单目运算符,仅作用于紧邻的单个特征条件,用于修饰、取反单一规则。如果优先级低于 AND/OR,会直接篡改业务逻辑。例如定向规则A AND NOT B,必须优先执行 NOT B,再执行交集运算;若优先级倒置,会被错误解析为 NOT(A AND B),彻底偏离“满足A、剔除B”的定向需求。所有单目取反运算,天然优先级高于双目运算。
2)AND 优先级居中(交集等价乘法)
AND 是交集运算,逻辑上等价于数学「乘法」,代表精准、严格的条件约束。在混合逻辑中,需要优先执行精准筛选。例如 A OR B AND C,默认语义为 A OR (B AND C),先通过 AND 完成精准条件匹配,再通过 OR 做宽泛兜底,完全贴合广告定向“先精准、后宽泛”的业务逻辑。
3)OR 优先级最低(并集等价加法)
OR 是并集运算,逻辑上等价于数学「加法」,代表宽泛的条件兜底,因此最后执行。该规则与 SQL、检索引擎、编程语言布尔逻辑完全统一,是工业界通用标准。
3. 编译规则与 RPN 执行细节(NOT 重点纠错)
- 特征Term(操作数) :解析用户画像得到的特征标签,直接推入后缀表达式序列,作为集合运算的数据源。
- 双目算子 AND/OR:严格遵循优先级栈内比对、弹栈输出,保证左右集合的运算顺序不错乱,匹配常规定向逻辑。
- 单目算子 NOT(核心易错点) :NOT 仅作用于紧邻的前一个特征集合,属于后置单目运算。 业务定向常用逻辑:
A AND NOT B(满足A、剔除B人群) 正确 RPN:A B NOT AND 执行语义:先对 B 集合取反,再与 A 集合求交,等价于集合差集 A-B。 致命误区:A B AND NOT语义为「对 A∩B 整体取反」,完全不符合广告剔除定向,属于典型编译错误。 - 括号作用:仅用于人工配置复杂逻辑时改变优先级,编译完成后全部消除,输出纯线性、无分支的可执行表达式。
复杂定向逻辑可在微秒内完成扁平化转换,完美适配计算机单向扫描执行特性。
四、在线检索:Bitmap集合栈位运算求值
系统通过Bitmap集合栈执行后缀表达式,栈中元素为广告ID位图集合,全程无递归、无分支。
1. 执行流程
- 遇到特征Term:查询倒排索引,将对应广告Bitmap压栈;
- 遇到布尔算子:弹出栈顶两个集合,执行AND/OR/AND_NOT位运算,结果重新压栈。
2. 结果输出
遍历结束后,栈顶唯一Bitmap即为匹配全部用户定向规则的候选广告全集,直接送入排序环节,全程毫秒级响应。
五、工业级核心性能优化
针对百亿流量瓶颈,头部引擎通过四项底层优化榨干硬件算力:
1. 特征整型化,舍弃字符串运算
通过全局字典将字符串Term转为整型FeatureID,算子映射为固定负数,全流程基于整型数组运算,消除字符串比对损耗,大幅提升CPU缓存命中率。
2. AND_NOT算子融合,规避全集爆炸
标准 RPN 表达式 A B NOT AND 虽然逻辑准确,但存在严重性能隐患:原生 NOT 需要计算全局广告全集补集,在千万级广告库下会造成内存与 CPU 瞬间爆炸。因此广告引擎做了专属编译优化:将高频的「与非」业务语法,预编译为独立的 AND_NOT 二元算子。运行时直接执行 A.andNot(B),从A集合中精准剔除B集合,无需构建全局全集,彻底规避补集运算的性能瓶颈。
3. Roaring Bitmap + SIMD并行计算
采用Roaring Bitmap分层存储,极致压缩内存占用;底层绑定CPU SIMD指令,单指令并行处理数十条广告逻辑,集合运算吞吐量大幅提升。
4. WAND算法提前剪枝
结合广告eCPM、出价预估,在检索阶段提前过滤无法进入Top榜单的低质广告,无需完成完整表达式计算,大幅减少无效算力消耗。
六、总结:广告召回的设计精髓
整套工业级广告召回架构,本质是静态预处理降复杂度、动态编译适配个性化流量的高性能设计范式。
广告定向规则离线固化为紧凑的倒排 Bitmap,规避在线重复解析;用户千面的画像与筛选逻辑,通过调度场算法动态编译为线性后缀表达式;最终依托 CPU 位运算、SIMD 向量化、算子融合、WAND 剪枝等多层优化,实现极致低延迟检索。
以简单的「索引查询 + 集合栈运算」,支撑千万级广告池、百亿流量下的毫秒级召回,是后端高并发系统中「预处理换低延迟、硬件级算力压榨」的经典落地案例。