Solr中stored field与docValues存储、性能及配置选型咨询
Solr stored字段与DocValues相关问题解答
1. 两类字段的存储位置
Solr索引按段(segment)拆分独立存储,两类字段的存储文件和结构完全不同:
- stored fields(存储字段):属于行式存储结构,存放在对应段目录下的
.fdt(存实际字段值)、.fdx(文档ID到字段值位置的位置索引)、.fdm(段级元数据)三类文件中。所有字段值按文档ID聚合排列,同一个文档的所有stored字段值在磁盘上是连续存储的,读取单文档多字段时仅需扫描连续磁盘块即可完成。 - docValues字段:属于列式存储结构,按字段维度独立组织存储,存放在对应段目录下的
.dvd(存实际列值)、.dvm(列级元数据)文件中(不同字段类型的底层存储细节略有差异)。同一个字段的所有文档值连续排列,支持堆外内存直接映射读取,不需要全量加载到JVM堆内存。
2. 无分面/排序的普通查询场景下的性能对比
这种场景下启用docValues不会带来性能提升,多数场景下性能反而比只用stored fields差:
普通查询的字段读取逻辑是点查命中的少量文档的指定返回字段值,stored fields的行存结构对这个场景适配性极强——读取单个文档的N个返回字段只需要1次连续IO就能拿到所有值。而docValues是列存结构,要获取N个字段的值需要分别访问N个独立列文件的对应位置,随机IO开销、寻址成本会随返回字段数量上升明显升高。
只有当查询仅返回1-2个短值原子字段时,两者性能差距才会缩小到可忽略的程度,不存在docValues性能更优的情况。
3. 生产环境是否建议全量替换stored fields为docValues
完全不建议做全量替换,核心原因有三点:
- 存储成本不划算:对于长文本、大内容字段(比如文章正文、商品详情、富文本摘要),docValues的列式存储压缩率远低于stored的行式存储,全量替换会大幅提升磁盘占用。
- 性能适配有缺陷:如前面所说,多字段返回的普通查询场景下,docValues的点查延迟明显高于stored fields,全量替换会直接拉高核心查询链路的响应时间。
- 功能支持有限:docValues仅适合存储原子类型的未分词字段(数值、日期、精确值字符串等),分词后的text类型字段、KB级以上的大值字段即使配置docValues,存储和读取的性价比也极低,不存在全量替换的可行性。
生产实践参考
- 长文本、大值、分词字段:仅开启stored即可,不需要开启docValues
- 用于排序、分面、聚合的短值原子字段(价格、分类ID、上架时间、状态标记等):必须开启docValues,是否保留stored可按业务场景调整:如果这类字段经常作为独立返回字段、查询返回字段总数很少,可以关闭stored节省空间;如果查询时需要和多个其他字段一起返回,建议保留stored兼顾查询性能。
内容的提问来源于stack exchange,提问作者Eli Johnes
相关产品推荐
相关产品推荐

