Причина длительного времени ответа на первый поисковый запрос?

Я работаю над приложением, которое использует MySQL в качестве своей базы данных. Однако я добавляю функцию поиска с автозаполнением/"результатами по мере ввода", которая использует ElasticSearch. Получение соответствующих данных из MySQL в ElasticSearch не является проблемой, и мои поиски работают нормально.

Однако у меня есть некоторые проблемы с производительностью, но только при выполнении «первого» поискового запроса, который занимает около 1-5 секунд. Под «первым» я подразумеваю первый поиск в течение пары минут; второй поиск в течение 10 секунд после первого поиска дает почти мгновенные результаты, в то время как второй поиск через пять минут после первого дает результаты только после значительной задержки.

Моя первоначальная мысль заключалась в том, что настройка HTTP-соединения (которое объединяется .NET Framework) вызывала дополнительную задержку, но кажется странным, что это займет 1-5 секунд в быстрой сети LAN, когда даже не используется DNS-имя для разрешения сервер ElasticSearch.

Есть ли другие возможные виновники/обычные подозреваемые, на которых мне следует обратить внимание? Или начальная задержка HTTP-соединения кажется разумной (и что мне с этим делать?)?

Поиск выполняется следующим образом (обратите внимание, что клиент ElasticSearch/NEST управляется как синглтон и уже создан):

public IEnumerable<Person> Search(ElasticClient esclient, IEnumerable<string> queryParts, int groupId) {
    // Make the search query and return the results.
    return esclient.Search<Person>(s => s
        .Query(q =>
            q.Terms(p => p.FirstName, queryParts) ||
            q.Terms(p => p.LastName, queryParts)
        )
        .Filter(f => f
            .Term(p => p.MemberOfGroups, new int[] { groupId })
        )
    ).Documents;
}

РЕДАКТИРОВАТЬ: My ElasticClient создается следующим образом:

new ElasticClient(new ConnectionSettings(new Uri(esUrl), index));

person David Nordvall    schedule 26.10.2015    source источник
comment
Как создать экземпляр ElasticClient?   -  person Rob    schedule 26.10.2015
comment
Квест обновлен с созданием экземпляра ElasticClient.   -  person David Nordvall    schedule 28.10.2015
comment
@DavidNordvall, как выглядит ваш кластер ES и сопоставление для Person?   -  person Russ Cam    schedule 03.11.2015


Ответы (2)


Скорее всего, это кеширование, которое происходит в Elasticsearch. Первый запрос будет кэшировать результаты фильтров, последующий вызов будет использовать кэшированные результаты вместо повторного запуска запроса. Если вы тем временем обновите индексы, кеш станет недействительным, потому что данные изменились.

Вы можете проверить это предположение следующим образом:

  • временное отключение refresh:
PUT /index/_settings
{
  "index": {
    "refresh_interval": "-1"
  }
}
  • выполнить запрос один раз
  • подождите несколько минут
  • запустите запрос второй раз и сравните результаты
  • после теста вы можете включить установку Refresh_Interval до исходного значения. Если вы не меняли его в настройках, то должно быть 1s (по умолчанию).
person Andrei Stefan    schedule 27.10.2015
comment
Отключение обновления будет означать, что недавно проиндексированные документы не будут отображаться в моих результатах поиска, но все поиски (кроме самого первого) должны быть быстрыми? Что будет означать, что установка интервала обновления 3600 (один час) будет означать, что новые документы будут появляться в результатах поиска только один раз в час и что только один поиск в час будет медленным? - person David Nordvall; 27.10.2015
comment
Я упомянул refresh_interval, чтобы проверить гипотезу о том, что именно кэширование делает первый вызов более длительным, чем другие. Когда документы обновляются/добавляются/удаляются, кеш становится недействительным. Я пытаюсь запретить обновлять документы, чтобы мы могли проверить кеш. - person Andrei Stefan; 27.10.2015
comment
Это, кажется, не проблема. Я протестировал как отключение обновления, так и отключение обновления индекса, и ни одно из них не изменило поведение начального поиска, требующего очень долгого времени. - person David Nordvall; 28.10.2015
comment
И вы использовали один и тот же запрос каждый раз? - person Andrei Stefan; 28.10.2015
comment
Значение переменной queryParts (см. мой фрагмент кода в вопросе) изменилось, а термин фильтра - нет. - person David Nordvall; 28.10.2015
comment
Хорошо, запустите эту команду GET /_stats/filter_cache?index=your_index_name и посмотрите, есть ли filter_cache evictions. - person Andrei Stefan; 28.10.2015
comment
Нет вытеснения кеша фильтров. - person David Nordvall; 28.10.2015
comment
Это странно. Вы случайно не очищаете кеш вручную? Какая это версия ЕС? - person Andrei Stefan; 28.10.2015
comment
ЕС версии 1.7.2. Насколько я знаю, я не очищаю кеш вручную. У меня есть одна служба, которая постоянно обновляет индекс новыми и/или обновленными документами, и одно веб-приложение, которое запрашивает индекс. Обновление индекса выполняется с помощью API IndexMany‹T›() клиента NEST. - person David Nordvall; 28.10.2015
comment
Мне интересно, какой запрос генерирует ваш код .NET... можете ли вы включить медленные журналы и установить пороговое значение на очень низкое значение (1 мс) и запустить свой запрос? Тогда посмотрите в логах и предоставьте сгенерированный запрос, пожалуйста. - person Andrei Stefan; 28.10.2015

вы можете проверить или опубликовать журналы вашего гибкого поискового кластера здесь. Он должен находиться в вашем каталоге $log_directory/. Это даст более подробное представление о том, что происходит внутри кластера, если вы установите уровень tarce для журналов.

Во-первых, если кеш является проблемой для первого запроса, вы можете использовать эластичные обогреватели поиска для подогрева кэша кластера после развертывания или написать планировщик для запуска подогревателей дважды или трижды в день.

Спасибо.

person user3775217    schedule 27.10.2015