调整磁盘使用率

编辑

禁用不需要的功能

编辑

默认情况下,Elasticsearch 会为大多数字段建立索引并添加 doc values,以便可以直接进行搜索和聚合。例如,如果您有一个名为 foo 的数字字段,您需要在其上运行直方图,但您永远不需要对其进行过滤,则可以安全地在您的映射中禁用此字段的索引。

resp = client.indices.create(
    index="index",
    mappings={
        "properties": {
            "foo": {
                "type": "integer",
                "index": False
            }
        }
    },
)
print(resp)
response = client.indices.create(
  index: 'index',
  body: {
    mappings: {
      properties: {
        foo: {
          type: 'integer',
          index: false
        }
      }
    }
  }
)
puts response
const response = await client.indices.create({
  index: "index",
  mappings: {
    properties: {
      foo: {
        type: "integer",
        index: false,
      },
    },
  },
});
console.log(response);
PUT index
{
  "mappings": {
    "properties": {
      "foo": {
        "type": "integer",
        "index": false
      }
    }
  }
}

text 字段在索引中存储归一化因子,以方便文档评分。如果您只需要在 text 字段上进行匹配,而不在意生成的分数,则可以使用 match_only_text 类型。此字段类型通过删除评分和位置信息来节省大量空间。

不要使用默认的动态字符串映射

编辑

默认的动态字符串映射会将字符串字段同时索引为 textkeyword。如果您只需要其中一个,这将是浪费的。通常,id 字段只需要索引为 keyword,而 body 字段只需要索引为 text 字段。

可以通过在字符串字段上配置显式映射或设置将字符串字段映射为 textkeyword 的动态模板来禁用此功能。

例如,这是一个可以用来仅将字符串字段映射为 keyword 的模板

resp = client.indices.create(
    index="index",
    mappings={
        "dynamic_templates": [
            {
                "strings": {
                    "match_mapping_type": "string",
                    "mapping": {
                        "type": "keyword"
                    }
                }
            }
        ]
    },
)
print(resp)
response = client.indices.create(
  index: 'index',
  body: {
    mappings: {
      dynamic_templates: [
        {
          strings: {
            match_mapping_type: 'string',
            mapping: {
              type: 'keyword'
            }
          }
        }
      ]
    }
  }
)
puts response
const response = await client.indices.create({
  index: "index",
  mappings: {
    dynamic_templates: [
      {
        strings: {
          match_mapping_type: "string",
          mapping: {
            type: "keyword",
          },
        },
      },
    ],
  },
});
console.log(response);
PUT index
{
  "mappings": {
    "dynamic_templates": [
      {
        "strings": {
          "match_mapping_type": "string",
          "mapping": {
            "type": "keyword"
          }
        }
      }
    ]
  }
}

注意分片大小

编辑

较大的分片在存储数据方面效率更高。要增加分片的大小,您可以通过创建索引时使用较少的主分片、创建较少的索引(例如,通过利用滚动 API)或使用 缩小 API 修改现有索引来减少索引中主分片的数量。

请记住,较大的分片大小会带来一些缺点,例如较长的完整恢复时间。

禁用 _source

编辑

_source 字段存储文档的原始 JSON 主体。如果您不需要访问它,则可以禁用它。但是,需要访问 _source 的 API(如更新、突出显示和重新索引)将无法工作。

使用 best_compression

编辑

_source 和存储字段很容易占用大量的磁盘空间。通过使用 best_compression 编解码器,可以更积极地压缩它们。

强制合并

编辑

Elasticsearch 中的索引存储在一个或多个分片中。每个分片都是一个 Lucene 索引,由一个或多个段组成 - 磁盘上的实际文件。较大的段对于存储数据更有效。

强制合并 API 可用于减少每个分片的段数。在许多情况下,可以通过设置 max_num_segments=1 将每个分片的段数减少到一个。

我们建议仅对只读索引执行强制合并(这意味着该索引不再接收写入)。 当文档被更新或删除时,旧版本不会立即删除,而是被软删除并标记为“墓碑”。这些软删除的文档会在常规段合并期间自动清除。但是强制合并可能会产生非常大的(> 5GB)段,这些段不符合常规合并的条件。因此,软删除文档的数量可能会迅速增加,从而导致更高的磁盘使用率和更差的搜索性能。如果您定期强制合并接收写入的索引,这也会使快照更昂贵,因为无法增量备份新文档。

缩小索引

编辑

缩小 API 允许您减少索引中的分片数量。与上面的强制合并 API 一起使用,可以显著减少索引的分片和段的数量。

使用足够小的数字类型

编辑

您为数值数据选择的类型会对磁盘使用率产生重大影响。特别是,整数应使用整数类型(byteshortintegerlong)存储,浮点数应适当存储在 scaled_float 中,或者存储在适合用例的最小类型中:使用 float 而不是 double,或者使用 half_float 而不是 float 将有助于节省存储空间。

使用索引排序将相似文档放在一起

编辑

当 Elasticsearch 存储 _source 时,它会一次压缩多个文档,以提高整体压缩率。例如,文档共享相同的字段名称非常常见,并且它们共享一些字段值也很常见,尤其是在具有低基数或 zipfian 分布的字段上。

默认情况下,文档按照添加到索引的顺序一起压缩。如果您启用了索引排序,则它们将按排序顺序压缩。将具有相似结构、字段和值的文档一起排序应提高压缩率。

将字段按相同顺序放置在文档中

编辑

由于多个文档被一起压缩成块,如果字段始终以相同的顺序出现,则在这些 _source 文档中更有可能找到更长的重复字符串。

汇总历史数据

编辑

保留较旧的数据对于以后的分析可能很有用,但由于存储成本通常会避免这样做。您可以使用下采样来汇总和存储历史数据,而成本仅为原始数据存储成本的一小部分。请参阅 下采样时间序列数据流