Запрос Elasticsearch _search всегда выполняется для каждого индекса - PullRequest
0 голосов
/ 28 ноября 2018

У меня проблема с приборной панелью Kibana, которая выдает множество предупреждений Courier Fetch: xxx of 345 shards failed. каждый раз, когда я перезагружаю ее.

Хорошо, я прошу данные, охватывающие последние 15 минут,и у меня есть индекс в день.Сегодняшний индекс не содержит 345 осколков.Итак, почему мой запрос охватывает так много шардов?


Вещи, которые я проверил:

  • Количество индексов и шардов в индексе:

    Я проверил это, используя конечную точку _cat/indices: после фильтрации индексов, которые я не создал сам (например, индексы кибаны, в основном все, что начинается с точки), у меня есть 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,

Мы видим, чтоВторой запрос возвращает те же результаты, что и первый, но выполняет поиск по каждому индексу.

  • My timestamp Индексируется поле:

    По умолчанию каждое поле вasticsearch индексируется, но я все равно дважды проверил его:

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: это было проверено на другомэластичный кластер той же версии, с некоторыми полями, явно не включенными в индекс

1 Ответ

0 голосов
/ 25 января 2019

TL; DR

Я наконец решил проблему, просто уменьшив количество осколков.

Полное раскрытие

При использовании инструментов разработки на кибане я мог найтимного ошибок в конечной точке _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, вероятно, будет работать, но, по-видимому, настоятельно рекомендуется против (насколько я понимаю, в большинстве случаев эта ошибка является лишь признаком более глубоких проблем, которые следует исправитьвместо этого)

Это одноузловой кластер объемом 160 ГБ, имеющий (сейчас) более 350 сегментов.Это приводит к чрезвычайно низкому среднему размеру для каждого шарда, поэтому я решил сначала попробовать номер 4. Переиндексировать мои данные, чтобы использовать меньшее количество шардов.

Как я его делю

Использовать один шард на индекс:

Я создал следующий шаблон индекса:

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

Теперь все мои будущие индексы будут иметь один осколок.

Мне все еще нужно переиндексировать или объединить существующие индексы, но это должно быть сделано со следующей точкой в ​​любом случае.

Переключение на месячные индексы (вместо ежедневных)

Я изменил код, который вставляет данные в ES, чтобы использовать основанный на месяце индексname (например, 201901_monthly_logs, а затем переиндексирует каждый старый индекс к соответствующему в новом шаблоне:

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

Наслаждайтесь!

Выполнив это, я сократился до 7 индексов(и еще 7 осколков). Все, что осталось, - это изменить шаблон индекса с _logs на _monthly_logs в моих визуализациях кибаны.

У меня не было никаких проблем с этого времени, я будупросто подожди еще немного, затем удали мои старые индексы.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...