【发布时间】: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