ElasticSearch索引设计

240 阅读4分钟

何为索引设计?

数据写入之前,提前创建索引设置和数据结构,已达到性能,稳定性和资源利用最大化,通常包括以下方面:

  • 索引存储量评估
  • 索引读写情况
  • 分片设置
  • 副本设置
  • 索引字段类型与扩展
  • 性能参数调优

下面结合Setting和Mapping设计

Setting设计

业务类型

  • 写多读少:压力主要在写入端,
  • 读多写少:对于查询量大的索引,要保证查询性能优先,可以设置更多的分片数以分摊性能

分片设置

分片(shard)是es存储数据的文件块,主要有两种作用:

  • 水平扩展
  • 提高读写性能和吞吐量

数据写入时,每个 doc 会根据routing进行路由:shard = hash(routing)%number_of_primary_shards

所以可以指定路由键保证同类型数据落到同一分片,查询时省去分片协调的时间,但需考虑数据倾斜

一旦创建了分片数,无法更改。

Elastic 官方推荐的单分片大小存储控制在 20GB~40GB 之间,不要超过 50GB,如果单分片存储量超出范围过大,会出现如下问题:

  • 超出单分片文档数限制:es限制doc数为Integer.MAX_VALUE : 2,147,483,519
  • 恢复速度慢: 节点重启、分片恢复的时候时间就会越长,IO 压力也会越大。同时会影响查询性能
  • 迁移成本高: 增加迁移索引数据迁移时间成本

副本设置

副本( replicas )主要用来提供集群的高可用。

副本的缺点:影响集群写入性能(写入的时候会主副分片都写入数据)与提升一倍的存储成本

副本的优点:提升查询性能(查询的时候可以主、副分片并行执行)

但是如果要保证高可用,一定要保证最少为 1

Mapping设计

es分为动态映射和静态映射。其中动态映射指数据写入 ES 索引时进行动态映射匹配,静态映射则需要手动指定,业务模型已知的情况下,尽可能使用静态设计。对于不确定的字段,可以结合动态 mapping 进行控制

设计流程

  • 评估业务数据字段个数(常态化的)
  • 根据不同的字段评估类型,并判断是否需要检索
  • 评估字段是否需要排序、聚合分析。如果是text类型字段,需要聚合分析的,需要开启 fielddata

完整参考:www.elastic.co/guide/en/el…

注意事项

  • ES不支持删除已有字段
  • ES不支持修改字段类型

实战建议

硬件层面

  • 内存到位:严重依赖文件系统缓存来加快搜索速度。通常,你应该确保至少有一半的可用内存进入文件系统缓存,以便 Elasticsearch 可以将索引的热点区域保留在物理内存中。
  • 磁盘到位:对写入速度有超高要求的,必要时换SSD
  • CPU核数和线程数:基于CPU 核数合理调节线程池和队列的大小

Settings层面

  • 分片大小:单分片控制在 20~40G 内。单分片支持的 doc 数量在2,147,483,519。
  • 分片数量:建议趋近于节点数,提升并发性能
  • 副本数量:reindex 数据建议为 0 个;生产使用建议至少 1 个
  • total_shards_per_node:如果分片数小于等于节点数,建议1个。否则按比例增加即可。
  • refresh_interval: 时效性要求高建议用默认 1s ,否则建议设置在 30~60s 左右。

Mappings层面

  • templates 使用:对于同一类型索引进行提炼,提前做 templates ,方便后期灵活调整。
  • keyword、text:精准查询与聚合计算使用 keyword 、分词检索使用text;
  • 动态templates:对于不确定的字段需要设置类型映射,可以考虑使用。
  • 字段数量:单索引推荐字段数 1000 以内
  • 对象嵌套:默认限制嵌套 20 层,建议不要超过 3 层
  • 属性设置:根据业务情况,针对不同字段类型进行属性设置。比如对于不查询检索的字段,设置 index:false,字段类型能用keyword就不要用其他

Search层面

  • 尽可能减少检索字段数量

  • 控制返回字段和结果

  • 合理设置size大小,深度分页建议scroll

  • 规避使用脚本

  • 有效利用filter:可以用到缓存,和query 相比,不需要计算评分,所以更快。

参考

www.elastic.co/guide/en/el…

www.elastic.co/guide/en/el…