Recovery, шарды в состоянии INITIALIZING

Коллеги добрый день!
Столкнулся с проблемой следующего характера:

Есть кластер состоящий из 3 узлов, 1 мастер (8x CPU, 16Gb Head, 32Gb RAM) и 2 дата ноды (8x CPU, 31Gb Heap, 64Gb RAM)
На каждой из дата нод по 2500 индексов и по (>10 тыс. шардов), данных около 1.2 Тб, около 5 млрд. документов. Диски по 1 Тб выделены на каждую ноду. "Да это плохо, архитектуру уже меняю."

Индексы имеют два primary shard и одну реплику. Случилось следующее:

Перезагрузилась ВМ со второй дата нодой, не беда, у нас кластер продолжает работать (yellow state). Нода успешно поднялась и начался процесс восстановления данных, прошло 15 часов и кластер до сих пор в состоянии yellow. Новые шарды перестали аллоцироваться
_cluster/health
https://pastebin.com/S3grQTNq

_cluster/settings
https://pastebin.com/aqiXfgqN

allocation/explain
https://pastebin.com/7WrfywcE

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

Решил поэксперементировать и пришел к выводу, что elasticsearch не может восстановить сразу такое огромное количество шардов на одной ноде, так как когда я закрыл все индексы и решил восстановить 1000 индексов (3000 шардов), восстановление опять дошло до active_shards_percent_as_number 48-50%, кластер в состоянии yellow, новые шарды не аллоцировались.

Тогда я решил небольшими пачками восстановить 1000 индексов, по 10 штук примерно, и вуаааля, все восстановилось успешно.

Отсюда вопрос, почему так? я уперся в потолок?
Я понимаю, что при таком количество шардов на одной ноде может возникнуть всё что угодно, но хотя бы в логах что-нибудь должно же быть написано. Потому что я ничего критичного не увидел. Заранее спасибо!

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

Судя по allocation/explain для первой шарды она уперлась в лимит на количество одновременных восстановлений:

"deciders": [
        {
          "decider": "throttling",
          "decision": "THROTTLE",
          "explanation": "reached the limit of incoming shard recoveries [505], cluster setting [cluster.routing.allocation.node_concurrent_incoming_recoveries=500] (can also be set via [cluster.routing.allocation.node_concurrent_recoveries])"
        }

Вы пытались улучшить этот процесс, увеличением числа одновременных восстановлений до 500, но вместо этого вы все затормозили создав толпу из 500 одновременных восстановлений, которые ломанулись через вашу сеть и столкнулись с ограниченными возможностями одного диска на чтение и запись и внутренних систем. 500 - это слишком много. Надо было оставить около 20 или даже 10 и посмотреть что там происходить, что вы и сделали в ручную. Того же результата можно было добиться уменьшив concurrent_recoveries до 10.

Копировать 500 файлов одновременно с одного диска на другой не имеет никакого смысла. Оно только замедляет копирование каждой индивидуальной шарды и производит впечатление, что все застряло. Если у вас диска на второй ноде HDD то все эти файлы - просто борются за управление головкой диска и все замедляется для всех.

Отсюда вопрос, почему так? я уперся в потолок?

Все перечисленное выше должно было все затормозить. Однако, если все совсем встало, то скорее всего вы столкнулись с этим багом. Если количество одновременных восстановлений превышает размер пула потоков GENERIC то это может вызвать взаимною блокировку потоков восстановления. В вашем случае, размер этого пула - 4*8СPUs = 32. То есть, в вашей системе установка одновременных восстановление больше 32 может привести к проблемам.

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

Игорь, спасибо за ссылку на баг, установил настройки пула как Вы рекомендовали и все восстановилось без проблем (удалил репилики на всех индексах и заново их добавил). Диски были SSD, в пике восстановления достигали 1.500 mb\sec.

От себя хочется добавить коллегам, кто сталкивается с подобными проблемами: обращайте внимание на правильную архитектуру индексов и mapping в ElasticSearch, это поможет избавиться от большинства проблем.

This topic was automatically closed 28 days after the last reply. New replies are no longer allowed.