Есть ли способ гарантировать, что индекс ElasticSearch был удален - PullRequest
1 голос
/ 13 июня 2019

В некоторых автоматизированных тестах я пытаюсь удалить и сразу же заново создать индекс в начале каждого теста, используя высокоуровневый клиент ElasticSearch (версия 6.4), следующим образом:

DeleteIndexRequest deleteIndexRequest = new DeleteIndexRequest(indexName);
deleteIndexRequest.indicesOptions(IndicesOptions.lenientExpandOpen());
client.indices().delete(deleteIndexRequest, RequestOptions.DEFAULT);

CreateIndexRequest createIndexRequest = new CreateIndexRequest(indexName);
request.mapping("_doc", "{...}", XContentType.JSON);
client.indices().create(request, RequestOptions.DEFAULT);

у меня проблема в том, что периодически мои тесты терпят неудачу в момент создания индекса с ошибкой:

{"error": {"root_cause":[{"type":"resource_already_exists_exception","reason":"index [(index-name)/(UUID)] already exists, ...,}] "status":400}

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

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

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

Я также пытался выполнить проверку exists() перед операцией создания.Интересно, что в этом случае, если я запускаю тесты без точек останова, проверка exists() всегда возвращает false (то есть, что индекс не существует) даже в тех случаях, когда в этом случае произойдет ошибка, , но , еслиЯ ставлю точку останова перед операцией создания, затем проверка exists() возвращает true в случаях, когда произойдет ошибка.

Я немного растерялся.Насколько я понимаю, мои запросы должны быть синхронными, и из комментария к к этому вопросу это должно означать, что операция delete() возвращается только тогда, когда индекс определенно был удален.

Я подозреваю, что ключевой частью проблемы может быть то, что эти тесты выполняются на кластере из 3 узлов.При настройке клиента я обращаюсь только к одному из узлов:

client = new RestHighLevelClient(RestClient.builder(new HttpHost("example.com", 9200, "https")));

, но вижу, что каждая операция реплицируется на два других узла.

Когда я останавливаюсьТочка останова перед операцией создания, в случаях, когда индекс не удаляется, я вижу, что он не удаляется ни на одном из узлов, и, кажется, не имеет значения, как долго я жду, он никогда не удаляется.

Можно ли как-нибудь надежно определить, был ли индекс удален перед его созданием?Или, может быть, мне нужно что-то сделать до Я пытаюсь выполнить операцию удаления, чтобы гарантировать ее успешность?

1 Ответ

1 голос
/ 13 июня 2019

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

Это одна вещь, которую вы должны рассмотреть: «Если используется внешний вариант управления версиями, операция удаления автоматически создает индекс, если он не был создан ранее (см. API создания индекса для создания индекса вручную).» https://www.elastic.co/guide/en/elasticsearch/reference/current/docs-delete.html Какой тип объяснил бы, почему существует () вернул бы false. Поэтому, если используется внешний вариант управления версиями, опция удаления фактически создаст индекс с тем же именем до его удаления.

Вы упомянули о том, что вы работаете с кластером из трех узлов. То, что вы можете попробовать это: «При создании запросов на удаление вы можете установить для параметра wait_for_active_shards требование, чтобы минимальное количество копий шарда было активным, прежде чем начинать обрабатывать запрос на удаление». Вот очень подробное объяснение, которое, безусловно, стоит прочитать: https://www.elastic.co/guide/en/elasticsearch/reference/current/docs-index_.html#index-wait-for-active-shards

Я предлагаю вам попробовать:

curl -X DELETE 127.0.0.1:9200/fooindex?wait_for_active_shards=3

Вы сказали, что у вас есть 3 узла в кластере, так что это означает, что: "... операция индексации потребует 3 активных копии осколка, прежде чем продолжить, это требование должно быть выполнено, потому что в кластере есть 3 активных узла, каждый один держит копию осколка. " Эта проверка, вероятно, не на 100% водонепроницаема, так как согласно документам здесь: https://www.elastic.co/guide/en/elasticsearch/reference/current/docs-index_.html#index-wait-for-active-shards «Важно отметить, что этот параметр значительно снижает вероятность того, что операция записи не выполнит запись в необходимое количество копий сегмента, но не полностью исключает эту возможность, поскольку эта проверка происходит до того, как начинается операция записи. После операции записи в процессе, репликация все равно возможна для любого количества копий сегмента, но все еще успешна на первичном. В разделе _shards ответа операции записи показано количество копий сегмента, для которых репликация была успешной / неудачной. " поэтому, возможно, используйте этот параметр, но пусть ваш код проверит ответ, чтобы увидеть, не произошла ли какая-либо операция.

Вы также можете попробовать следующее: (Я не могу найти хорошую документацию для подтверждения этой информации) Это должно быть в состоянии сказать вам, если кластер не готов принять удаления.

curl -X DELETE 127.0.0.1:9200/index?wait_for_completion=true
...