Как работает эластичный поиск delete_by_query? Что происходит, когда мы вставляем новые данные и извлекаем их при удалении документов?

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

Ниже приведена информация о конфигурации

  • Ява: 8
  • Эластичная версия: 7.1.1
  • Добавлены эластичные зависимости:

    <dependency>
        <groupId>org.elasticsearch.client</groupId>
        <artifactId>elasticsearch-rest-high-level-client</artifactId>
        <version>7.1.1</version>
    </dependency>
    
    <dependency>
        <groupId>org.elasticsearch</groupId>
        <artifactId>elasticsearch</artifactId>
        <version>7.1.1</version>
    </dependency>
    

В моем случае ежедневно в индекс dev-answer добавляется около 10 тысяч записей. Я хочу инициировать операцию удаления (это можно запускать ежедневно, или раз в неделю, или раз в месяц), которая в основном удалит все документы сверху index, если выполняется определенное условие. (Который я дам в DeleteByQueryRequest)

Для удаления существует API, указанный в последней версии doc, на который я ссылаюсь.

DeleteByQueryRequest request = new DeleteByQueryRequest("source1", "source2");

При чтении документации я столкнулся со следующими запросами, которые я не могу понять.

  1. Как в документе: It’s also possible to limit the number of processed documents by setting size. request.setSize(10); Что означает обработанный документ? Будет ли удалено только 10 документов?

  2. Какой размер партии я должен установить? request.setBatchSize(100); его производительность зависит от того, сколько документов мы собираемся удалить?

    Должен ли я сначала позвонить get no of documents и на основании этого setBatchSize следует изменить?

  3. request.setSlices(2); Срезы должны зависеть от того, сколько ядер у машины-исполнителя или от количества ядер в эластичном кластере?

  4. В документации указан метод setSlices(2), который я не могу найти в классе org.elasticsearch.index.reindex.DeleteByQueryRequest. Что мне здесь не хватает?

  5. Давайте рассмотрим, выполняю ли я этот запрос на удаление в асинхронном режиме, который занимает 0,5-1,0 секунды, между тем, если я делаю запрос на получение этого индекса, выдаст ли это какое-то исключение? Также в то же время, если я вставлю новый документ и извлеку его, сможет ли он дать ответ?


person AshwinK    schedule 05.07.2019    source источник
comment
Очень интересный вопрос. Я так понимаю, вы спрашиваете о конечной точке _delete_by_query, а не о конечной точке _bulk? Если вы спрашиваете о конечной точке _delete_by_query, можете ли вы переименовать вопрос, чтобы избежать недоразумений, потому что _bulk также позволяет удалять документы.   -  person Pierre-Nicolas Mougel    schedule 05.07.2019
comment
Я немного запутался, наверняка это удаление по запросу, но в java API я собираюсь использовать функцию: public final void deleteByQueryAsync(DeleteByQueryRequest deleteByQueryRequest, RequestOptions options, ActionListener<BulkByScrollResponse> listener) from classorg.elasticsearch.client.RestHighLevelClient. Итак, он собирается сделать массовый запрос или удалить по запросу? Также в случае удаления более 10 КБ в очень немногих случаях близко к 1 КБ записей, что будет хорошо? delete_by_query или _bulk ?   -  person AshwinK    schedule 05.07.2019
comment
И есть еще одна функция для запроса синхронизации, deleteByQuery, которая возвращает BulkByScrollResponse, поэтому возникает путаница, где это _bulk удалить или delete_by_query   -  person AshwinK    schedule 05.07.2019
comment
Я понимаю ваше замешательство. Конечная точка _delete_by_query будет внутренне выполнять bulk запросы для эффективного удаления документов, но это определенно разные конечные точки.   -  person Pierre-Nicolas Mougel    schedule 05.07.2019
comment
Хорошо понял. Я изменил вопрос, как было предложено. Спасибо.   -  person AshwinK    schedule 05.07.2019
comment
Спасибо, но не могли бы вы написать delete_by_query вместо delete в заголовке, чтобы избежать путаницы и помочь другим пользователям найти этот вопрос? delete также является еще одной конечной точкой. Пишу полный ответ на ваш вопрос.   -  person Pierre-Nicolas Mougel    schedule 05.07.2019
comment
Конечно. Я это сделаю.   -  person AshwinK    schedule 05.07.2019


Ответы (1)


1. Как в doc: Также можно ограничить количество обрабатываемых документов, установив размер. запрос.setSize(10); Что означает обработанный документ? Будет ли удалено только 10 документов?

Если вы еще этого не сделали, прочитайте search/_scroll документация. _delete_by_query выполняет поиск по прокрутке, используя запрос, указанный в качестве параметра.

Параметр size соответствует количеству документов, возвращаемых каждым вызовом конечной точки scroll. Если у вас есть 10 документов, соответствующих вашему запросу, и размер 2, elasticsearch внутренне выполнит 5 вызовов search/_scroll (т. е. 5 пакетов), а если вы установите размер 5, будут выполнены только 2 вызова search/_scroll.

Независимо от параметра size все документы, соответствующие запросу, будут удалены, но это будет более или менее эффективно.

2. Какой размер партии я должен установить? запрос.setBatchSize(100); его производительность зависит от того, сколько документов мы собираемся удалить?

Метод setBatchSize() эквивалентен установке параметра size в запросе. Чтобы узнать, правильное значение параметра размера.

3. Должен ли я сначала сделать вызов, чтобы не получить документы, и на основе этого setBatchSize должен быть изменен?

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

4. Срезы должны зависеть от того, сколько ядер у машины-исполнителя или от количества ядер в эластичном кластере?

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

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

5. В документации указан метод setSlices(2), который я не могу найти в классе org.elasticsearch.index.reindex.DeleteByQueryRequest. Что мне здесь не хватает?

Вы правы, это, вероятно, ошибка в документации. Я никогда не пробовал, но я считаю, что вам следует использовать forSlice(TaskId slicingTask, SearchRequest slice, int totalSlices).

6. Давайте рассмотрим, выполняю ли я этот запрос на удаление в асинхронном режиме, который занимает 0,5-1,0 секунды, между тем, если я делаю запрос на получение этого индекса, выдаст ли это какое-то исключение? Также в то же время, если я вставлю новый документ и извлеку его, сможет ли он дать ответ?

Во-первых, как указано в документации, конечная точка _delete_by_query создает снимок индекса и работает с этой копией.

Для запроса get это зависит от того, был ли документ уже удален или нет. Он никогда не отправит исключение, вы просто получите тот же результат, если вы извлекаете существующий или несуществующий документ. Обратите внимание, что если вы не укажете sort в поисковом запросе, порядок удаления документов не определяется.

Если вы вставляете (или обновляете) документ во время обработки, этот документ не будет учитываться конечной точкой _delete_by_query, даже если он соответствует запросу _delete_by_query. Здесь используется снимок. Поэтому, если вы вставите новый документ, вы сможете получить его. То же самое, если вы обновите существующий документ, документ будет создан снова, если он уже был удален или обновлен, но не удален, если он еще не удален.

В качестве примечания: удаленные документы по-прежнему будут доступны для поиска (даже после завершения задачи delete_by_query) до refresh произошла операция.

_delete_by_query не поддерживает параметр refresh. request return, упомянутый в документации для операции refresh, относится к запросам, которые могут иметь параметр обновления. Если вы хотите принудительно обновить, вы можете использовать _refresh конечная точка. По умолчанию операция обновления выполняется каждую секунду. Таким образом, после завершения операции _delete_by_query не более чем через 1 секунду удаленные документы не будут доступны для поиска.

person Pierre-Nicolas Mougel    schedule 05.07.2019
comment
Думали ли вы об использовании дневных индексов? Затем вы можете просто удалить весь индекс, что намного дешевле, поскольку вы избежите всех слияний, происходящих после больших удалений. Такой подход был бы более производительным (по крайней мере, для удаления), а также более простым в реализации. Однако могут быть компромиссы в отношении чрезмерного шардинга. - person xeraa; 05.07.2019
comment
Большое спасибо за подробный ответ и ссылку на документацию. Это прояснило многие понятия. Пакетный документ имеет смысл в том, что размер пакета должен зависеть от размера возвращаемых данных. Так что это не имеет ничего общего с ограничением прокрутки, верно? В delete_by_query пакетное ограничение используется для копирования данных из текущего индекса в его снимок, верно? - person AshwinK; 05.07.2019
comment
Поскольку в этом случае я не устанавливаю значение обновления, это означает, что оно будет false (the default), верно? Но что это значит The changes made by this request will be made visible at some point after the request returns.(from refresh doc) ? Что здесь request returns? - person AshwinK; 05.07.2019
comment
@xeraa Да, эти варианты тоже имеют смысл. Но в настоящее время я не думаю о ежедневных индексах до тех пор, пока операция удаления не будет иметь фиксированную периодичность. Просто интересно знать, какие компромиссы будут там? - person AshwinK; 05.07.2019
comment
Я обновил ответ ответом на ваш вопрос об операции refresh. Я не уверен, что понимаю ваш вопрос о размере партии и ограничении прокрутки. Что вы имеете в виду под ограничением прокрутки? - person Pierre-Nicolas Mougel; 06.07.2019
comment
Ограничение прокрутки @Pierre-NicolasMougel Я имею в виду "size": 100, которое будет задано при вызове _search?scroll API. - person AshwinK; 06.07.2019
comment
Хорошо, тогда размер партии является пределом прокрутки. - person Pierre-Nicolas Mougel; 06.07.2019
comment
Недостатки ежедневных индексов: у вас, вероятно, будет больше осколков (вероятно, 1 в день). Для каждого сегмента существуют определенные накладные расходы (поэтому держите их на низком уровне), и вашим операциям поиска потребуется искать больше сегментов (вероятно, через псевдоним индекса myindex-*). - person xeraa; 06.07.2019