elasticsearch如何设计索引

本文为博客园做者所写: 一寸HUI,我的博客地址:https://www.cnblogs.com/zsql/html

最近在作es相关的工做,因此记录下本身的一些想法,可能不少方面不会很全面,可是基本都是通过验证的。本文主要是围绕着思考,从多个方面进行考虑,怎么设计索引比较好,直接进入主题吧,本文的es版本为elasticsearch7.8.1。sql

1、索引设计的重要性

  首先索引建立后,索引的分片只能经过_split和_shrink接口对其进行成倍的增长和缩减,主要是由于es的数据是经过_routing分配到各个分片上面的,因此本质上是不推荐去改变索引的分片数量的,由于这样都会对数据进行从新的移动。还有就是索引只能新增字段,不能对字段进行修改和删除,缺少灵活性,因此每次都只能经过_reindex重建索引了。还有就是一个分片的大小以及因此分片数量的多少严重影响到了索引的查询和写入性能。因此可想而知,设计一个好的索引可以减小后期的运维管理和提升很多性能。因此前期对索引的设计是至关的重要的。app

  • 好的索引设计在整个集群规划中占据举足轻重的做用,索引的设计直接影响集群设计的好坏和复杂度。
  • 好的索引设计应该是充分结合业务场景的时间维度和空间维度,结合业务场景充分考量增、删、改、查等全维度设计的。
  • 好的索引设计是彻底基于“设计先行,编码在后”的原则,前期会花很长时间,为的是后期工做更加顺畅,避免没必要要的返工

2、如何设计索引

  在设计索引以前咱们要明白索引有些什么内容,明白索引的构成,好比索引的基本配置setting,映射mapping,还有重要的分片,副本,模板,索引的生命周期等。知道这些以后就能够有针对性的设计了。首先要结合公司的业务场景,数据量的大小,天天增量如何,数据的特色,会不会对历史数据进行从新更新。数据存多久,是永久仍是有必定的周期。数据须要准实时呢仍是不须要准实时呢。因此清楚索引的构成和知道业务场景,才可以结合起来作更好的设计。运维

2.一、考虑索引的公共基本配置

因为elasticsearch7.x不容许把索引级别的设置配置在elasticsearch.yml中,因此须要对每一个索引进行单独的配置,这样的话就比较麻烦,因此能够把这些公共的配置配置在索引模板中,这样就能够在新建索引的时候能够自动的设置到索引中,关于索引模板的操做能够看考:聊聊elasticsearch7.8的模板和动态映射elasticsearch

接下来看看一些经常使用索引级别的配置ide

"number_of_replicas": 1, #推荐副本数为1 "max_result_window": 100000, "refresh_interval": "30s", #这里对实时性要求不高,能够增长该值提升写入性能 "index.search.slowlog.threshold.query.warn": 10s, "index.search.slowlog.threshold.query.info": 5s, "index.search.slowlog.threshold.query.debug": 2s, "index.search.slowlog.threshold.query.trace": 500ms, "index.search.slowlog.threshold.fetch.warn": 1s, "index.search.slowlog.threshold.fetch.info": 800ms, "index.search.slowlog.threshold.fetch.debug": 500ms, "index.search.slowlog.threshold.fetch.trace": 200ms, "index.indexing.slowlog.threshold.index.warn": 10s, "index.indexing.slowlog.threshold.index.info": 5s, "index.indexing.slowlog.threshold.index.debug": 2s, "index.indexing.slowlog.threshold.index.trace": 500ms "dynamic": false #是否关闭动态字段映射,默认为true,这里选择我的选择禁用

固然索引的配置还有不少其余的,能够根据实际状况进行调整,这样就能够把须要配置公共索引配置设计成索引模板:post

PUT _index_template/template_index { "index_patterns": [ "index-*" ], "template": { "settings": { "number_of_replicas": 1, "max_result_window": 100000, "refresh_interval": "30s", "index.search.slowlog.threshold.query.warn": "10s", "index.search.slowlog.threshold.query.info": "5s", "index.search.slowlog.threshold.query.debug": "2s", "index.search.slowlog.threshold.query.trace": "500ms", "index.search.slowlog.threshold.fetch.warn": "1s", "index.search.slowlog.threshold.fetch.info": "800ms", "index.search.slowlog.threshold.fetch.debug": "500ms", "index.search.slowlog.threshold.fetch.trace": "200ms", "index.indexing.slowlog.threshold.index.warn": "10s", "index.indexing.slowlog.threshold.index.info": "5s", "index.indexing.slowlog.threshold.index.debug": "2s", "index.indexing.slowlog.threshold.index.trace": "500ms" }, "mappings": { "dynamic": false } }, "priority": 10 }

这样新建index-开头的索引的时候都会默认配置好如上的配置,这样就是考虑到基本设置公共化性能

2.二、索引命名规范

  这部分主要说下索引命名规范,包括别名,经过别名可使得索引的操做变得更加灵活,一个索引能够有多个别名,固然一个别名能够配置多个索引,这样的话就极大的增长了索引的的灵活性。在索引的命名上规定特殊字段开头,一样对其好进行权限控制,关于权限控制能够参考:elasticsearch7.8权限控制和规划测试

必须严格按照以下命名格式:(不然将没法使用,由于这里设置了相关权限);fetch

  • 索引命名规范:index-{行业}-{业务}-{版本}
  • 别名命名规范:index-{行业}-{业务}

 若是是索引拆分后(有多个索引),须要一个全局的读的别名对全部拆分后的全部进行命名,和一个最新索引写的别名(只对可更新的索引),若是这里没有描述清楚,请见2.5大索引的设计,两个别名可规范以下:

  • 读别名:index-{行业}-{业务}-read
  • 写别名:index-{行业}-{业务}-insert

2.三、mapping的设计

mapping设置主要就是怎么选择数据类型,分词等

中文分词:推荐使用:"analyzer": "ik_max_word" ,这样能够更细粒度的进行中文分词

设置字段的时候,务必过一下以下图示的流程。根据实际业务须要,主要关注点:

  • 数据类型选型;
  • 是否须要检索;
  • 是否须要排序+聚合分析;
  • 是否须要另行存储

 核心参数的含义,梳理以下

  

 2.四、分片的设计

这个很重要,直接影响到后期的管理和性能。

Elasticsearch中的数据组织成索引。每个索引由一个或多个分片组成。每一个分片是Luncene索引的一个实例,你能够把实例理解成自管理的搜索引擎,用于在Elasticsearch集群中对一部分数据进行索引和处理查询。

分片设计原则

  • 推荐每一个分片的大小:20-40G,建议不超过30G,可是也会有特殊的状况,有些索引字段少,可是数据量大,这样的话也能够增长一些分片数
  • 确保每一个节点的分片数量保持在低于每1GB堆内存对应集群的分片在20-25之间。 所以,具备30GB堆内存的节点最多能够有600-750个分片
  • 每一个索引的分片:通常为节点数的1-3倍,假设咱们有15个数据节点,则15*3*40G=1.8T,这样一个索引最多设置真的大,若是超过了,就须要参考大索引的设计
  • 分片数量尽可能为数据节点的倍数,这样就可使得数据进来均衡,可是数据量极少的索引,根据状况进行分片数量的设计

下面写一个简单的参考表(均可以根据实际状况进行调整,只是我的的建议):

索引的大小 分片数量设置
0-20G 2
20-100G 8
100-400G 15
400-900G 30
900G-1.6T 45

如上设置是基于15个数据节点进行配置的,基本都给增量预留了一些空间,最好是根据实际状况进行设定,若是一个索引已经很大了,上面的配置不能知足了的话须要对对索引进行拆分了,使用索引模板+Rollover+索引生命周期进行自动滚动,拆分索引。见2.5节

2.五、大索引的设计

  当一个索引太大时就会有不少的风险,首先会影响性能,当分片数必定的状况下,数据愈来愈多,一个分片就会愈来愈大,就会违背了上面的设计原则,其次就是一个索引出问题,很难恢复,而且影响范围广,那如何对很大的索引进行设计呢。可使用索引模板+Rollover+生命周期进行自动滚动建立索引,全部的索引都用一个别名进行读,而且设置一个索引为写,这样就可以很好的拆分索引。先看看这么设计的原理图。

 上面有三个索引,经过index_all索引进行检索,是用index_latest保证只写入到一个最新的索引中,每次索引知足三个条件(文档数,时间,索引大小)中的一个,就会自动的滚动生成新的索引。接下来作个实操,这样更方面理解。

先来个官网,有兴趣的能够参考:https://www.elastic.co/guide/en/elasticsearch/reference/7.8/getting-started-index-lifecycle-management.html

主要分为四个步骤:

  1. 建立索引生命周期的规则
  2. 建立索引模板并应用该生命周期
  3. 初始化一个索引
  4. 验证

首先建立生命周期的规则,对于索引的生命周期能够参考:对Elasticsearch生命周期的思考,若是数据是按期存储的,好比一些日志,只保留最近30天,这样的数据结合索引的生命周期能够自动的进行清理。咱们首先建立一个策略policy_index,这里是测试,因此把时间调至5分钟,这些配置都应该根据实际状况进行设置。

PUT _ilm/policy/policy_index { "policy": { "phases": { "hot": { "actions": { "rollover": { "max_size": "50GB", "max_age": "5m" } } } } } }

  接下来设计索引模板,而且该策略应用进去。

PUT _index_template/policy_index_template { "index_patterns": [ "index-test-*" ], "template": { "settings": { "number_of_shards": 1, "number_of_replicas": 1, "index.lifecycle.name": "policy_index", #配置策略 "index.lifecycle.rollover_alias": "index-test-insert" }, "aliases": { "index-test-read": { "is_write_index": false #这个别名是用来读的,不容许写,不然会和写的那个别名冲突 } } } }

这里的模板只是为了演示该小节的内容,实际状况应该把基本配置以及mapping相关的设置好

    接下来就是建立一个索引了

PUT index-test-000001

 

 建立好以后,而后给索引添加别名index-test-insert,索引就自动有了两个别名,read负责读,insert负责写

 

 接下来,只要经过验证便可:GET index-*/_ilm/explain

 最后达到条件后就会自动生成新的索引,而后把index-test-insert别名切换到新的索引上面,就是这样子的

 

 大索引的设计就是拆分,不少都是根据时间进行切分索引的,若是记得没错的话,上面的000001这些能够配置为日期的。

参考博文:

https://mp.weixin.qq.com/s/KQQJfKCOuqadTujbLNu5aA

https://mp.weixin.qq.com/s?__biz=MzI2NDY1MTA3OQ%3D%3D&chksm=eaa8291cdddfa00ae765d5fc5298e252a0f848197348123266afb84751d9fe8907aff65d7aea&idx=1&mid=2247483700&scene=21&sn=1549fc794f77da2d2194c991e1ce029b

相关文章
相关标签/搜索