【问题标题】:Elasticsearch _search query always runs on every indexElasticsearch _search 查询总是在每个索引上运行
【发布时间】:2018-11-28 15:06:47
【问题描述】:

我遇到了 Kibana 仪表板的问题,每次我重新加载它时都会抱怨多条 Courier Fetch: xxx of 345 shards failed. 警告消息。

好的,我要的是过去 15 分钟内的数据,而且我每天都有一个索引。今天的索引不可能包含 345 个分片。那么,为什么我的查询会跨越这么多分片?


我检查过的事情:

  • 索引数和每个索引的分片数:

    我使用_cat/indices 端点检查了这一点:过滤掉我自己没有创建的索引后(例如 kibana 的索引,基本上所有以点开头的索引),我有 69 个索引,每个索引包含 5 个分片(加起来总共 345 个分片)。这正是我所期待的。

    这基本上意味着我的搜索是在我的所有索引上执行的。

  • 我不会将新数据写入旧索引:

    这是对今天索引1上一小时记录的查询:

GET 20181027_logs/_search
{
"query": {
    "bool": {
      "must": [
        {
          "range": {
            "timestamp": {
              "gte": 1543326215000,
              "lte": 1543329815000,
              "format": "epoch_millis"
            }
          }
        }
      ]
    }
  }
}

答案(截断):

{
  "took": 2,
  "timed_out": false,
  "_shards": {
    "total": 5,
    "successful": 5,
    "failed": 0
  },
  "hits": {
    "total": 1557,

不限制索引的相同查询:

GET *_logs/_search
{
"query": {
    "bool": {
      "must": [
        {
          "range": {
            "timestamp": {
              "gte": 1543326215000,
              "lte": 1543329815000,
              "format": "epoch_millis"
            }
          }
        }
      ]
    }
  }
}

答案(截断):

{
  "took": 24,
  "timed_out": false,
  "_shards": {
    "total": 345,
    "successful": 345,
    "failed": 0
  },
  "hits": {
    "total": 1557,

我们可以看到,第二个查询返回的结果与第一个完全相同,但是搜索了每个索引。

  • 我的timestamp 字段已编入索引:

    默认情况下,elasticsearch 中的每个字段都有索引,但我还是仔细检查了它:

GET 20181027_logs/_mapping

{
  "20181027_logs": {
    "mappings": {
      "logs": {
        "properties": {
          […]
          "timestamp": {
            "type": "date"
          }
          […]

虽然非索引字段会给出2

           "timestamp": {
             "type": "date",
             "index": false
           }

剩余线索

在这一点上,我真的不知道可能是什么问题。

顺便说一句:时间戳字段不是事件的插入日期,而是事件实际发生的日期。不管这个时间戳是什么,事件都会插入到最新的索引中。 这意味着每个索引都可以有对应于过去日期的事件,但没有未来日期。

在这种精确的情况下,我不明白这有什么关系:因为我们只查询最后 15 分钟,所以无论发生什么,数据都只能在最后一个索引中。

Elasticsearch 和 Kibana 版本:5.4.3

感谢您阅读本文,任何帮助将不胜感激!


1 : 索引命名有误,导致索引名与实际对应的日期有偏差,但这里应该无所谓。

2:这是在另一个相同版本的弹性集群上检查的,其中一些字段明确选择退出索引

【问题讨论】:

  • 您查询的索引模式是什么?有多少索引映射到该索引模式?
  • 当索引映射因特定字段的索引而异时,我看到分片失败。例如,当一个字段映射到一个索引中的文本和另一个索引中的关键字时,这将导致同样的错误。请查看您的集群日志。
  • 在您的示例中使用 345 个分片(不限制索引的查询)的原因是 url 中的通配符。在 _search 请求中使用通配符时,将选择所有匹配的索引(以及属于它们的所有分片)来执行查询。查询的限制/过滤根本不会影响搜索到的索引/分片。它只会影响每个搜索索引/分片的结果。之后所有索引/分片的结果将合并为一个结果。

标签: elasticsearch kibana


【解决方案1】:

TL;DR

我终于通过减少分片数量解决了这个问题。

全面披露

在 kibana 上使用开发工具时,我可以在 _msearch 端点上发现许多错误:

{
  "shard": 2,
  "index": "20180909_logs",
  "node": "FCv8yvbyRhC9EPGLcT_k2w",
  "reason": {
    "type": "es_rejected_execution_exception",
    "reason": "rejected execution of org.elasticsearch.transport.TransportService$7@754fe283 on EsThreadPoolExecutor[search, queue capacity = 1000, org.elasticsearch.common.util.concurrent.EsThreadPoolExecutor@16a14433[Running, pool size = 7, active threads = 7, queued tasks = 1000, completed tasks = 16646]]"
  }
},

这基本上证明了我的 ES 服务器充斥着太多分片上的太多并行请求。

据我所知,kibana 查询我的索引模式的每个索引显然是正常的,如果其中一些不包含任何新数据(ES 无论如何都应该查询它们,并得出结论认为它们自从时间戳字段被索引以来,几乎立即不包含任何数据)

从那里,我有几个选择:

  • 1:减少数据保留
  • 2:减少我正在执行的并行请求的数量
  • 3:向我的集群添加节点
  • 4:重组我的数据以使用更少的分片
  • 5:增加搜索队列的大小

在我的情况下,1 和 2 不是一个选项。

5 可能会起作用,但显然强烈建议不要这样做(据我所知,在大多数情况下,此错误只是更深层次问题的症状,应该予以修复)

这是一个 160GB 的单节点集群,拥有(现在)超过 350 个分片。这使得每个分片的平均大小极低,因此我决定首先尝试第 4 点:重新索引我的数据以使用更少的分片。

我是怎么做的

每个索引使用一个分片:

我创建了以下索引模式:

PUT _template/logs {
  "template": "*_logs",
  "settings": {
    "number_of_shards": 1
  }
}

现在,我所有未来的索引都将有一个分片。

我仍然需要重新索引或合并现有索引,但这无论如何都必须在下一点完成。

切换到每月指数(而不是每日)

我修改了将数据插入到 ES 中的代码以使用基于月份的索引名称(例如201901_monthly_logs,然后将每个旧索引重新索引到新模式中的对应索引:

POST _reindex
{
  "source": {
    "index": "20181024_logs"
  },
  "dest": {
    "index": "201810_monthly_logs"
  }
}

享受吧!

完成后,我减少了 7 个索引(以及 7 个分片)。 剩下的就是在我的 kibana 可视化中将索引模式从 _logs 更改为 _monthly_logs

从那以后我没有遇到任何问题,我会再等一会儿,然后删除我的旧索引。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-07-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-05-14
    • 2014-05-30
    相关资源
    最近更新 更多