Elasticsearch — это поисковая и аналитическая система NoSQL, которую легко начать использовать для анализа журналов, текстового поиска, анализа в реальном времени и многого другого. Тем не менее, Elasticsearch представляет собой сложную распределенную систему со множеством рычагов, которые нужно использовать для достижения оптимальной производительности.
В этом блоге мы рассмотрим решения распространенных проблем производительности Elasticsearch в масштабе, включая медленную индексацию, скорость поиска, размер сегментов и индексов, а также мультиарендность. Многие решения рождаются в результате интервью и обсуждений с ведущими инженерами и архитекторами, имеющими практический опыт эксплуатации системы в больших масштабах.
При работе с рабочими нагрузками с высокой пропускной способностью записи вам может потребоваться настроить Elasticsearch для повышения производительности индексации. Мы предлагаем несколько рекомендаций по использованию достаточных ресурсов для индексации, чтобы эта операция не влияла на производительность поиска в вашем приложении:
Увеличьте интервал обновления : Elasticsearch делает новые данные доступными для поиска, обновляя индекс. Обновления автоматически происходят каждую секунду, когда индекс получает запрос за последние 30 секунд. Вы можете увеличить интервал обновления, чтобы зарезервировать больше ресурсов для индексации.
Используйте Bulk API . Известно, что при приеме крупномасштабных данных время индексации с использованием API обновления может занимать недели . В этих сценариях вы можете ускорить индексацию данных более экономичным способом с помощью Bulk API. Даже при использовании Bulk API вам необходимо знать количество проиндексированных документов и общий размер массового запроса, чтобы убедиться, что он не снижает производительность кластера. Elastic рекомендует сравнивать размер пакетного запроса, и, как правило, он составляет 5–15 МБ на пакетный запрос .
Увеличьте размер буфера индекса . Вы можете увеличить лимит памяти для невыполненных запросов индексирования до значения, превышающего значение по умолчанию, составляющее 10 % от кучи. Это может быть рекомендовано для рабочих нагрузок с большим объемом индексации, но может повлиять на другие операции, требующие интенсивного использования памяти.
Отключить репликацию. Вы можете установить для репликации нулевое значение, чтобы ускорить индексацию, но это не рекомендуется, если Elasticsearch является системой записи вашей рабочей нагрузки.
Ограничьте обновления и мутации данных на месте . Вставки, обновления и удаления требуют переиндексации целых документов. Если вы передаете CDC или транзакционные данные в Elasticsearch, возможно, вам стоит рассмотреть возможность хранения меньшего количества данных, поскольку тогда будет меньше данных для переиндексации.
Упростите структуру данных. Имейте в виду, что использование структур данных, таких как вложенные объекты, приведет к увеличению количества операций записи и индексирования. Упрощая количество полей и сложность модели данных, вы можете ускорить индексацию.
Если выполнение ваших запросов занимает слишком много времени, это может означать, что вам необходимо упростить модель данных или устранить сложность запроса. Вот несколько областей, которые следует учитывать:
Создайтесоставной индекс . Объедините значения двух полей с низкой мощностью вместе, чтобы создать поле с высокой мощностью, которое можно легко найти и получить. Например, вы можете объединить поле с почтовым индексом и месяцем, если это два поля, которые вы обычно фильтруете для своего запроса.
Включите пользовательскую маршрутизацию документов: Elasticsearch передает запрос всем сегментам для возврата результата. С помощью настраиваемой маршрутизации вы можете определить, в каком сегменте находятся ваши данные, чтобы ускорить выполнение запроса. Тем не менее, вы должны внимательно следить за горячими точками при выборе пользовательской маршрутизации.
Используйте тип поля ключевого слова для структурированного поиска. Если вы хотите выполнить фильтрацию на основе содержимого, например идентификатора или почтового индекса, для более быстрого поиска рекомендуется использовать тип поля ключевого слова, а не целочисленный тип или другие числовые типы полей.
Откажитесь от родительских-дочерних и вложенных объектов . Отношения «родитель-потомок» являются хорошим решением проблемы отсутствия поддержки соединений в Elasticsearch и помогают ускорить прием и ограничить переиндексацию. В конце концов, при таком подходе организации действительно достигают предела памяти. Когда это произойдет, вы сможете повысить производительность запросов, выполнив денормализацию данных.
Многие проблемы масштабирования с помощью Elasticsearch сводятся к стратегии сегментирования и индексации. Не существует единой стратегии, подходящей для всех, относительно того, сколько шардов вам следует иметь или какого размера они должны быть. Лучший способ определить стратегию — провести тесты и тесты на однородных рабочих нагрузках. Вот еще несколько советов, на которые стоит обратить внимание:
Используйте API принудительного слияния . Используйте API принудительного слияния, чтобы уменьшить количество сегментов в каждом сегменте. Объединение сегментов происходит автоматически в фоновом режиме и удаляет все удаленные документы. Использование принудительного слияния позволяет вручную удалить старые документы и повысить производительность. Это может быть ресурсоемким, поэтому не должно происходить во время пиковой нагрузки.
Остерегайтесь дисбаланса нагрузки : Elasticsearch не имеет хорошего способа понять использование ресурсов по сегментам и принять это во внимание при определении размещения сегментов. В результате возможны горячие осколки. Чтобы избежать этой ситуации, вы можете рассмотреть возможность использования большего количества сегментов, чем заметок с данными, и меньших сегментов, чем узлов данных.
Используйте индексы на основе времени . Индексы на основе времени могут уменьшить количество индексов и сегментов в вашем кластере в зависимости от срока хранения. Elasticsearch также предлагает API индекса переноса, позволяющий перейти на новый индекс в зависимости от возраста или размера документа для освобождения ресурсов.
Наиболее распространенными стратегиями мультиарендности являются использование одного индекса для каждого клиента или арендатора или использование настраиваемой маршрутизации. Вот как вы можете взвесить стратегии для своей рабочей нагрузки:
Индекс для каждого клиента или арендатора. Настройка отдельных индексов для каждого клиента хорошо подходит для компаний с небольшой базой пользователей, от сотен до нескольких тысяч клиентов, а также когда клиенты не обмениваются данными. Также полезно иметь индекс для каждого клиента, если каждый клиент имеет свою собственную схему и нуждается в большей гибкости.
Пользовательская маршрутизация. Пользовательская маршрутизация позволяет указать сегмент, в котором находится документ, например идентификатор клиента или идентификатор клиента, чтобы указать маршрутизацию при индексировании документа. При запросе на основе конкретного клиента запрос будет направляться непосредственно в сегмент, содержащий данные о клиенте, что ускоряет время ответа. Пользовательская маршрутизация — хороший подход, когда у вас есть согласованная схема для ваших клиентов и у вас много клиентов, что часто встречается, когда вы предлагаете модель freemium.
Elasticsearch предназначен для анализа журналов и сценариев использования текстового поиска. Многим организациям, которые используют Elasticsearch для масштабной аналитики в реальном времени, придется идти на компромиссы для поддержания производительности или экономической эффективности, включая ограничение сложности запросов и задержки приема данных. Когда вы начинаете ограничивать шаблоны использования, ваш интервал обновления превышает соглашение об уровне обслуживания или вы добавляете больше наборов данных, которые необходимо объединить, возможно, имеет смысл поискать альтернативы Elasticsearch.
Rockset является одной из альтернатив и специально создан для приема потоковых данных в реальном времени и запросов с низкой задержкой в масштабе. Узнайте, как перейти с Elasticsearch, и изучите архитектурные различия между двумя системами.