调优磁盘使用率
本页面提供了减少 Elasticsearch 索引存储空间的策略。磁盘使用情况受字段映射、索引设置、文档结构以及分段和分片管理方式的影响。请利用这些建议来提高压缩率、剔除不必要的数据,并针对您的特定用例优化存储。
默认情况下,Elasticsearch 会对大多数字段进行索引并添加 doc values,以便它们能够开箱即用进行搜索和聚合。例如,如果您有一个名为 foo 的数值字段,您需要对其运行直方图,但永远不需要对其进行过滤,那么您可以在 mappings 中安全地禁用该字段的索引
PUT index
{
"mappings": {
"properties": {
"foo": {
"type": "integer",
"index": false
}
}
}
}
text 字段在索引中存储归一化因子以便利文档评分。如果您只需要对 text 字段进行匹配功能,而不关心生成的评分,则可以改用 match_only_text 类型。该字段类型通过舍弃评分和位置信息,显著节省了空间。
默认的 动态字符串映射 会将字符串字段同时索引为 text 和 keyword。如果您只需要其中一个,这会造成浪费。通常,id 字段只需要索引为 keyword,而 body 字段只需要索引为 text 字段。
可以通过在字符串字段上配置显式映射,或设置将字符串字段映射为 text 或 keyword 的动态模板来禁用此功能。
例如,这里有一个模板,可用于仅将字符串字段映射为 keyword
PUT index
{
"mappings": {
"dynamic_templates": [
{
"strings": {
"match_mapping_type": "string",
"mapping": {
"type": "keyword"
}
}
}
]
}
}
更大的分片在存储数据时效率更高。要增加分片的大小,您可以通过创建索引时使用较少的主分片、减少索引创建数量(例如利用 Rollover API),或者使用 Shrink API 修改现有索引来减少索引中的主分片数量。
请记住,分片过大也有缺点,例如完整的恢复时间较长。
有关分片策略的更多信息,请参考调整分片大小。
_source 字段存储文档的原始 JSON 主体。如果您不需要访问它,可以将其禁用。但是,需要访问 _source 的 API(例如 update、highlight 和 reindex)将无法工作。
_source 和存储的字段很容易占用不可忽视的磁盘空间。通过使用 best_compression 编码器,可以对它们进行更积极的压缩。
Elasticsearch 中的索引存储在一个或多个分片中。每个分片都是一个 Lucene 索引,由一个或多个分段(磁盘上的实际文件)组成。较大的分段存储数据的效率更高。
可以使用 force merge API 来减少每个分片中的分段数量。在许多情况下,通过设置 max_num_segments=1,每个分片的段数可以减少到一个。
我们建议仅对只读索引(即不再接收写入的索引)进行强制合并。当文档被更新或删除时,旧版本不会被立即移除,而是被软删除(soft-deleted)并标记为“墓碑 (tombstone)”。这些软删除的文档会在常规的分段合并期间自动清理。但是,强制合并可能会产生非常大(> 5GB)的分段,这些分段不符合常规合并的条件。因此,软删除文档的数量可能会迅速增长,从而导致更高的磁盘使用率和更差的搜索性能。如果您定期对正在接收写入的索引进行强制合并,这也会使快照成本更高,因为新文档无法以增量方式备份。
shrink API 允许您减少索引中的分片数量。结合上面的 force merge API,这可以显着减少索引的分片和分段数量。
您为数值数据选择的类型会对磁盘使用情况产生重大影响。特别是,整数应使用整数类型(byte、short、integer 或 long)存储,而浮点数如果合适的话应存储在 scaled_float 中,或者存储在适合用例的最小类型中:使用 float 代替 double,或使用 half_float 代替 float,将有助于节省存储空间。
当 Elasticsearch 存储 _source 时,它会一次压缩多个文档,以提高整体压缩率。例如,文档共享相同的字段名非常普遍,而且它们共享某些字段值也很常见,尤其是对于具有低基数或 齐夫分布 的字段。
默认情况下,文档会按照它们被添加至索引的顺序一起进行压缩。如果您启用了索引排序,则它们将改为按排序后的顺序进行压缩。将具有相似结构、字段和值的文档排序在一起应该会提高压缩率。
由于多个文档被一起压缩进块中,如果字段总是以相同的顺序出现,则在这些 _source 文档中更有可能找到更长的重复字符串。
保留旧数据对于以后的分析很有用,但由于存储成本的原因,通常会避免这样做。您可以使用降采样来汇总和存储历史数据,而成本只是原始数据存储成本的一小部分。请参见对时间序列数据流进行降采样。