前语

我们好,我是路由器没有路

今日跟我们聊下自己在工作中总结的关于运用 ElasticSearch 的一些标准,如有不当的当地,欢迎纠正。

Elasticsearch 是一个根据 Lucene 的查找引擎,支撑分布式查找、多租户、实时查找和剖析等才能,具有高效、安稳、可扩展的优势,被广泛应用于企业级查找和数据剖析场景。

关于 ElasticSearch 的介绍,这里不再赘述了,有爱好的同学能够看下我前面写的一篇文章:Elasticsearch 的简单介绍和如何运用。

基础装备规划

分片(shard)容量

  • 非日志型(查找型、线上事务型)的 shard 容量在 20~40GB(主张在 20G)
  • 日志型的 shard 容量在 35~100GB(主张 35G)
  • 单个 shard 的文档个数不能超越 20 亿左右(Integer.MAX_VALUE – 128)

注:一个 shard 便是一个 lucene 分片,ES 底层根据 lucene 实现。

索引(index)数量

大索引需求拆分:提高功用,下降危险,将危险分散化。

反例:例如一个 10 多 T 的索引,按 date 查询、name 查询

正例:indexname 拆成多个 index_name${date}

正例:indexname 按 hash 拆分 index_name{1,2,3,…100..}

节点、分片、索引

一个节点办理的 shard 数不要超越 200 个

索引 mapping 的规划准则

大准则:不运用默许装备和动态 mapping、数据用处(类型、分词、存储、排序)弄清,下面是一个标准 mapping

{
"aliases":{
"my_index_name":{}
},
"settings":{
"index":{
"refresh_interval":"1s",
"number_of_shards":"12",
"number_of_replicas":"1",
"search.slowlog.threshold.query.warn":"5s",
"search.slowlog.threshold.query.info":"1s",
"search.slowlog.threshold.fetch.warn":"1s",
"search.slowlog.threshold.fetch.info":"800ms",
"indexing.slowlog.threshold.index.warn":"12s",
"indexing.slowlog.threshold.index.info":"2s"
}
},
"mappings":{
"_default_":{
"_all":{
"enables":false
}
},
"my_type_name":{
"properties":{
"xxx_id":{
"type":"keyword"
},
"timestamp":{
"type":"long"
},
"xxx_status":{
"type":"integer"
},
"xxx_content":{
"type":"ztext"
}
}
}
}
}

refresh 频率(refresh_interval)

ES 的定位是准实时查找引擎,该值默许是 1s,表明写入后 1 秒后可被查找到,所以这里的值取决于事务对实时性的要求。

留意这里并不是越小越好,改写频率高也意味着对 ES 的开支也大,通常事务类型在 1-5s,日志型在 30s-120s,假如会集导入数据可将其设置为-1,ES 会自动完结数据改写(留意完结后更改回来,否则后续会出现查找不到数据)。

别号(aliases)

记住:在某些场景下可运用别号,但不要过度依靠别号功用。

正例

索引名:index_name_v1

别号:index_name

未来重建 index_name_v2 索引,关于事务来说只需求换别号。

type 个数

1 个就够了,从 ES6 开端只支撑一个 type,这个 type 比较鸡肋,后边的版本可能会去掉。

假如必定用:针对现已运用多个 type 的场景,必定要确保不同 type 下字段尽量保持一致,否则会加大数据稀少性,存储与查询功用受影响

慢日志(slowlog)

必定要装备,默许不记载慢查询,kcc 供给了 grafana、kibana 查询功用。

副本(number_of_replicas)

1 个就够用,副本多写入压力不行忽视。极端情况下:比如批量导入数据,能够将其调整为 0。

字段规划

  • textkeyword 的用处有必要辨明:分词和关键词(确定字段是否需求分词)
  • 确定字段是否需求独立存储
  • 字段类型不支撑修改,有必要慎重
  • 对不需求进行聚合/排序的字段禁用 doc_values
  • 不要在 text 做含糊查找

text 类型:适用于分词用于查找,适用于 email 、内容、描述等需求分词的全文检索,不适用聚合。

keyword 类型:无需分词,整段完好精确匹配,适用于:email 、地址、状态码、分类 tags。

设置合理的 routing key(默许是 id)

id 不均衡:集群容量和拜访不均衡,关于分布式存储是丧命的。

关闭 _all

ES6.0 现已去掉,对容量(索引过大)和功用(功用下降)都有影响。

防止大宽表:

ES 默许最大 1000,但主张不要超越 100

text 类型的字段不要运用聚合查询

text 类型 fileddata 会加大对内存的占用,假如有需求运用,主张运用 keyword

聚合查询防止运用过多嵌套,

聚合查询的中心成果和最终成果都会在内存中进行,嵌套过多,会导致内存耗尽。

以下是聚合就嵌套了 3 层,成果都会保存在内存中,

假如仅有值较多,就会导致内存耗尽:

{
"aggs":{
"country":{
"terms":{
"filed":"country",
"size":10
},
"aggs":{
"city":{
"terms":{
"filed":"city",
"size":20
},
"aggs":{
"salary":{
"terms":{
"filed":"salary",
"size":20
}
}
}
}
}
}
}
}

慎重操作

  1. 准则:不要疏忽规划,快便是慢,坏的索引规划后患无穷.

  2. 回绝大聚合 :ES 核算都在 JVM 内存中完结。

  3. 回绝含糊查询:es 一大杀手

    wildcard 查找

    {
    "query":{
    "wildcard":{
    "title.keyword":"*张三*"
    }
    }
    }
    
  4. 回绝深度分页 ES 获取数据时,每次默许最多获取 10000 条,获取更多需求分页,但存在深度分页问题,必定不要运用 from/Size 方法,主张运用 scroll 或许 searchAfter 方法。

    scroll 会把上一次查询成果缓存必定时间(经过装备 scroll=1m 实现),所以在运用 scroll 时必定要确保 search 成果集不要太大。

  5. 基数查询 尽量不要用基数查询去查询去重后的数据量巨细(kibana 中界面上显现是 Unique Count,Distinct Count 等)

    即少用以下查询:

    "aggregations":{
    "cardinality":{
    "field":"userId"
    }
    }
    
  6. 禁止查询 indexName-*

  7. 防止运用 scriptupdate_by_querydelete_by_query,对线上功用影响较大。

需留意的问题

  1. 一个索引的 shard 数一旦确定不能改动
  2. ES 不支撑事务 ACID 特性。
  3. reindex: reindex 能够实现索引的 shard 改变,但价值非常大:速度慢、对功用有影响,所以好的规划和规划更重要

总结

以上是自己在工作中总结的关于 ElasticSearch 的运用标准,如对你有帮助,能够给个赞。

另外,Elasticsearch 的运用需求结合实际事务场景,经过优化和办理来提高其功用和安稳性,我们需求根据特定的事务场景和运用需求来挑选适宜的方案。

声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。