两小时 Elasticsearch 性能优化,直接把慢查询干团灭了

 

​问题:慢查询

搜索平台的公共集群,由于业务众多,对业务的es查询语法缺少约束,导致问题频发。业务可能写了一个巨大的查询直接把集群打挂掉,但是我们平台人力投入有限,也不可能一条条去审核业务的es查询语法,只能通过后置的手段去保证整个集群的稳定性,通过slowlog分析等,下图中cpu已经100%了。

两小时 Elasticsearch 性能优化,直接把慢查询干团灭了插图亿华云

昨天刚好手头有一点点时间,就想着能不能针对这些情况,把影响最坏的业务抓出来,进行一些改善,于是昨天花了2小时分析了一下,找到了一些共性的问题,可以通过平台来很好的改善这些情况。

首先通过slowlog抓到一些耗时比较长的查询,例如下面这个索引的查询耗时基本都在300ms以上:

{

"from": 0,

"size": 200,

"timeout": "60s",

"query": {

"bool": {

"must": \[

{

"match": {

"source": {

"query": "5",

"operator": "OR",

"prefix\_length": 0,

"fuzzy\_transpositions": true,

"lenient": false,

"zero\_terms\_query": "NONE",

"auto\_generate\_synonyms\_phrase\_query": "false",

"boost": 1

}

}

},

{

"terms": {

"type": \[

"21"

\],

"boost": 1

}

},

{

"match": {

"creator": {

"query": "0d754a8af3104e978c95eb955f6331be",

"operator": "OR",

"prefix\_length": 0,

"fuzzy\_transpositions": "true",

"lenient": false,

"zero\_terms\_query": "NONE",

"auto\_generate\_synonyms\_phrase\_query": "false",

"boost": 1

}

}

},

{

"terms": {

"status": \[

"0",

"3"

\],

"boost": 1

}

},

{

"match": {

"isDeleted": {

"query": "0",

"operator": "OR",

"prefix\_length": 0,

"fuzzy\_transpositions": "true",

"lenient": false,

"zero\_terms\_query": "NONE",

"auto\_generate\_synonyms\_phrase\_query": "false",

"boost": 1

}

}

}

\],

"adjust\_pure\_negative": true,

"boost": 1

}

},

"\_source": {

"includes": \[

\],

"excludes": \[\]

}

}

这个查询比较简单,翻译一下就是:

SELECT guid FROM xxx WHERE source=5 AND type=21 AND creator=0d754a8af3104e978c95eb955f6331be AND status in (0,3) AND isDeleted=0;

​慢查询分析

这个查询问题还挺多的,不过不是今天的重点。比如这里面不好的一点是还用了模糊查询fuzzy_transpositions,也就是查询ab的时候,ba也会被命中,其中的语法不是今天的重点,可以自行查询,我估计这个是业务用了SDK自动生成的,里面很多都是默认值。

第一反应当然是用filter来代替match查询,一来filter可以缓存,另外避免这种无意义的模糊匹配查询,但是这个优化是有限的,并不是今天讲解的关键点,先忽略。

1、错用的数据类型

我们通过kibana的profile来进行分析,耗时到底在什么地方?es有一点就是开源社区很活跃,文档齐全,配套的工具也非常的方便和齐全。

两小时 Elasticsearch 性能优化,直接把慢查询干团灭了插图1亿华云

可以看到大部分的时间都花在了PointRangQuery里面去了,这个是什么查询呢?为什么这么耗时呢?这里就涉及到一个es的知识点,那就是对于integer这种数字类型的处理。在es2.x的时代,所有的数字都是按keyword处理的,每个数字都会建一个倒排索引,这样查询虽然快了,但是一旦做范围查询的时候。比如 type

THE END
Copyright © 2024 亿华云