先把当时的情况摆出来。把向量改成 on_disk 想省内存,服务重启后第一次查询要 8 秒,后续恢复到 40 毫秒,监控告警在每次发布后都连续触发。
原因不止一个,得分开看。向量落盘后首次查询要从磁盘读入并建缓存。还有一种是冷启动没有预热,请求直接打在磁盘上。
另外,HNSW 索引与向量是两个开关,只开一个省不了多少内存。少数情况下是磁盘 IOPS 不足时读放大更明显。
上来先确认两个 on_disk 开关的状态
curl -s http://127.0.0.1:6333/collections/kb | jq '.config'
然后重启后先跑一批查询做预热
python -c "print(['预热问题%d'%i for i in range(50)][:3])"
接着把 HNSW 留在内存只让向量落盘
curl -X PATCH http://127.0.0.1:6333/collections/kb -H "Content-Type: application/json" -d '{"vectors":{"on_disk":true},"hnsw_config":{"on_disk":false}}'
末了对比预热前后的首查延迟
curl -s -o /dev/null -w "%{time_total}\n" -X POST http://127.0.0.1:6333/collections/kb/points/search -H "Content-Type: application/json" -d '{"vector":[0.1,0.2],"limit":5}'
同事提醒我看一下最近一次发布,时间点确实对得上。
恢复的判定其实很直接。预热后的首次查询在 1 秒内返回,P99 稳定在 60 毫秒以内,内存占用比全内存模式下降一半。
on_disk 省的是内存不是延迟,读多写少还得看磁盘是否 NVMe,机械盘上开了反而更慢。这类问题最好一次改到位,反复小改反而容易把原因搅混。
