ElasticSearch 1.6, похоже, теряет документы во время теста высокой доступности

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

Я установил минимальный кластер, используя легкодоступное изображение Docker для ElasticSearch 1.6 (https://registry.hub.docker.com/_/elasticsearch):

  • 2 узла мастера/данных
  • 1 клиент node (как всегда с кем-либо подключиться)

Затем я запускаю небольшое приложение-загрузчик, которое вставляет 500 000 документов по 1 КБ каждый.

Это занимает около 1 минуты с половиной на моей машине. За это время я перезапускаю текущий мастер node (перезагрузка докера).

В конце прогона Java API ответил OK на 100% моих запросов, но когда я проверяю количество документов с запросом на завивки, осталось несколько документов (где-то между 2 и 10 в зависимости от пробегов я сделал)

Даже с явным запросом "_refresh" в индексе, мой счетчик документов тот же.

Моя основная забота, конечно, заключается не в том, что некоторые документы не могут быть сохранены во время сбоя, а скорее в положительном результате, возвращаемом API (тем более, что я тестирую с помощью WriteConsistencyLevel.ALL).

Я знаю этот билет, но не уверен, применим ли он к моему основному сценарию

Мои вставки выполняются следующим образом:

client.prepareUpdate("test", "test", id)
      .setDoc(doc).setUpsert(doc)
      .setConsistencyLevel(WriteConsistencyLevel.ALL)
      .execute.get.isCreated == true

Остальную часть кода можно найти здесь: https://github.com/joune/nosql/blob/master/src/main/scala/ap.test.nosql/Loader.scala

Пожалуйста, сообщите, если вы думаете, что я делаю что-то явно неправильно.

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


Обновить Дополнительные журналы по просьбе Андрея Стефана

> grep discovery.zen.minimum_master_nodes elasticsearch.yml
discovery.zen.minimum_master_nodes: 2

> curl -XPUT 'http://localhost:9200/_cluster/settings' -d '{"transient":{"logger._root":"DEBUG"}}'
{"acknowledged":true,"persistent":{},"transient":{"logger":{"_root":"DEBUG"}}}%
> curl -XPUT 'http://localhost:9200/_cluster/settings' -d '{"transient": {"logger.index.translog":"TRACE"}}'
{"acknowledged":true,"persistent":{},"transient":{"logger":{"index":{"translog":"TRACE"}}}}%

Запустите тест с 200 000 записей:

0 KO | 200000 OK
> curl -XGET 'localhost:9200/test/test/_count?preference=_primary'
{"count":199991,"_shards":{"total":5,"successful":5,"failed":0}}%  

Я разместил журналы здесь: https://gist.github.com/ab1ed844f2038c30e63b

Ответы

Ответ 1

Я знаю этот билет, но не уверен, применим ли он к моему базовому сценарию https://github.com/elastic/elasticsearch/issues/7572

Я сделал рытье, и я получаю это. Причина в том, что во время закрытия node мы закрываем транспортный уровень до того, как отключим службу индексов, а это означает, что текущая операция эффективно разделяется (точно так же, как в случае сетевой проблемы). Очевидно, это нехорошо, и я открыл https://github.com/elastic/elasticsearch/issues/12314 для отслеживания этого.

В качестве побочного примечания - с Elasticsearch 2.0 мы добавили заголовок shard в ответ, указав, сколько черепов было успешным. Это дает вам возможность проверить, действительно ли операция была успешно записана на все осколки и при необходимости повторить попытку. Это пример успешного ответа (запись как первичной, так и реплики).

{
    "_shards" : {
        "total" : 2,
        "failed" : 0,
        "successful" : 2
    },

Наконец, обратите внимание, что сбой в осколке не означает, что # 7572 сыграл определенную роль. Это очень маловероятно. Однако во всех случаях, когда # 7572 действительно произошло, заголовок будет иметь значение!= Успешно.

Ответ 2

Много замечаний в комментариях здесь. Я бы смиренно предположил, что кластер с двумя допустимыми главными узлами не является "высокой доступностью". Статус elasticsearch docs:

Рекомендуется избегать наличия только двух основных подходящих узлов, поскольку кворум из двух равен двум. Следовательно, потеря либо master node приведет к неработоспособному кластеру.

По существу, в кластере с двумя мастерами с discovery.zen.minimum_master_nodes правильно установлен на 2, как только либо node опускается, вы не может быть мастером, и поэтому у вас больше нет кластера. Если для параметра minimum_master_nodes установлено значение 1, у вас будет целый ряд проблем, с которыми можно бороться (split-brain). Мы запускаем 3 мастера для каждого ES-кластера (и, кроме того, запускаем выделенных мастеров). Мне было бы очень интересно узнать, получаете ли вы разные результаты с помощью 3-х основных кластеров.

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