Amazon Elasticsearch - параллельные массовые запросы - PullRequest
1 голос
/ 20 февраля 2020

Когда я добавляю 200 документов в ElasticSearch с помощью одного массового запроса - это очень быстро.

Но мне интересно, есть ли шанс ускорить процесс с одновременным выполнением : 20 одновременных выполнений с 10 документами в каждом.

Я знаю, что это неэффективно, но, возможно, есть шанс ускорить процесс с одновременными выполнениями?

Ответы [ 2 ]

3 голосов
/ 21 февраля 2020

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

Существует множество параметров, которые можно настроить, когда речь идет о производительности пишет Elasticsearch. Одна очень быстрая победа, которую вы должны проверить: используете ли вы HTTP keep-alive для ваших соединений? Это сэкономит много накладных расходов TCP и TLS при настройке каждого соединения. Именно это изменение может значительно повысить производительность, а также раскрыть некоторые важные архитектурные соображения для вашего конвейера индексирования.

Так что проверьте это и посмотрите, как это происходит. Оттуда мы должны go вниз и продолжить наш путь.

Индекс на диске - Lucene. Lucene - это сегментированный индекс. Часть index является основной причиной, по которой вы в первую очередь используете Elasticsearch: словарь отсортированных терминов можно искать за O (log N). Это супер быстро и масштабируемо. Сегментная часть состоит в том, что вставка в индекс не особенно быстра - в зависимости от вашей реализации, для поддержания сортировки требуется O (log N) или O (N log N).

Так что хитрость Lucene заключается в буферизации эти обновления и добавить новый сегмент; по сути это коллекция мини-индексов. Поиск некоторого относительно небольшого числа сегментов все еще намного быстрее, чем все время, чтобы поддерживать отсортированный индекс при каждом обновлении. Со временем Lucene позаботится о объединении этих сегментов, чтобы удержать их в некотором разумном диапазоне размеров, удалив удаленные и перезаписанные документы в процессе.

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

Sharding делает это немного интереснее.

Одна из сильных сторон Elasticsearch - способность раздел данные индекса по нескольким шардам. Это помогает с доступностью, и помогает масштабировать рабочие нагрузки за пределы ресурсов одного сервера.

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

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

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

В большинстве тестов и анализов, которые я видел, и в моем опыте работы с Lucene в течение ~ десяти лет медленной частью индексации является преобразование значений документов в инвертированный индексный формат. Разбор текста, анализ его в терминах и т. Д. Может быть очень сложным и дорогостоящим. Пока в массовом запросе достаточно документов, которые достаточно хорошо распределены между осколками, параллелизм не так значим, как насыщение работы, выполненной на уровне сегмента и сегмента.

При настройке массовых запросов мой совет вот так.

  • Использовать поддержку активности HTTP. Это не обязательно. (Вы используете TLS, верно?)
  • Выберите размер пакета, когда каждый запрос занимает скромное количество времени. Где-то около 1 секунды, вероятно, не более 10 секунд.
  • Если вы можете придумать, измерьте, сколько времени занимал каждый массовый запрос, и динамически увеличивайте и сокращайте свою партию.

Прочная очередь открывает множество возможностей. Если можно извлекать и собирать документы и вставлять их, скажем, в Kafka, то этот процесс можно запустить параллельно, чтобы насытить базу данных и распараллелить любую денормализацию или подготовку документов. Затем другой процесс извлекает из очереди и отправляет запросы на сервер, и с некоторой легкой координацией вы можете тестировать и настраивать различные параллелизм на разных этапах. Очередь также позволяет вам приостанавливать обновления для различных задач миграции и обслуживания, когда помогает на некоторое время перевести кластер в режим только для чтения.

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

Чтобы закрыть, что, если вы запускаете в любом случае до параллелизма? Каковы риски? Некоторые рабочие нагрузки не контролируют параллелизм, и нет времени или ресурсов, чтобы поставить очередь перед поисковой системой. В этом случае Elasticsearch может избежать довольно значительного количества параллелизма. Он имеет довольно большие пулы потоков для обработки одновременных обновлений документов. Если эти пулы потоков переполнены, он отклонит ответы с сообщением об ошибке HTTP 429 и сообщением об превышении глубины очереди. Они могут повлиять на стабильность кластера в зависимости от доступных ресурсов и количества сегментов в индексе. Но это все довольно заметные проблемы.

Итог: нет, 20 одновременных пакетов с 10 документами в каждом, вероятно, не увеличат производительность по сравнению с 1 пакетом с 200 документами. Если ваши массовые операции выполняются быстро, вы должны увеличивать их размер до тех пор, пока они не будут выполняться в течение одной или двух секунд или проблематичны c. Используйте keep-alive. Если есть другие накладные расходы на стороне приложения, увеличьте ваш параллелизм до 2x или 3x и измерьте эмпирически. Если индексирование является критически важным, используйте быструю и длительную очередь.

0 голосов
/ 20 февраля 2020

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

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

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

Поскольку вы делаете это партиями по 200, велика вероятность, что это будет наиболее оптимальный способ индексации. Но, опять же, это будет зависеть от факторов, упомянутых выше.

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