前语
我们好,我是路由器没有路。
今日跟我们聊下自己在工作中总结的关于运用 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。
字段规划
text
和keyword
的用处有必要辨明:分词和关键词(确定字段是否需求分词)- 确定字段是否需求独立存储
- 字段类型不支撑修改,有必要慎重
- 对不需求进行聚合/排序的字段禁用
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
}
}
}
}
}
}
}
}
慎重操作
-
准则:不要疏忽规划,快便是慢,坏的索引规划后患无穷.
-
回绝大聚合 :ES 核算都在 JVM 内存中完结。
-
回绝含糊查询:es 一大杀手
即
wildcard
查找{ "query":{ "wildcard":{ "title.keyword":"*张三*" } } }
-
回绝深度分页 ES 获取数据时,每次默许最多获取 10000 条,获取更多需求分页,但存在深度分页问题,必定不要运用 from/Size 方法,主张运用 scroll 或许 searchAfter 方法。
scroll 会把上一次查询成果缓存必定时间(经过装备 scroll=1m 实现),所以在运用 scroll 时必定要确保 search 成果集不要太大。
-
基数查询 尽量不要用基数查询去查询去重后的数据量巨细(
kibana
中界面上显现是 Unique Count,Distinct Count 等)即少用以下查询:
"aggregations":{ "cardinality":{ "field":"userId" } }
-
禁止查询 indexName-*
-
防止运用
script
、update_by_query
、delete_by_query
,对线上功用影响较大。
需留意的问题
- 一个索引的
shard
数一旦确定不能改动 - ES 不支撑事务
ACID
特性。 - reindex: reindex 能够实现索引的 shard 改变,但价值非常大:速度慢、对功用有影响,所以好的规划和规划更重要
总结
以上是自己在工作中总结的关于 ElasticSearch
的运用标准,如对你有帮助,能够给个赞。
另外,Elasticsearch
的运用需求结合实际事务场景,经过优化和办理来提高其功用和安稳性,我们需求根据特定的事务场景和运用需求来挑选适宜的方案。