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 не предназначен для запуска производственного процесса, класса с только двумя доступными для мастера узлами.