Будьте осторожны, чтобы не утонуть в зыбучих песках Elasticsearch глубокой пагинации

Разработка программного обеспечения - забавная штука. По мере развития своих навыков я начинаю формировать представление о том, что правильно и неправильно, что хорошо, а что плохо. Эта врожденная интуиция работает в большинстве случаев, а бывает, что она кусает меня за задницу. Десять лет назад разработка приложения означала разработку базового CRUD-приложения.

  1. Индексная страница с таблицей и строками.
  2. Страница редактирования записей.
  3. Пагинация, помогающий пользователю просмотреть 1 из миллиона страниц.

То, что Пагинация- плохая идея, не означает, что разработчик не попытается встроить его в свое приложение. Даже лучшие из нас хотят попытаться уйти от ответственности.

Подводные камни Elasticsearch

Elasticsearch, как и большинство других систем хранения данных, позволяет выполнять пагинацию набора данных, но есть одна загвоздка: Глубокая пагинация в распределенных системах.

Как объясняется на сайте документации Elasticsearch:

Чтобы понять, почему глубокая пагинация является проблематичной, представим, что мы ищем в одном индексе с пятью первичными шардами. Когда мы запрашиваем первую страницу результатов (результаты с 1 по 10), каждый шард создает свои 10 лучших результатов и возвращает их координирующему узлу, который затем сортирует все 50 результатов для выбора общей десятки лучших.
Теперь представьте, что мы запрашиваем страницу 1 000 - результаты с 10 001 по 10 010. Все работает точно так же, за исключением того, что каждый шард должен выдать свои 10 010 лучших результатов. Затем координирующий узел сортирует все 50 050 результатов и отбрасывает 50 040 из них!
Вы видите, что в распределенной системе стоимость сортировки результатов растет в геометрической прогрессии, чем глубже мы заходим на страницу. Не зря поисковые системы не выдают более 1 000 результатов по любому запросу.

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

Решения

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

Улучшить поиск

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

Не выкладывайте на страницу большие массивы данных

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

  • Диапазоны дат
  • Статус записи
  • Значимость .

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

Сводная информация

Пользователям могут потребоваться все данные, потому что они хотят сделать какой-то вывод, который может быть получен только из полного набора данных. В этом случае интерфейс или API должен иметь доступ к вычисленной сводной информации. Доступ к сводной информации сделает работу гораздо приятнее. Это легко сделать с помощью агрегации Elasticsearch.

 Пагинация... до определенного момента

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

Ядерный вариант (Не делайте этого!)

Elasticsearch отклонит любой запрос на листание, если он достигнет значения index.max_result_window.

Заметьте, что размер from+ не может быть больше, чем значение индекса index.max_result_window, которое по умолчанию равно 10 000.

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

Заключение

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

Понравилась статья? Поделиться с друзьями:
Добавить комментарий