Rust in Everything
基于 tantivy 0.27.0

设计取舍

前五部分讲的是 tantivy 怎么写段、怎么存、怎么查。这一部分只有一页,回头看那些代码背后的选择。ARCHITECTURE.md 把它们归结为一句话:查询和写入的内存要有上界,代价是索引「is designed to handle these updates in large batches」。每个取舍都落到具体的源码,说明换来了什么、放弃了什么,能量化的配了本机实测;机制本身只给链接,不再重讲。

  1. 设计取舍:不可变段换来不加锁的读和 mmap,更新只能删了再加;1000 篇文档一篇一提交比一次提交慢约 950 倍,默认 reader 靠 500 ms 轮询,NEAR_REAL_TIME 从 0.9 起一直是 TODO;没有主键,重复文档照收,删除要用不分词的字段;schema 一对一,一个字段一个分析器;同步查询直接放在 tokio worker 上实测把无关任务最长拖慢 177 到 250 ms,spawn_blocking 也要配并发上限;mmap 打开 20 MB 索引只要 0.26 ms,文件被截断时进程被 SIGBUS 杀掉。
flowchart TB
  goal["内存有上界"] --> imm["不可变段"]
  goal --> bat["批量提交"]
  imm --> mm["mmap 直接读"]
  imm --> del["删除按 term"]
  bat --> vis["提交后才可见"]
  goal --> syn["同步 API 自带线程"]
  syn --> tok["tokio 里挪线程"]

这些取舍在实际项目里会变成具体的坑,报错原文和最小复现在 07 常见坑;本站的搜索模块怎么踩中其中几个(每次 upsert 新开 writer、提交后立刻丢弃),见在本站中。

💬 关联讨论

发起讨论
加载中...