在 11 万篇文档的索引上同时进行地理排序搜索时,会导致进程崩溃:每次搜索都会对整个地理 RTree 进行反序列化

作者: aizukanne创建于 2026年8月20日更新于 2026年9月10日

同步在 11M 文件索引 OOM 上进行地理组合搜索 杀死进程:每次搜索都会将整个地理RTree 解析

□ 总结

在11.2M文件的索引上,每个文件都带有QQgeo'点,同时进行数个地理分类搜索,使得meilsearch进程可以分配每个查询的多GB匿名内存,并在数秒内被OOM杀死. 单一的此类查询存活下来(有2–3 GB RSS突起和~1.8 sttency). 如果查询组合继续进行, 进程将重新启动- loops 。

根源似乎在mili'中:对于任何地理搜索,只要有1 000个候选者(GeoSort Strategy:Dynamic (1000)'默认),fill-cache' callsindex.geo-rtree(txn)',bincode-deistrication the whole-corpus RTree<GeoPoint>'从LMDB变成匿名堆积器,每次搜索。 唯一的缓存是每条搜索的 " GeoSort " struct ( " search/ new/geo sort.rs " ) 上的一个字段,因此同时进行的地理搜索保留了树的完整副本。

□ 环境

  • 小型搜索v1.53.1'和v1.52.3'(官方Docker图像getmeili/meilisearch:v1.53.1'/:v1.52.3')——两者行为相同
  • 单一节点,容器内存限制 4 GiB (`mem limit'),主机 16 GB RAM,事件时为~7 GB免费
  • 索引:11,194,620个文档,每个文件都有QQGeo;可搜索文本字段;同义词已配置;其他所有设置默认

□ 观察行为

以“sort”表示的打字头式查询(3/6/10-char前缀)的货币-10基准:[“-geoPoint(lat,lng):asc]:

  • 过程RSS攀升~0.45 GiB~~4 GiB 在秒内,然后内核杀死它:
内存 cgroup 出自内存 : 已杀死进程 1692285 (meilisearch)
共计-vm:2175979948kB,动能:4091448kB,文件-s:31200kB
oom- kill: constract=CONSTRAINT MEMCG,. 任务=meilisearch (中文(简体) ).

(在两个版本和三个查询变体中记录了10起这种杀人事件;`Total-vm'在每起杀人事件中为~2.17起PB-据推测主要为稀有的LMDB地图,此处列出其完整性。 )

  • 客户端看到已丢弃的连接(连接错误'/远程协议错误'),而不是HTTP错误。 ——单最坏情况查询(3-char前缀,100k+考生) 隔离:HTTP 200 in1.76 S,RSS spoke~2–3 GiB,进程活下来.
  • 将候选人套装捆绑起来有**** 帮助:增加'“过滤器”:-GeoRadius(lat,lng 500)''仍然在货币下崩溃,限制在6/10-char前缀也是如此——这与整个树木负荷独立于被过滤的候选人套装一致。
  • 同一指数上的基线,无地缘分类:第95页 61-77毫秒,以相值为10;零出错;平稳RSS~100 MiB.

□ 代码指针( 当前“ 主要”)

  • crates/mili/src/documents/geo-sort.rs'-fill-cache()'呼叫index.geo-rtree(txn)',并将结果插入self.rtree'(仅指`GeoSort'-Intance缓存)。
  • crates/mili/src/index.rs'-geo rtree ()'返回SerdeBincode<RTree>GeoPoint>>从`main'DB中去区域化:每个呼叫一个完整的自有副本。
  • crates/mili/src/search/new/geo-sort.rs ' ——GeoSort ' 排名规则(每次搜索构建) . . . . . . .

内容来源: meilisearch/meilisearch