先把当时的情况摆出来。Elasticsearch 8.10 上给 dense_vector 字段写 index_options: {type: 'int8_hnsw', m: 16},PUT mapping 返回 400,原文 unknown parameter [int8_hnsw],同一份 mapping 放到 8.13 的测试集群能通过,删索引重建也停在同一个参数上。

把日志和配置对完,能解释这个现象的基本就这几处。int8_hnsw 从 8.12 才开始提供。还有一种是用的是 OpenSearch 分支没有这个类型。

还有一种情况,index_options 被写到字段外层。另外,已有 mapping 不能原地改类型只能 reindex。

动手时先确认集群版本

curl -s http://localhost:9200 | jq '.version.number'

新建索引单独验证 int8_hnsw

curl -X PUT http://localhost:9200/vec_test -H "content-type: application/json" -d '{"mappings":{"properties":{"v":{"type":"dense_vector","dims":768,"index_options":{"type":"int8_hnsw","m":16}}}}}'

8.10 先用 hnsw 过渡

curl -X PUT http://localhost:9200/vec_test -H "content-type: application/json" -d '{"mappings":{"properties":{"v":{"type":"dense_vector","dims":768,"index":true,"similarity":"cosine"}}}}}'

升级后 reindex 再对比召回

curl -X POST 'http://localhost:9200/_reindex?wait_for_completion=false' -H "content-type: application/json" -d '{"source":{"index":"vec_v1"},"dest":{"index":"vec_v2"}}'

这台环境是别人交接的,不少默认值被动过,只能一项项核。

同事提醒我看一下最近一次发布,时间点确实对得上。

命令输出我都留了记录,免得改完记不清原来的值。

恢复的判定其实很直接。新索引 mapping 里 index_options.type 为 int8_hnsw,kNN 延迟下降且 100 条抽样的召回率不低于 0.9。

提醒一点。量化是有损的,先拿一成样本对比召回再全量切换,直接覆盖线上索引很难回退。拖得越久,排查成本越高,因为现场状态会被后续操作覆盖。

作者 9823189