3、缓存架构基础:缓存分层模型(L1/L2/L3)、缓存命中率与延迟、写回与写直达策略
3.1 缓存分层模型(L1 / L2 / L3)
在倒排索引缓存系统中,单一缓存层往往无法同时满足极低延迟、高吞吐与大数据量的需求。因此,业界普遍采用多级缓存(Multi-Level Cache)架构,将数据按访问频率、成本与容量分层放置。典型的倒排索引缓存分为三层:
| 层级 | 存储介质 | 典型容量 | 访问延迟 | 主要用途 |
|---|---|---|---|---|
| L1(一级缓存) | 进程内内存(堆内 / 堆外) | 几百 MB ~ 几 GB | < 1 μs | 热词倒排列表、高频查询结果 |
| L2(二级缓存) | 分布式内存(Redis / Memcached) | 几十 GB ~ 几百 GB | 1 ~ 5 ms | 中频词项、聚合统计缓存 |
| L3(三级缓存) | 本地 SSD / 远程 KV 存储 | 几 TB ~ 几十 TB | 10 ~ 50 ms | 冷数据、全量索引快照 |
设计要点:L1 追求极致速度,通常使用
ConcurrentHashMap 或 Caffeine 实现;L2 侧重数据共享与一致性;L3 作为降级兜底,保证缓存未命中时仍能从近端存储快速恢复。
下图展示了倒排索引查询在三级缓存中的流动路径:
3.2 缓存命中率与延迟
缓存系统的核心性能指标是命中率(Hit Ratio)与平均访问延迟(Average Latency)。两者共同决定了查询的整体响应速度。
3.2.1 命中率公式
对于三级缓存,全局命中率计算如下:
全局命中率 = 1 - (1 - h1) × (1 - h2) × (1 - h3)
其中:
h1 = L1 命中率
h2 = L2 命中率(L1 未命中时)
h3 = L3 命中率(L1、L2 均未命中时)
3.2.2 平均延迟模型
平均访问延迟由各级命中率与延迟加权计算:
平均延迟 = h1 × t1 + (1 - h1) × h2 × t2 + (1 - h1) × (1 - h2) × h3 × t3 + (1 - h1) × (1 - h2) × (1 - h3) × t_miss
典型数值示例(假设 t_miss = 100ms):
h1=0.85, t1=0.001ms
h2=0.70, t2=3ms
h3=0.95, t3=30ms
→ 平均延迟 ≈ 0.85×0.001 + 0.15×0.70×3 + 0.15×0.30×0.95×30 + 0.15×0.30×0.05×100
→ ≈ 0.00085 + 0.315 + 1.2825 + 0.225 = 1.823ms
关键结论:L1 命中率每提升 5%,平均延迟可降低约 0.5~1ms。在倒排索引场景中,热词(Top 10% 词项)贡献了 80% 以上的查询量,优先提升 L1 热词命中率是性价比最高的优化手段。
3.2.3 命中率影响因素
- 缓存容量:容量越大,能容纳更多词项,但边际收益递减。
- 淘汰策略:LRU(最近最少使用)适合倒排索引的时间局部性;LFU(最不经常使用)适合稳定热词。
- 词项分布:Zipf 分布下,少量热词占据大部分流量,L1 只需覆盖热词即可获得高命中率。
- 写入频率:索引更新越频繁,缓存失效越多,命中率越低。
3.3 写回(Write-Back)与写直达(Write-Through)策略
当倒排索引发生增量更新(如新增文档、词项合并)时,缓存与后端存储之间的数据同步策略直接影响一致性与写入性能。两种主流策略对比如下:
| 策略 | 写入流程 | 延迟 | 一致性 | 适用场景 |
|---|---|---|---|---|
| 写直达(Write-Through) | 同时写入缓存和后端存储,确认两者均成功后返回 | 较高(等待存储确认) | 强一致性(缓存与存储实时同步) | 对一致性要求高的核心索引、金融级搜索 |
| 写回(Write-Back) | 仅写入缓存,标记脏数据,异步批量刷回后端存储 | 低(仅内存写入) | 最终一致性(短时间窗口内可能不一致) | 高吞吐写入、日志索引、近实时搜索 |
倒排索引场景注意:写回策略在缓存节点宕机时可能丢失未刷盘的脏数据。建议配合 WAL(Write-Ahead Log)或复制机制保证数据不丢。写直达虽然一致性更强,但写入延迟会放大,不适合高频词项更新。
下图对比了两种策略在倒排索引更新时的数据流差异:
3.4 策略选择建议
- 热词更新频繁且允许短时不一致:使用写回策略,配合 L1 缓存 TTL 过期机制,降低写入延迟。
- 核心元数据或一致性敏感数据:使用写直达策略,确保每次写入都同步到后端存储。
- 混合方案:L1 采用写回 + L2 采用写直达,兼顾写入性能与跨节点一致性。
- 错误处理集成:写回策略必须实现脏数据队列重试与崩溃恢复;写直达需处理存储超时时的缓存回滚。
实践参考:在 Elasticsearch 的倒排索引缓存中,FST(有限状态转换器)缓存使用写回策略,而段合并后的元数据更新使用写直达。这种分层策略选择是倒排索引缓存一致性闭环设计的关键。