Profile API

原文链接 : https://www.elastic.co/guide/en/elasticsearch/reference/current/search-profile.html

译文链接 : Profile API

贡献者 : 王晗

此功能是实验性功能,可能在未来的版本中完全更改或删除。

Profile API提供了在搜索请求中执行单个组件的详细时间信息。它让用户了解在底层如何执行搜索请求,这样用户可以理解为什么某些请求是缓慢的,并采取措施改善他们。

Profile API的输出非常详细,特别是对于跨多个分片的复杂请求执行。推荐使用pretty打印响应信息,这样有助于理解输出结果。

用法/Usage

任意_search请求可以通过添加一个顶级profile参数来实现概要描述。

  1. curl -XGET 'localhost:9200/_search?pretty' -H 'Content-Type: application/json' -d'
  2. {
  3. "profile": true, (1)
  4. "query" : {
  5. "match" : { "message" : "message number" }
  6. }
  7. }
  8. '

(1) 设置顶级profile参数为true,开启搜索概要描述

这将产生以下结果:

  1. {
  2. "took": 25,
  3. "timed_out": false,
  4. "_shards": {
  5. "total": 1,
  6. "successful": 1,
  7. "failed": 0
  8. },
  9. "hits": {
  10. "total": 4,
  11. "max_score": 0.5093388,
  12. "hits": [...]
  13. },
  14. "profile": {
  15. "shards": [
  16. {
  17. "id": "[2aE02wS1R8q_QFnYu6vDVQ][twitter][1]",
  18. "searches": [
  19. {
  20. "query": [
  21. {
  22. "type": "BooleanQuery",
  23. "description": "message:message message:number",
  24. "time": "1.873811000ms",
  25. "time_in_nanos": "1873811",
  26. "breakdown": {
  27. "score": 51306,
  28. "score_count": 4,
  29. "build_scorer": 2935582,
  30. "build_scorer_count": 1,
  31. "match": 0,
  32. "match_count": 0,
  33. "create_weight": 919297,
  34. "create_weight_count": 1,
  35. "next_doc": 53876,
  36. "next_doc_count": 5,
  37. "advance": 0,
  38. "advance_count": 0
  39. },
  40. "children": [
  41. {
  42. "type": "TermQuery",
  43. "description": "message:message",
  44. "time": "0.3919430000ms",
  45. "time_in_nanos": "391943",
  46. "breakdown": {
  47. "score": 28776,
  48. "score_count": 4,
  49. "build_scorer": 784451,
  50. "build_scorer_count": 1,
  51. "match": 0,
  52. "match_count": 0,
  53. "create_weight": 1669564,
  54. "create_weight_count": 1,
  55. "next_doc": 10111,
  56. "next_doc_count": 5,
  57. "advance": 0,
  58. "advance_count": 0
  59. }
  60. },
  61. {
  62. "type": "TermQuery",
  63. "description": "message:number",
  64. "time": "0.2106820000ms",
  65. "time_in_nanos": "210682",
  66. "breakdown": {
  67. "score": 4552,
  68. "score_count": 4,
  69. "build_scorer": 42602,
  70. "build_scorer_count": 1,
  71. "match": 0,
  72. "match_count": 0,
  73. "create_weight": 89323,
  74. "create_weight_count": 1,
  75. "next_doc": 2852,
  76. "next_doc_count": 5,
  77. "advance": 0,
  78. "advance_count": 0
  79. }
  80. }
  81. ]
  82. }
  83. ],
  84. "rewrite_time": 51443,
  85. "collector": [
  86. {
  87. "name": "CancellableCollector",
  88. "reason": "search_cancelled",
  89. "time": "0.3043110000ms",
  90. "time_in_nanos": "304311",
  91. "children": [
  92. {
  93. "name": "SimpleTopScoreDocCollector",
  94. "reason": "search_top_hits",
  95. "time": "0.03227300000ms",
  96. "time_in_nanos": "32273"
  97. }
  98. ]
  99. }
  100. ]
  101. }
  102. ],
  103. "aggregations": []
  104. }
  105. ]
  106. }
  107. }

(1)返回的搜索结果,为简便起见,这里省略

即使对于一个简单的查询,响应过程也是相对复杂的。在深入更复杂的例子之前,让我们先全面剖析它。

首先,profile响应的整体结构如下:

  1. {
  2. "profile": {
  3. "shards": [
  4. {
  5. "id": "[2aE02wS1R8q_QFnYu6vDVQ][twitter][1]", (1)
  6. "searches": [
  7. {
  8. "query": [...], (2)
  9. "rewrite_time": 51443, (3)
  10. "collector": [...] (4)
  11. }
  12. ],
  13. "aggregations": [...] (5)
  14. }
  15. ]
  16. }
  17. }

| (1)profile返回参与响应的每一个分片,这些分片由唯一ID标识 | | (2)每个概要都包含关于查询执行的详细信息部分 | | (3)每个概要都有一个单独的rewrite_time累计时间。 | | (4)每个概要还包含关于运行搜索的lucene Collector部分 | | (5)每个概要都包含有关聚合执行的详细信息部分 |

因为一个搜索请求可能在一个或多个索引分片上执行,并且搜索范围覆盖一个或多个索引,profile的响应中顶层元素是一个shard对象数组。每个分片对象列表都列出唯一标识分片的id。ID的格式是[nodeID][indexName][shardID]

profile本身可能包含一个或多个”searches”字段,其中每个搜索search是针对底层Lucene索引执行的查询。用户提交的大多数搜索请求只会执行对Lucene索引的一个search。但偶尔也会执行多个搜索searches,如包括全局聚合(这需要执行第二个“match_all”查询全局上下文)。

在每个搜索对象里,会有两个概要信息的数组:query 数组和collector 数组。与搜索对象并肩的是一个聚合aggregations 对象,它包含聚合的概要信息。在未来,可以添加更多的部分,如建议 suggest,高亮highlight等。

这也会有一个rewrite 度量显示重写查询的总时间 (以纳秒为单位)。