Воскресенье, 15 марта 2020 14:10

Searchkick::MissingIndexError. Elasticsearch

Оцените материал
(2 голосов)

Сегодня рассказ об интересной коллизии и о несложном способе ее разрешения; также все описанное может служить некоторым подспорьем для начинающих Ruby on Rails разработчиков, не работавших ранее с elasticsearch и gem 'searchkick'.

Searchkick::MissingIndexError. Elasticsearch
Phusion Passenger. Frozen processes

Короткой строкой вводные: в качестве веб-сервера использовалась связка nginx/1.14.0 + Phusion_Passenger/6.0.2, также Ruby 2.3.1p112 / Rails 4.2.0, MariaDB 10.3.16, Elasticsearch 6.8.1, Redis 4.0.9, и отметим присутствие в системе довольно старого (3.1.0) релиза searchkick. Проект не являлся разработкой вашего покорного слуги, а достался ему, так сказать, в наследство, вернее сказать - на аутсорсинг; техническая документация от команды разработчиков была, что называется, "при наличии отсутствия", разнообразных же трабл же (см. скриншот) хватало... но не хотелось начинать изучение не самой простой инфраструктуры с апгрейдов.

Тем не менее, ситуация требовала немедленных решений, поскольку имело место перманентное Searchkick::MissingIndexError, "падение индекса", после которого веб-сайт отказывался работать в нормальном режиме, и так вплоть до запуска вручную и окончания реиндексации:

 

RAILS_ENV=production rake searchkick:reindex CLASS=Product

 

Здесь нелишне будет кратко процитировать выводы аудита одного из пользователей Elasticsearchsearchkick, столкнувшегося, по-видимому, с похожей проблемой:

Did you solve this? We were having the same problem with almost exactly the same conditions: We have a cron job that runs Model.reindex. When it was running, it changed index mappings to wrong mappings. But, if we use console to run Model.reindex, it creates index with correct mappings.

After investigating we discovered that try to reindex without last reindex have finished was causing this.

Looks like Searchkick's reindex run clean_indices before start a new reindex but it doesn't kill current reindex process, so it erases index mappings but the first reindex continues to run by creating a index with default elasticsearch mapping.

, и ответ разработчика:

I think a check before each reindex call will slow down indexing significantly, so I'd recommend one of the alternatives depending on the behavior you want:

To have the old job stop when a new one starts, disable automatic index creation
To allow for overlapping jobs, use the retain: true option and write custom cleaning logic

Also, fwiw, I would avoid scheduling Model.reindex to run automatically in most situations (since it can affect the mapping). You can sync records to the current index with:

Product.reindex(scoped: true)

Также еще описание.

Итак, было принято решение для начала отключить автоматический реиндекс. В скобках: судя по репликам разработчика джема - им были оперативно внесены соответствующие исправления в программный код, и вполне достаточно было бы, вероятно, попросту обновить gem 'searchkick' до актуальной версии... но мы, как всегда, не ищем легких путей. Итак, включенную по умолчанию автоматическую реиндексацию отключаем следующим образом, как будет показано далее.

Сразу оговорюсь, старый способ:

# Require explicit index creation
action.auto_create_index: false

не работает для актуального релиза Elasticsearch; находим elasticsearch.yml (пути могут разниться) и поступаем следующим образом:

# /etc/elasticsearch/elasticsearch.yml
action.auto_create_index: ".watches,.triggered_watches,.watcher-history-*"

Дополнительно (просто чтобы избавиться от назойливого варнинга):

Mar 05 22:26:07 vinil elasticsearch[61416]: warning: Falling back to java on path. This behavior is deprecated. Specify JAVA_HOME

- совсем нелишне явно указать путь к java, предварительно его посмотрев:

echo $JAVA_HOME
# /etc/default/elasticsearch
JAVA_HOME=/usr/lib/jvm/java-8-oracle

Затем, само собой разумеется:

sudo service elasticsearch restart
sudo service elasticsearch status -l

Для полноты картины упомяну о совете, почерпнутом на этой страничке; в случае, если после правки конфига приложению не удается рестартануть -

Mar 05 22:26:07 vinil systemd[1]: Started Elasticsearch.
Mar 05 22:26:10 vinil systemd[1]: elasticsearch.service: Main process exited, code=exited, status=1/FAILURE
Mar 05 22:26:10 vinil systemd[1]: elasticsearch.service: Failed with result 'exit-code'.

- кому-то, вполне вероятно, поможет (путь может разниться) следующее, хотя и небесспорное, решение.:

sudo rm -rf /var/lib/elasticsearch/elasticsearch/nodes/0/ # Delete the state-0.st fille

Также в помощь это описание. И это. Ну и еще вот это.

Результат произведенных манипуляций, которые постарался здесь кратко описать, не заставил себя ждать: ошибка 500 Internal Server Error исчезла. Так что... рекомендую.

Продолжение, как всегда, следует.

Последнее изменениеВоскресенье, 15 марта 2020 15:05

1 Комментарий

  • Комментировать Evgenij Суббота, 04 апреля 2020 00:07 написал Evgenij

    Правильный способ рестарта elasticsearch:
    _stackoverflow.com
    /questions
    /14119062/restart-elasticsearch-node

Оставить комментарий

Добавьте ваш комментарий

Разработка web-проектов

Комментарии в блоге