1. 程式人生 > >用PROFILE API 定位 ES 慢查詢

用PROFILE API 定位 ES 慢查詢

轉載處:https://www.easyice.cn/archives/267

有時在發起一個查詢時,他會被延遲,或者響應時間很慢,查詢緩慢可能會有多種原因;範圍包括 shard 問題,或者計算查詢中的某些元素。 從 elasticsearch 2.2版本開始提供 Profile API 供使用者檢查查詢執行時間和其他詳細資訊。在這篇部落格中,我們將探討如何使用profile API檢視查詢計時。

Profile API


Profile API 是Elasticsearch 2.2版本的一個實驗性特性, Profile API 返回所有分片的詳細資訊。為了簡單起見,我們建立一個只有1個分片的索引。

Index creation:

 

 

1

2

3

4

5

6

7

8

 

curl -XPUT http:localhost:9200/myindex -d '{

"settings":{

    "number_of_replicas": 0,

    "number_of_shards": 1

}

}'

 

 

在上面建立的索引中,我們為演示基本的搜尋寫入若干文件,然後從結果中解釋 profile API。讓我們索引三個doc:

 

 

1

2

3

4

5

6

7

8

9

10

11

 

curl -XPOST http://localhost:9200/myindex/mytype/1 -d '{

"brand" : "Cotton Plus"

}'

curl -XPOST http://localhost:9200/myindex/mytype/2 -d '{

"brand" : "Van Huesen"

}'

curl -XPOST http://localhost:9200/myindex/mytype/3 -d '{

"brand" : "Arrow"

}'

 

 

可以通過在 query 部分上方提供 “profile: true” 來啟用Profile API。讓我們來看看帶profile引數的 query 在單個查詢中長什麼樣子:

 

 

1

2

3

4

5

6

7

8

9

10

 

curl XPOST http://localhost:9200/myindex/mytype/_search -d '{

"profile": true,

     "query": {

       "match": {

         "brand": "Cotton Plus"

       }

     }

}'

 

 

Profile API的結果是基於每個分片計算的。由於在我們的例子中只有一個分片,我們在profile API響應的分片陣列中只有一個數組元素,如下所示:

 

 

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

 

{

"shards": [

   {

     "id": "[egPYczsCRTqaeJ8jKhFjtw][myindex][0]",

     "searches": [

       {

         "query": [

           {

             "query_type": "BooleanQuery",

             "lucene": "brand:levi brand:goals",

             "time": "1.293761000ms",

             "breakdown": {

               "score": 0,

               "create_weight": 136078,

               "next_doc": 0,

               "match": 0,

               "build_scorer": 1082113,

               "advance": 0

             },

             "children": [

               {

                 "query_type": "TermQuery",

                 "lucene": "brand:levi",

                 "time": "0.04626300000ms",

                 "breakdown": {

                   "score": 0,

                   "create_weight": 30190,

                   "next_doc": 0,

                   "match": 0,

                   "build_scorer": 16073,

                   "advance": 0

                 }

               },

               {

                 "query_type": "TermQuery",

                 "lucene": "brand:goals",

                 "time": "0.02930700000ms",

                 "breakdown": {

                   "score": 0,

                   "create_weight": 16600,

                   "next_doc": 0,

                   "match": 0,

                   "build_scorer": 12707,

                   "advance": 0

                 }

               }

             ]

           }

         ],

         "rewrite_time": 64032,

         "collector": [

           {

             "name": "TotalHitCountCollector",

             "reason": "search_count",

             "time": "0.002931000000ms"

           }

         ]

       }

     ]

   }

}

 

 

Profile API響應說明

上面的響應顯示的是單個分片。每個分片都被分配一個唯一的ID,ID的格式是[nodeID][indexName][shardID]。現在在"shards"數組裡還有另外三個元素,它們是:

  1. query
  2. rewrrite_time
  3. collector

Query

Query 段由構成Query的元素以及它們的時間資訊組成。Profile API結果中Query 部分的基本組成是:

  1. query type – 它向我們顯示了哪種型別的查詢被觸發。此處是布林值。因為多個關鍵字匹配查詢被分成兩個布林查詢。

     

  2. lucene – 該欄位顯示啟動查詢的lucene方法。這裡是 "brand:levi brand:goals"

  3. time – lucene 執行此查詢所用的時間。單位是毫秒。

  4. breakdown – 有關查詢的更詳細的細節,主要與lucene引數有關。
  5. children – 具有多個關鍵字的查詢被拆分成相應術語的布林查詢,每個查詢都作為單獨的查詢來執行。每個子查詢的詳細資訊將填充到Profile API輸出的子段中。在上面的章節中,可以看到第一個子元素查詢是"levi",下面給出查詢時間和其他breakdown引數等詳細資訊。同樣,對於第二個關鍵字,有一個名為"goals"的子元素具有與其兄弟相同的資訊。從查詢中的子段中,我們可以得到關於哪個搜尋項在總體搜尋中造成最大延遲的資訊。

Rewrite Time

由於多個關鍵字會分解以建立個別查詢,所以在這個過程中肯定會花費一些時間。將查詢重寫一個或多個組合查詢的時間被稱為“重寫時間”。(以納秒為單位)。

Collectors

在Lucene中,收集器是負責收集原始結果,收集和組合結果,執行結果排序等的過程。例如,在上面的執行的查詢中,當查詢語句中給出size:0時,使用的收集器是"totalHitCountCollector"。這隻返回搜尋結果的數量(search_count),不返回文件。此外,收集者所用的時間也一起給出了。

總結

在這篇部落格中,我們看到Profile API非常有用,它讓我們清楚地看到查詢時間。通過向我們提供有關子查詢的詳細資訊,清楚地知道在那個環節查詢慢,這是非常有用的。另外,API返回結果中,關於Lucene的詳細資訊也讓我們深入瞭解到 elasticsearch 是如何執行查詢的。

參考:

http://cwiki.apachecn.org/display/Elasticsearch/Profile+API

相關文章:

  1. elasticsearch indices.recovery 流程分析與速度優化