2016年,东京飞往巴黎的航班上,一个前端工程师读完了Rust官方教程。他刚在Exalead干了几年企业搜索,又在Indeed日本分部摸过Lucene 2.4的底。14小时后落地,他决定用这门新语言造个搜索引擎——不是为替代谁,就想验证自己到底懂不懂这行。

7年后,这个叫Tantivy的Rust库成了Quickwit、ParadeDB、LNX的底层引擎,甚至让Lucene团队主动找上门合作优化性能。2024年,Datadog收购了他创办的Quickwit。这个航班上的 side project,最终成了云原生日志搜索领域最被低估的基础设施之一。

「长期发酵的挫败感」是顶级驱动力

「长期发酵的挫败感」是顶级驱动力

Paul Masurel的搜索生涯始于法国企业搜索公司Exalead,职位是前端工程师。「我喜欢认为,我的挫败感源于不属于核心团队。」他在采访中这样描述,「长期发酵的挫败感在我看来是一种被低估的驱动力。」

这种挫败感把他推到了Indeed日本分部的后端岗位,终于摸到搜索引擎的核心。但Lucene 2.4的代码库像一座年久失修的大教堂——功能完备,但没人敢动地基。Paul想要的是那种「小到开发者能真正拥有」的东西。

2016年的那次飞行给了他契机。Rust的所有权模型、零成本抽象、 fearless concurrency(无畏并发),对一个写惯C++的人来说像一份精确的手术工具包。他花了两个月业余时间,在GitHub上扔出了第一个版本——「有点傻,但证明这想法能跑」。

他没打算造Lucene的替代品,只想造一个自己能完全理解的系统。

模块化不是功能,是生存策略

模块化不是功能,是生存策略

Tantivy的设计哲学藏在它的 crate(Rust的包单元)结构里。索引、查询、分词、存储——每个组件都可以单独替换或禁用。Paul从Lucene汲取了架构灵感,但用Rust的类型系统做了更激进的解耦。

这种模块化在2017年看起来像是过度设计。但当2020年Quickwit需要为日志场景定制倒排索引格式时,他们直接换掉了Tantivy的存储层,而不是 fork 整个项目。ParadeDB在PostgreSQL里嵌入Tantivy做混合搜索时,也只用了索引和查询模块,分词器用的是自己的。

「Rust确实影响了代码组织方式,但我不认为它塑造了架构。」Paul说,「Lucene才是真正的灵感来源。」

这句话的潜台词是:Tantivy不是Rust炫技的产物,而是一个熟悉Lucene的人,用更现代的工具重新实现了一遍——同时修正了那些「历史遗留的妥协」。

与Lucene从竞争到「奇怪的合作」

与Lucene从竞争到「奇怪的合作」

2022年,Lucene核心开发者Adrien Grand在基准测试中发现了一个反常现象:Tantivy在某些查询场景下比Lucene快30%。不是Rust对Java的胜利,而是Tantivy采用了一种更激进的跳表(skip list)压缩策略。

Paul原本预期的是防御姿态。毕竟Lucene背后有Elastic、AWS、Google的工程师,Tantivy只有他一个人在周末维护。但Grand发来的邮件里没有敌意,只有一行:「你们是怎么做到的?」

接下来的18个月,两个团队开始共享优化思路。Lucene 9.7采纳了Tantivy的跳表布局;Tantivy 0.21则借鉴了Lucene的块最大WAND(Weak AND)算法变体。这种「开源层面的竞合」在基础设施领域极其罕见——通常要么吞并,要么无视。

Paul的解读很直接:「搜索是一个足够深的领域,没有团队能垄断所有好想法。」

Datadog收购背后的技术赌注

Datadog收购背后的技术赌注

2020年,Paul与François Massot创办Quickwit,目标是用Tantivy做云原生的日志搜索。当时市场已经被Elastic Cloud和Splunk瓜分,但有一个缝隙没人填:PB级日志的低成本存储+秒级查询。

Quickwit的解法是把索引和对象存储(S3/MinIO)解耦。热数据走本地SSD,温数据存对象存储,查询时按需拉取索引块。Tantivy的模块化设计让这种「分层存储」成为可能——他们只改了存储层,查询引擎原封不动。

2024年Datadog收购Quickwit时,后者已经处理着每月数十PB的日志量。对Datadog来说,这不是人才收购(acqui-hire):Quickwit的架构直接补上了自家日志产品在高延迟查询上的短板,而Tantivy的Rust代码库比Java更易做安全审计。

Paul现在Datadog负责搜索基础设施。他的GitHub提交记录显示,每周仍有固定时间维护Tantivy——这个7年前的 side project,如今有两个全职维护者和47个贡献者。

被问到「如果2016年没上那趟航班」时,Paul停顿了一下:「我可能会用Go写,然后卡在垃圾回收的停顿上。或者干脆不写,继续在Indeed调Lucene的参数。」

那个航班上的决定,本质上是一个工程师对「可理解性」的执念——而可理解性,最终成了可扩展性的前提。当大多数团队还在争论「Rust是不是比Java快」时,Tantivy的用例已经证明:语言只是工具,对问题域的深刻理解才是护城河。

下一个会用Rust重写的基础设施会是什么?Paul没有直接回答,但提到了他正在看的领域:向量搜索的索引结构。「HNSW(分层可导航小世界图)在内存里很漂亮,但没人解决好怎么把它高效地序列化到磁盘。」他说,「这听起来像2016年的搜索索引,不是吗?」