ElasticSearch 索引设计指南

6000+字讲透ElasticSearch 索引设计 我们创建索引就像创建表结构一样,必须非常慎重的,索引如果创建不好后面会出现各种各样的问题索引设计的重要性索引创建后,索引的分片只能通过_split和_shrink接口对其进行成倍的增加和缩减主要是因为es的数据是通过_routing分配到各个分片上面的,所以本质上是不推荐去改变索引的分片数量的,因为这样都会对数据进行重新的移动。还有就是索引只能新增字段,不能对字段进行修改和删除,缺乏灵活性,所以每次都只能通过_reindex。 阅读详情

1. 何为ES索引设计

ElasticSearch(以下简称:ES )是一个分布式、RESTful 风格的搜索和数据分析引擎。区别于传统关系型数据库(比如:MySQL、Oracle 等),ES 在定义数据模型和搜索方式上非常灵活,数据模型可以采用静态数据映射与动态数据映射,搜索方式也支持多维度类型的搜索(结构化数据、非结构化数据、地理位置、指标参数等)。如果对事务性要求不高或者事务性操作在 RDMS 端,可以考虑使用 ES 作为海量数据存储与检索分析的平台。用户在创建新索引时,可以直接写数据,所有配置走默认,收缩自如、十分灵活;也可以精细化评估,按照自己的业务需求,提前做好索引的 settings 和 mappings 的设置,未雨绸缪、尽在掌握。

针对 ES 索引设计还是有一些问题困扰着我们:

  • 那么何为 ES 索引设计?

  • 为什么需要提前规划,做不好索引设计又会出现什么问题?

  • 如何做好 ES 索引设计,有什么需要注意的要点?

  • 索引应该如何设置分片数,副本数?

  • 索引大小不可预估,如何做动态拆分?

  • mapping 如何设置,有什么需要注意的?

  • 以下会逐点展开,抽丝剥茧,让大家基于上述问题的解析对 ES 索引设计有一个全新的认知。

1.1 ES 索引设计

ES 索引设计主要是根据在新索引数据写入前,提前手动创建索引的配置与数据结构,以达到极致的稳定性和资源利用的最大化。一个完备的 ES 索引设计,通常会涉及以下几个点:

  • 索引的存储量评估与分片数大小

  • 索引的读写情况

  • 索引的副本数量

  • 索引的字段类型与是否可扩展

  • 性能优化需要调整哪些参数

  • 以上几点包含了索引层面、分片层面、字段层面的考量,后续的几个章节主要也是围绕这几点进行展开分析。

1.2 ES 索引设计可能遇到的问题

如果采用的是索引动态创建,使用的将是默认的配置。对于数据量大,业务复杂的系统,可能会出现如下问题:

分片数无法修改,数据膨胀后,导致无法使用:ES 7.x 后默认分片数为 1 ,而单个分片的存储 doc 数为 2,147,483,519 。超过则无法写入。而分片数设置后,无法修改,只能通过 reindex 进行调整,但是会有很大的性能隐患和时间成本。

影响写入性能:对于日志类的写多读少的业务类型,没必要按照默认的每秒进行 refresh 刷新,可以根据业务情况,调整为 60s 甚至 120s ,这样可以大大提升写入性能。

影响恢复性能:当集群有节点 left 集群的时候,集群需要对 unassigned shards 进行恢复,如果是默认的配置,则会在1min 后进行恢复(将宕机节点的 shards 在集群的副本进行恢复),这样会大大提升集群节点之间的 IO 操作,当本节点加入进来后,还会继续进行大量的节点间 shards 同步,会大大影响恢复进度,继而影响集群性能。如果是调高"index.unassigned.node_left.delayed_timeout"这个参数,集群则会在一段时间内不做分配,在宕机节点重启后,由宕机节点本机磁盘数据进行恢复,在大型集群调优中,能提到数倍的恢复差异。

数据结构无法更改:ES 的字段类型一旦创建无法更改,当动态映射的类型不满足业务需求时,则会出现隐患。

举例,下图是动态创建写入数据:

以上数据对应的动态映射的 settings 如下:

可以看到如果直接动态映射,很多索引级别和 mapping 级别的设置都不可控。

而静态映射,在设置的时候就能把握很多属性细节:

2. 索引Settings设计

索引的 Settings 部分主要针对的是索引和分片层面的设置,重点讨论的是索引的分片大小与分片数的评估(涉及到存储评估设置)、索引恢复设置与性能优化设置。相信了解了这些可以对索引的 Settings 设置更加游刃有余。

要点:索引大小预估、分片大小设计、shards_per_nodes、refresh、flush设置、node_left(delayed_timeout)、replicas

2.1 存储评估设置

在创建索引前,应该做一个短暂的评估,重点在于索引的 业务类型 、 存储周期 、 分片配置 这几块。

2.1.1 业务类型

  • 写多读少

一般日志类的数据是写多读少,压力主要在写入端,且数据量很大。索引通常以日期为单位(常见的有按天、也有按周的),比如log_appcode-yyyy.mm.dd或者log_appcode-yyyy.ww。

对于写入量特别大的索引,建议使用 rollover  进行索引滚动创建管理。这样能保证单个索引存储量可控,单个分片存储也可控。动态索引的使用效果如下:

log_appcode-2021-10-01-000001
log_appcode-2021-10-01-000002
log_appcode-2021-10-01-000003
  • 写少读多

除日志类外,很多业务类的数据是写少读多,也即数据产生并不是周期性的,可以根据业务和压测进行数据量来进行评估。

对于查询量大的索引,应保证查询性能优先,可以设置尽可能多的分片数,以保证请求平摊提升性能。

2.1.1.1  rollover 操作实践

a. 创建需要 rollover 的索引,并设置对应的别名 alias

PUT log_xxx-20211020-000001
{
  "aliases": {
    "log_xxx-alias": {
      "is_write_index": true
   }
 }
}

b. 向别名批量插入若干数据

PUT log_xxx-alias/_bulk
{"index":{"_id":1}}
{"name":"zhangsan"}
{"index":{"_id":2}}
{"name":"lisi"}
{"index":{"_id":3}}
{"name":"wangwu"}
{"index":{"_id":4}}
{"name":"zhaoliu"}
{"index":{"_id":5}}
{"name":"qinqi"}

c. 调用 rollover api ,触发调整逻辑, 设置三个维度,其中 max_docs 生效

POST log_xxx-alias/_rollover
{
  "conditions": {
    "max_age": "7d",
    "max_docs": 5,
    "max_size": "5gb"
 }
}

运行结果:

d.继续插数据,可以看出数据已经写到新的 index 中

PUT log_xxx-alias/_bulk
{"index":{"_id":6}}
{"title":"testing 06"}

运行结果:

以上 rollover 的流程可以用如下图展示:

2.1.2 存储周期

存储周期决定了索引的存储量上限,用户可以在创建前评估存储周期,可参考 业务类型 中的来一并评估。

2.1.3 分片配置

分片:分片( shard )是 ES 中存储数据的文件块,也是 ES 数据存储的最小单位。通常一个索引会分为多个分片存储,不同分片存储的数据不同。分片可以被放置在任何节点上。

分片主要有以下两种作用:

  • 提升索引水平扩展的能力(扩缩容量)

  • 提高索引的读写性能,可以充分利用分布式特性,提高吞吐量

分片也有局限: 一旦创建了分片数,无法更改。 因为数据写入时,每个 doc 都会进行路由,将 routing 的 hash 值与分片数取模来确定 doc 对应的分片。如果更改分片数,则无法确定 doc 对应的分片。算法很简单,如下:

shard = hash(routing)%number_of_primary_shards

分片数设置主要调整如下参数:

  • index.number_of_shards :索引的分片数

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

  • 有超出单分片文档数限制的风险: 分片内部对应的是Lucene的索引文件,一个Lucene索引文件包含多个Segment(段),后者是Lucene索引中最小的独立存储单元。因为Segment内部的doc id使用Java的整型,所以doc 数的限制也为=》  Integer.MAX_VALUE : 2,147,483,519  条。超出此条数,则索引无法写入,会导致数据丢失

  • 恢复速度慢: 单分片越大,在节点重启、分片恢复的时候时间就会越长,IO 压力也会越大。同时会影响查询性能

  • 增加迁移成本: 分片是 ES 对数据的隔离,单分片过大还会增加迁移索引数据迁移时间成本

基于上述,分片数的设置是索引设计的重中之重。根据实战经验与官方论坛,总结出几点设计思路:

  • 评估存储周期

  • 评估每天的存储量。继而根据单天的存储量 * 存储周期 = 总存储量

  • 初算分片数:根据总存储量 / 分片存储量(日志数据建议50GB、业务数据建议30GB)

  • 微调分片数:如果算得的分片数 << 节点数,可以考虑适当增加分片数量,以提升并发性能。理想情况下:在规模中小型的集群中,分片数 == 节点数能发挥出集群最大的性能。

2.1.4 副本设置

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

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

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

一般评估副本的数量,需要评估业务的场景和集群节点规模。建议:普通业务1个副本即可,安全等级高、重要性大的,可适当增加副本数。

副本数设置主要调整如下参数:

  • index.number_of_replicas :索引的副本数

例如,ES 7.x 中的. security 索引是用来保存认证账号信息的,极为重要,集群内部设置的副本就非常多。公司内部的一个日志大集群,管理公司所有实时日志,其中 .security 保存全员账号信息。设置的副本就为 9 。

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

副本设置为 0 ,可能会出现以下问题:

  • 高可用性无法保证:一旦有节点宕机,集群状态直接从Green=》 Red,宕机节点无法使用,影响非常大;

  • 可能造成数据倾斜:0 副本可能造成数据写入指定的机器,从而整体数据倾斜。机器资源利用差异加大;

  • 副本数的设计结合数据的安全需要。对于数据安全性要求非常高的业务场景,建议做好:增加备份(结合 ES 官方备份方案)。

分片和副本设置参考如下:


PUT /index/_settings
{
  "settings": {
    "index.number_of_shards": "10",
    "index.number_of_replicas": "1"
 }
}

2.2 索引恢复设置

索引恢复是一个复杂的过程,通常如果有节点left 集群后,会在一分钟后,集群开始进行恢复。

恢复期间主要会根据分片元数据信息,其余节点对应的宕机节点的分片,置这些分片为主分片,同时进行副本分片数据传输和同步,整体过程会消耗大量的 IO 资源,影响集群稳定性。且当宕机节点重启后,集群还会进行 rebalance shard ,进行进一步的平衡分配分片。整体而言时间很长,苦不堪言。

index.unassigned.node_left.delayed_timeout : 节点脱离集群后多久分配unassigned shards(默认1min)

可以调整上述参数来保证节点恢复期间,不要进行 unassigned 的分配。可以根据索引的存储量、分片数为不同的索引进行设置,如下的设置就能保证节点 left 集群 5 分钟内不进行分配:

PUT /index/_settings
{
  "settings": {
    "index.unassigned.node_left.delayed_timeout": "5m"
 }
}

2.3 性能优化设置

索引 Settings 中有很多参数可以直接影响到集群的读写性能,调整到位则事半功倍,一招调错也可能影响全局。

一般来说,集群默认的配置对性能影响不大,但是遇到数据海量的集群可能会出现一些问题,需要调整相关的参数来提高集群的稳定性和读写性能。

文中选取实践中使用最频繁的,效果最佳的两个参数:

  • index.routing.allocation.total_shards_per_node :将分配给单个节点的最大分片数(副本和主分片)。默认为无界。

  • index.refresh_interval :执行刷新操作的频率,这使得最近对索引的更改对搜索可见。默认为 1s 。

total_shards_per_node 参数主要影响的是集群写入的情况,当一个索引在同一个节点上有多个分片时,海量写入时会极大地飙高此节点的 CPU 占用和 Load 使用量。可以根据节点数、分片数调整此参数。例如:

比如数据节点有 10 个,索引分片数有 8 个,副本数 1 个。则设置为 2 则可。

比如数据节点有 20 个,索引分片数有 5 个,副本数 1 个。则设置为 1 则可。

refresh_interval 参数也是影响写入的性能,默认的 1s 属于近实时的检索,对于实时性要求高的可以适用。但是对于写多读少的日志类数据则不适合,集群要在每秒钟都要生成一个 Segment ,非常耗费资源,影响写入性能。推荐根据业务使用频次来设置此参数:

如果可以接受一定时间的查询延迟,则可以适当调大 refresh_interval 。

我们这边nginx的日志量很大,就单独做了设置,total_shards_per_node 设置为1、refresh_interval 设置为120s 。参考如下:

3. 索引Mapping设计

Mapping 是定义文档以及其包含的字段如何存储和索引的。Mapping 可以用来做如下定义:

  • 哪些字段可以设置为全文检索字段

  • 每个字段的数据类型

  • Date 类型的格式

  • 自定义规则来控制Dynamic Mapping的映射

  • 设置单个字段是否额外存储与存储类型

3.1 索引Mapping存储概要

索引映射(Mapping) 分为动态映射和静态映射。其中动态映射指数据写入 ES 索引时进行动态映射匹配。

如果不确定写入的数据字段或者类型,可以使用动态映射,等业务稳定后,视情况调整索引的 mapping 即可。

动态映射适合新字段和不确定类型的字段映射,官网推荐了两种方式来扩展和完善动态映射规则:

  • Dynamic field Mapping

动态字段映射保证了基本的字段匹配规则,只要是 "dynamic" : "true"(默认),就会开启字段映射,匹配规则如下:

  • Dynamic templates

动态模板可以为字段动态添加各种映射规则,比如可以匹配到包含特定字符的字段进行数据类型映射。

也可以直接根据 match_mapping_type 匹配到的数据字段进行映射。适合于特定类型的映射,可以作为静态 mapping 的有效补充。

3.2 索引Mapping设计流程

设置字段设计的时候,可以参考几点来进行:

  • 评估业务数据字段个数(常态化的)

  • 根据不同的字段评估类型,并判断是否需要检索

  • 评估字段是否需要排序、聚合分析。如果是text类型字段,需要聚合分析的,需要开启 fielddata

  • 字段是否需要额外存储( store )

根据以上几点基本可以最准确的定义字段的映射关系与存储结构,达到资源的利用最大化。

3.3 Mappings设计关键性参数

Mapping 设置中,除了数据类型,还有一些参数属性可以设置,挑选出核心影响的几个,整理如下:

以上的表格是截取了生产实践中使用频率较多的参数,其余更多的参数配置,可以参考官网:

https://www.elastic.co/guide/en/elasticsearch/reference/7.7/mapping-params.html

3.4 Mapping的注意事项

  • ES不支持删除已有字段

  • ES不支持修改字段类型

如果做动态映射,可能会出现使用过程中字段类型冲突的情况,此时只能 reindex 进行重新重置索引,并进行数据同步。如果数据量特别大的情况, reindex 期间会极大地影响集群性能。一定要慎重。

4. 复杂类型的设计

4.1 宽表模式

不同于 MySQL 类的传统关系型数据库,ES 对于多表关联查询不占优势。但是由于其灵活扩展的字段设计,可以采用宽表模式来有效的解决。

比如:一个用户发表多篇旅行游记,存储游记列表,设计对比如下:

按照 MySQL 建表思维:需要创建两个表(用户表、博客内容表),通过 userid 进行关联;

按照 ES 索引思维:可以创建游记索引,在每个游记内容中携带用户信息即可。内容有所增加,但是一次检索就可。

宽表模式:顾名思义,就是字段很多的数据表,通常是指业务相关的各指标、维度、属性关联在一起的一张数据表。宽表包含维度层次比较多,也容易造成冗余,但是有利于进行海量数据提取与分析,广泛应用于 olap 领域。

举例:ES 中游记索引设计如下:

4.2 Nested类型

nested 类型属于 ES 的对象类型,允许存储复杂嵌套的对象模型。nested 的出现提供了对象类型数组中的独立查询,保证了读取精度。nested 可以保证数组中每个对象的独立性。

nested 缺陷也比较明显,因为更新子文档需要更新整个对象,所以更新效率低。

4.3 父子文档类型

在 ES 6.x 版本后父子文档使用 join 来替代。父子文档解决了 nested 的子文档不能独立更新的问题,保证了父与子更新的独立性。比较适合 1 个父对多个子,且子文档更新频繁的场景。

父子文档更新便捷,但是由于内部维护了父子的复杂关联关系,需要占据更多内存,查询性能较之 nested 也较低。

Nested 和父子文档都属于文档嵌套的模型,但是使用方式和使用场景各有不同,详细对比如下:

5. 索引设计实战

本章节笔者通过生产的实时日志集群(简称:日志集群)的真实案例来剖析在生产中是如何使用上述的设计架构要点进行实战的。重点围绕索引的生命周期管理、分片的维护与评估、templates的灵活设计运用,以及实际的一个设计后的生产情况。力求给读者一个更直观的综合感受。

5.1 索引生命周期管理

索引生命周期管理通常指 ES 的各索引的存储周期管理维护,是维护 ES 集群稳定,存储成本,分片管理的重要方案。

日志集群采用了自研的方案,构成了“申请 + 维护 + 清理” 三位一体的生命周期管理方案。下面详细介绍一下:

  • 申请:日志集群以周为存储粒度,每个索引都是类似 log_appcode-yyyy.ww 这种模式,存储周期默认也是7天。如果需要保留更多的周期,则需要用户进行申请延长存储配额。我们这边自研了数据平台自助工单申请平台,其中就有 ES 存储周期的申请功能。见下图:

审批过后,该 appcode 对应的索引生命周期自动变成新的周期。

  • 维护:日志集群将不同的 appcode 的索引生命周期数值存储到了 postgresql 中,从日志申请流程通过,即会写入新 appcode 与默认的存储时长。当每次有存储周期修改审批后,自助工单平台会操作修改 postgresql 进行时长的调整。

  • 清理:根据 postgresql 的 appcode 存储数据,编写好清理脚本,并用 airflow 进行任务定时调度(每周一次),可以起到每周的索引清理工作。

注意:由于每周需要删除的索引众多(大约900~1000),不能一次删除,需要一个一个删除,并且中间进行 3-5s 的休眠。清理过程中,可以观察集群的 pending_tasks 是否飙高,集群 load 是否变高,来保障稳定性。可以选择集群使用率低的时间段来进行索引的清理操作。

5.2 索引settings设计

日志集群中索引 settings 设计主要需要考虑的点有:分片的周期评估与调整、性能优化的整体调整(主要包括total_shards_per_node 、refresh)、索引的提前创建。

5.2.1 分片周期调整

每周会有 airflow 定时任务进行索引分片评估计算。具体的逻辑如下:

a. 拿到本周的各 appcode 对应索引的主分片存储量,按照分片 SIZE (40G)来计算出分片数,可以参考如下 api 来执行

_cat/indices?format=json&pretty&bytes=b&h=index,pri,docs.count,pri.store.size

b. 获取到数据节点实例数,在 a 步骤得到的分片数和实例数取小值。如下:

计算方式:shard_count = MIN(shard_count, node_count)

api:_cat/nodes?format=json&h=name,ip,node.role

c. 计算 buffer ,buffer + shard_count 为最终的分片数。通常比例系数为30%,buffer为比例系数 * shard_count

日志类型数据分片大小建议在 30~50G 之间为佳。

具体 templates 的维护与设计管理,请见下章节。

5.2.2 total_shards_per_node 周期调整

total_shards_per_node 的周期调整可以和分片调整放到一起。以减少维护成本。

total_shards_per_node 默认为无限量。

调整原则为:保证单个索引在单个节点上保留最少的分片数,以避免数据分片倾斜的情况。

total_shards_per_node 的调整逻辑如下:

a. 首先设置 total_shards_per_node 几个范围,日志集群这边根据数据、节点情况设置了三个范围


total_shards_per_node: 1 => shard_count < node_count
total_shards_per_node: 2 => node_count < shard_count < node_count * 1.3(比例系数)
total_shards_per_node: 3 => node_count * 1.3 < shard_count

b. 根据上述的范围来计算不同索引的 total_shards_per_node 。

5.2.3 refresh 周期调整

refresh 的调整相对比较简单:默认所有的索引 refresh_interval 设置为 60s

对于非高优先级的 appcode,total_shards_per_node >1 的,设置 refresh_interval 为 120s 。

5.2.4 索引周期创建

确立好上述索引的配置信息后,可以提前创建下一周期的索引。

索引创建时机很重要,日志集群按周来索引数据,需要周一之前创建好下一周期的索引。

创建索引主要注意的点:

a. 为节省资源,需要在创建前判断索引在当前周是否有索引数据,如果没有,则不创建下一周期(如果已经下线,则就不会创建新的索引)

b.创建索引需要串行执行,且每个索引创建后,需要休眠 3-5s 

c. 索引周期创建同样需要 airflow 定时任务。根据每周的索引数和执行时长,评估创建的时间范围,来进行定时任务的调整。

5.3 templates 设计管理

templates 是索引模板,可以定义好一类 index-pattern的settings 、mappings。而日志类索引正式由于得天独厚的分类优势可以划分为各个不同的 index-pattern ,进而创建 templates 。

日志集群的 templates 架构主要分为两块:default templates、index-pattern templates。

前者是提取日志数据的公共内容写入到统一的 templates ,供所有日志索引数据

5.3.1 default templates

default templates 是默认的模板,用来作为根模板使用,适用于放一些通用的配置,以达到方便配置管理的作用。

日志集群的 default templates 主要做了以下几点:

a. 提供默认的分片、refresh

注:使用 default templates 的分片数和 refresh 刷新频率主要是为了新增的日志提供默认的配置。日志集群做过统计基本上 95% 以上的索引周存储量都在 1TB 以内,所以默认创建 20 分片的索引能满足绝大多数需求。

number_of_shards: 20
refresh_interval: 60s

b. 日志统一字段配置

根据各个业务线写入的数据字段类型,和 kafka 存储的日志源数据信息,提取了一些共用字段,举例如下:

@timestamp: date
send_time : long (时间戳)
app_code : keyword
source_ip : keyword
content   : text
log_name : keyword

更进一步,我们可以根据字段类型进行自身的数据内容,使用情况来进行字段属性方面的调整,比如:

app_code : 字段存储的是每个 appcode ,在单个 appcode 下没有检索意义。故而设置 index: false

content : 字段存储的是日志的主要内容,内容通常比较冗长。设置 norams: false, 不对 content 计算得分

根据上述,还对 source_ip、send_time 等字段都做了 index:false 的设置

一个较为完整的 default template 如下:

{
  "order": 1,
  "index_patterns": [
    "log_*"
 ],
  "settings": {
    "index": {
      "routing": {
        "allocation": {
          "total_shards_per_node": "1"
       }
     },
      "refresh_interval": "60s",
      "number_of_shards": "20",
      "translog": {
        "durability": "async"
     },
      "number_of_replicas": "1"
   }
 },
  "mappings": {
    "properties": {
      "@timestamp": {
        "type": "date"
     },
      "send_time": {
        "index": false,
        "type": "long"
     },
      "source_host": {
        "ignore_above": 256,
        "type": "keyword"
     },
      "log_name": {
        "ignore_above": 256,
        "type": "keyword"
     },
      "content": {
        "norms": false,
        "type": "text"
     },
      "app_code": {
        "ignore_above": 256,
        "index": false,
        "type": "keyword"
     },
      "source_ip": {
        "ignore_above": 256,
        "index": false,
        "type": "keyword"
     }
   }
 },
  "aliases": {}
}

5.3.2 建立各自的 template

一般有如下情况下需要用到独立的 template :

a. 有独立于 default templates 的字段需要提前设置,比如增加字段

b. 针对 default templates 的现有字段有属性调整设置,比如调整 date 类型的 format

c. 创建独立的 shard_count、total_shards_per_node ,如上文 5.2 所示

比如其中一个日志索引存储的是 city 相关的日志数据,所以会增加 cityName 字段;@timestamp(date类型) 写入的格式为 yyyy-MM-dd HH:mm:ss.SSS ,则修改了 date 的 format ;而分片相关的设置会在定时任务中进行自动更新。一个独立的 template 参考如下:

{
  "order": 99,
  "index_patterns": [
    "log_order_info-*"
 ],
  "settings": {
    "index": {
      "number_of_shards": "256",
      "routing": {
        "allocation": {
          "total_shards_per_node": "2"
       }
     },
      "refresh_interval": "120s"
   }
 },
  "mappings": {
    "properties": {
      "cityName": {
        "type": "keyword"
     },
      "@timestamp": {
        "format": "strict_date_optional_time||epoch_millis||yyyy-MM-dd HH:mm:ss.SSS",
        "type": "date"
     }
   }
 },
  "aliases": {}
}

templates 的重要字段说明:

  • order:创建索引template的执行的顺序,如果一个索引有多个 templates 匹配,则会根据 order 的顺序,升序执行。order 值越高的越后面执行,多个 templates 进行合集。相同配置以 order 高值为准,如果字段类型彼此冲突,会报错。

  • index_patterns:是 templates 匹配的 index 模板,一般会带上*,可以匹配多个相同类型的索引。

5.4 实战总结

总结上述的实战,主要涉及到了三块:索引生命周期管理、索引 settings 设计管理、索引的 templates 管理,这几块既有配置类的设计管理,也有性能方面的考虑,还加入了生产中使用的 templates 进行设计管理,提升可维护性。并统一通过 airflow 定时任务进行自动化维护,保证了索引周期性设计的稳定性。具体流程参考下图:

6. 最佳实战建议

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 ,具体参见 3.3 章节。

7. 总结

文末,总结一下 ES 索引设计的核心考量因素:

  • 业务模型已知的情况下,尽可能使用静态设计。对于不确定的字段,可以结合动态 mapping 进行控制

  • 索引分片和副本一定要提前设计好,如果索引存储周期不定,数据量很大的情况,可以结合 rollover 控制单分片大小

  • Mapping 创建好后,无法更改,所以对于不确定的参数建议进行完备的测试,方可放入生产环节

  • 根据业务提前设计要比后续遇到问题填坑省很多事情

相信读者认真看完此篇文章,结合业务场景,仔细思考,定能设计出性能更好、稳定性更强的索引。

8. 参考文献

  1. https://www.elastic.co/guide/cn/elasticsearch/guide/current/index-management.html

  2. https://www.elastic.co/guide/cn/elasticsearch/guide/current/mapping-intro.html

  3. https://www.elastic.co/guide/en/elasticsearch/reference/7.7/mapping.html

  4. https://www.elastic.co/guide/en/elasticsearch/reference/7.7/indices-rollover-index.html

  5. https://blog.youkuaiyun.com/laoyang360/article/details/83717399

elasticsearch 7.9.3知识归纳整理(二)之 es基本原理及使用kibana操作es的常见命令 es基本原理及使用kibana操作es的常见命令 阅读详情

相关推荐

搜索引擎anti-spam系统设计指南

一. 设计原则与整体体系结构 1.1 设计原则 搜索引擎ANTI-SPAM作为一个新型的技术领域,目前逐渐引起学术届和搜索引擎市场的逐步重视.通过大量资料分析,我认为一个好的实用ANTI-SPAM系统应该遵循以下两个设计原则: 原则1.实用的搜索引擎ANTI-SPAM系统应该允许核心算法公布,并且在核心算法公布之后不会导致现有ANTI-SPAM系统的失效. 原则2.实用的搜索引擎AN...

ChinaUnix博客搬家测试账号 681

ES 索引

ES 索引 Elasticsearch(以下称之为 ES)是一款基于 Lucene 的分布式全文搜索引擎,擅长海量数据存储、数据分析以及全文检索查询。 Lucene 是 Apache 下的一个子项目,是一个开放源代码的全文检索引擎工具包,但它不是一个完整的全文检索引擎,而是一个全文检索引擎的架构,提供了完整的查询引擎和索引引擎,它是 ES 实现全文检索的核心基础,索引文档以及搜索索引的的核心流程都是在 Lucene 中完成的。 基础结构 MySQL ES database数据库 inde

萝卜_7 1万+

【项目实战】ES的索引模式入门介绍

使用SpringBoot将数据Sink到ES中,或者使用Flink将数据Sink到ES中需要使用Kibana去看看数据是否正常sink写入,因此需要新建索引模式去查看数据。

奶爸的编程之路,也就一周冷个三天 2657

使用es必须要知道的一些知识点:索引篇

如果你的批量太大,它们会占用过多的内存。分区规则不一致:不同的索引模板可能具有不同的分区规则,例如按时间分区、按地理位置分区等。当批量处理器处理多个索引模板的请求时,如果分区规则不一致,会导致数据在不同的分区之间不均匀分布,影响查询性能和数据的存储效率。当Elasticsearch被用作大数据量存储中心时,尤其是从Mysql迁移数据进来的情况下,我们很多场景下其实无需对字符串分词,也就是说字符串存储不使用es中的。管理复杂性:处理多个索引模板的请求会增加管理的复杂性,包括索引模板的创建、更新和删除等操作。

子涵先生 6557

51、Joomla模板设计与搜索引擎优化指南

本文详细介绍了Joomla模板设计和搜索引擎优化的相关知识与操作方法。模板设计部分涵盖使用模板生成软件、模板框架、模板基础知识等内容;SEO部分则包括文章优化、元数据添加、SEF URL启用、内部超链接创建、URL重定向设置等实用技巧。通过这些内容,帮助用户提升Joomla网站的外观设计和搜索引擎排名,从而吸引更多访客。

q1w3e5r7t9y的博客 86

Latex里面关于作者名字显示有灰色; 二级+三级标题斜体;

Latex里面关于 作者名字显示有灰色; 二级+三级标题斜体,与正文的距离; 邮箱字体;ORCID字体设置(整理不易,请先关注,Thanks)

m0_61015717的博客 747

干货 | Elasticsearch 索引设计实战指南

题记随着 Elastic 的上市,ELK Stack 不仅在 BAT 的大公司得到长足的发展,而且在各个中小公司都得到非常广泛的应用,甚至连“婚庆网站”都开始使用 Elasticsear...

铭毅天下Elasticsearch 1万+

QTableView为例:Qt模型视图委托(MVD)(Model-View-Delegate)

QT中的MVD(模型-视图-委托)模式是一种类似于MVC的设计模式,将数据、界面和交互逻辑分离。模型负责数据管理,视图负责显示界面,而委托则嵌入在视图中处理数据的显示和编辑。QT提供了多种视图组件(如QListView、QTreeView、QTableView)和模型类(如QStandardItemModel、QAbstractItemModel),支持数据的多样化呈现。委托(Delegate)通过定制显示和编辑行为增强了视图的灵活性。该模式适用于各类数据结构展示(列表、表格、树形),能够高效处理数据与界面

菜一头包的博客 1990

Elasticsearch 索引设计实战指南

题记 随着 Elastic 的上市,ELK Stack 不仅在 BAT 的大公司得到长足的发展,而且在各个中小公司都得到非常广泛的应用,甚至连“婚庆网站”都开始使用 Elasticsearch 了。随之而来的是 Elasticsearch 相关部署、框架、性能优化的文章早已铺天盖地。 初学者甚至会进入幻觉——“一键部署、导入数据、检索&聚合、动态扩展, So Easy,妈妈再也不用担心...

spring_root的博客 924

C#计算八字

private string[] jq = { "小寒", "大寒", "立春", "雨水", "惊蛰", "春分", "清明", "谷雨", "立夏", "小满", "芒种", "夏至", "小暑", "大暑", "立秋", "处暑", "白露", "秋分", "寒露", "霜降", "立冬", "小雪", "大雪", "冬至" };private string[] dz = { "丑", "寅", "卯", "辰", "巳", "午", "未", "申", "酉", "戌", "亥", "子" };

m0_72939038的博客 828

利用腾讯云轻量服务器快速搭建网站CDN

腾讯云的轻量最近在主机和站长中间可谓是占尽来风头,优秀的线路,低廉的价格使得越来越多的人开始使用腾讯云的轻量级服务器来部署应用。由于腾讯云轻量服务器的海外服务器电信走的是CN2GIA线路带宽30m挺适合做CDN的,我就记录一下如何利用腾讯云香港的轻量服务器搭建一个CDN。 购买服务器 首先选购服务器,最近腾讯云在做活动,力度很大国内备案用户可以选用国内的服务器最低128元/年,未备案的可以选用香港或者新加坡的服务器。 购买链接 服务器系统选Debian、Ubuntu、centos都可以 一键脚

demo_top的博客 2566

elasticsearch 索引_干货 | Elasticsearch 索引设计实战指南

题记随着 Elastic 的上市,ELK Stack 不仅在 BAT 的大公司得到长足的发展,而且在各个中小公司都得到非常广泛的应用,甚至连“婚庆网站”都开始使用 Elasticsearch 了。随之而来的是 Elasticsearch 相关部署、框架、性能优化的文章早已铺天盖地。初学者甚至会进入幻觉——“一键部署、导入数据、检索&聚合、动态扩展, So Easy,妈妈再也不用担心我的 E...

weixin_39790102的博客 205

基于CST的PCB通孔三维建模实例

本文简明扼要地描述了如何利用CST的参数化脚本快速生成PCB的通孔三维模型,非常适合于进行快速精准的PCB参数分析。

一只豌豆象的博客 1838

Python分布式爬虫打造搜索引擎完整版-基于Scrapy、Redis、elasticsearch和django打造一个完整的搜索引擎网站

Python分布式爬虫打造搜索引擎 基于Scrapy、Redis、elasticsearch和django打造一个完整的搜索引擎网站https://github.com/mtianyan/ArticleSpider 未来是什么时代?是数据时代!数据分析服务、互联网金融,数据建模、自然语言处理、医疗病例分析……越来越多的工作会基于数据来做,而爬虫正是快速获取数据最重要的方式,相比其它语言,Pyth...

无 1万+

YOLO26涨点改进 | 全网独家,注意力创新改进篇 | Arxiv2025 | YOLO26引入MSLA多尺度线性注意力模块,高效提取多尺度特征和建模长程依赖,含多种创新改进,助力有效涨点

本文提出了一种多尺度线性注意力模块(MSLA)来优化YOLO26模型。MSLA通过并行使用不同尺寸的深度可分离卷积(3×3至9×9)提取多尺度特征,并结合线性注意力机制高效建模全局依赖关系。该模块显著提升了模型对多尺度目标的检测能力,同时保持了轻量化特性。实验表明,MSLA能有效增强小目标检测和复杂场景下的分割精度。文章详细介绍了MSLA的网络结构、核心优势及实现代码,并提供了两种集成MSLA的YOLO26改进方案,为实时目标检测任务提供了高效解决方案。

Ai缝合怪、助力小伙伴高效发论文 306

SNAP计算哨兵2号的LAI/FVC/FAPAR

SNAP的计算LAI方法是基于PROSAIL模型,集成的模块,很方便。首先要下载SNAP软件,下载步骤见。

所有专家都曾始于新手 2509

Elasticsearch 架构与索引设计完全指南:轻松掌握建模到实战的宝贵经验

高性能: 毫秒级查询响应,支持高并发访问高可用: 99.9% 以上服务可用性可扩展: 支持水平扩展,应对数据增长易维护: 清晰的索引结构,便于运维管理根据查询模式设计索引使用合适的字段类型合理规划分片数量设计 ILM 策略预留 20-30% 磁盘空间过度设计字段分片数过多或过少忽略数据增长预估所有字段都可搜索忽略索引生命周期。

jike007gt的博客 984

【Windows Server 2019】邮件服务器配置与管理——安装及配置Winmail服务器(上)

博文介绍了如何安装邮件服务器 Winmail,如何配置Winmail,包括运行服务器,Winmail管理工具介绍和域名配置。

VMware, Windows, Linux, Cisco, Container, Kubernetes, Kali 2万+

Elasticsearch简介

简介篇 全文搜索引擎是什么 全文搜索引擎是目前广泛应用的主流搜索引擎。它的工作原理是计算机索引程序通过扫描文章中的每一个词,对每一个词建立一个索引,指明该词在文章中出现的次数和位置,当用户查询时,检索程序就根据事先建立的索引进行查找,并将查找的结果反馈给用户的检索方式。这个过程类似于通过字典中的检索字表查字的过程。 从定义中我们已经可以大致了解全文检索的思路了,为了更详细的说明,我们先从生活中的数据说起。 我们生活中的数据总体分为两种:结构化数据 和 非结构化数据。 结构化数据: 指具有固定格式

猎户星座 2507

NTscan扫描工具

ntscan是一个扫描器,可以扫描没有密码和弱密码的共享,先到配置文件中填写猜测的用户名和密码,扫描过程中右侧出现的是扫描日志。

win10 跳过U8环境检测的IE WebControls.rar

win10 安装u8的时候 提示IE WebControls 不通过,这个工具可以欺骗u8的检查。 跳过U8环境检测的IE WebControls。提示导入失败后,重新检测通过。

搜索引擎优化(SEO)设计指南

做了一个投票调查,将近10%的人不认为seo(搜索引擎优化)是设计师应该承担的责任。令我更惊讶的是甚至有24%不知道什么是seo。如果你 不了解seo是什么或者不明白seo能帮你做什么,你有必要认真的阅读一下此文章,seo搜索引擎优化对于设计师来说是有指导意义的,它可以让你的网站或 博客很容易的被搜索引擎抓取、收录。我将介绍、解释一下设计师和程序员常犯的错误。同时我提供一些基本的技巧方法,从而更好

php菜鸟技术天地 1228

大中型超市收银系统(可直接运行)

光步前台收银系统系统功能:商品销售、商品退货、挂单、收银员权限、会员销售、单品取消、整单取消、商品查询、脱机销售、脱机数据上传,基本资料下载,开钱箱、小票打印、收款结算,支持多币种付款方式(现金、储值卡、礼券、微信等),支持多种促销。运行环境:.net 4.0登陆信息用户名:1001 密码:123456内置商品信息,商品编码可输入00001000 - 00010000,测试效果相关功能键F5 结算 F9挂单 F11商品查询 F8退货 Insert单品取消 Del整单取消 F12开钱箱F2 会员 Ctrl+Z退出系统 Home 锁屏 相关源码待公开

上一篇: 你有没有在MySQL的order by上栽过跟头
下一篇: 搞透Kafka的存储架构,看这篇就够了
JavaShark
博客等级 码龄4年 184粉丝 438原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值