Elasticsearch Oversharding - это состояние, указывающее на то, что у вас слишком много шардов, и поэтому они слишком малы. Хотя минимального предела для размера шарда Elastic не существует, наличие большего количества шардов на кластере Elasticsearch требует дополнительных ресурсов, поскольку кластеру необходимо поддерживать метаданные о состоянии всех шардов в кластере.
Хотя абсолютного предела не существует, в качестве ориентира можно считать, что идеальный размер шарда составляет от нескольких ГБ до нескольких десятков ГБ. Более подробно о масштабируемости можно узнать из этого официального руководства.
Как решить проблему
Если ваши шарды слишком малы, то у вас есть 3 варианта:
Удалить пустые индексы
Хотя пустые индексы не занимают места на диске, Elasticsearch все равно должен хранить в памяти расположение и маппинг шардов, поэтому рекомендуется регулярно обнаруживать и удалять пустые индексы на кластере Elasticsearch. Для этого можно использовать сценарий:
1 | GET _cat/indices?h=index,creation.date,docs.count,health&format=json |
В результате будет получен список индексов в формате JSON, который можно использовать для проверки размера, возраста и использования, чтобы удалить пустые индексы.
Удаление или закрытие индексов со старыми или ненужными данными
1 2 | DELETE myindex-2020* POST myindex-2020*/_close |
Закрытие определенных индексов часто является хорошим вариантом быстрого восстановления работы кластера, пока вы решаете, какое решение лучше выбрать в долгосрочной перспективе. Закрытие индекса освобождает ресурсы памяти, используемые индексом, при этом индекс остается на диске, и легко и быстро обратимо (POST myindex/_open).
Переиндексация в более крупные индексы
Ниже приводится переиндексация нескольких ежедневных или ежемесячных индексов в один индекс за год (убедитесь, что вы не создадите обратную проблему слишком большого размера шардов, настроив количество шардов в новом индексе в соответствии с общим объемом данных. Убедитесь, что размер шардов в новом индексе не превышает 50 ГБ/шард).
1 2 3 4 5 6 7 8 9 10 | POST _reindex { "source": { "index": "logs-2020*" }, "dest": { "index": "logs-2020" } } |
Примечания, которые следует иметь в виду
Осторожно, взрывы полей и маппинги
При объединении малых индексов в один большой индекс следует помнить, что маппинг или новый индекс будет содержать все поля из всех составляющих индексов. Поэтому необходимо убедиться, что объединяемые индексы имеют в основном одинаковые маппинги.
Следите за дублированием данных в процессе переиндексации
Если в процессе переиндексации (см. наши советы по переиндексации) в имени индекса используются подстановочные знаки (например, logs-*), то результаты могут дублироваться, поскольку до завершения процесса у вас будет две копии данных. Этого можно избежать, используя псевдонимы.
Следите за модификациями и обновлениями в процессе переиндексации
Если данные подвержены обновлениям в процессе переиндексации, то необходимо определить процедуру их учета и гарантировать, что в новых индексах будут отражены все изменения, внесенные в течение переходного периода переиндексации.
1 2 3 4 5 6 7 8 9 10 | PUT _cluster/settings { "transient": { "cluster.routing.allocation.disk.watermark.low": "85%", "cluster.routing.allocation.disk.watermark.high": "90%", "cluster.routing.allocation.disk.watermark.flood_stage": "95%", "cluster.info.update.interval": "1m" } } |
Как избежать этой проблемы
Существуют различные механизмы оптимизации размера шардов, например:
Применить ILM (управление жизненным циклом индекса).
С помощью ILM можно заставить Elasticsearch автоматически создавать новый индекс, когда текущий размер индекса достигает заданного максимального размера или возраста. ILM подходит для документов, не требующих обновлений, но не подходит для документов, требующих частого обновления, поскольку для этого необходимо знать, какой из предыдущих томов индекса содержит документ, который необходимо обновить.
Изменение стратегии работы приложения
Вы можете спроектировать приложение таким образом, чтобы обеспечить создание шардов разумного размера:
Подход, основанный на дате
myindex-yyyy.MM.dd
или myindex-yyy.MM
Если вы страдаете от переизбытка хранилищ, то вам, скорее всего, придется перейти от ежедневных индексов к ежемесячным или годовым.
Подход, основанный на атрибутах
myindex-<clientID>
Преимущество этого подхода заключается в том, что, зная идентификатор клиента, вы можете точно знать, какой индекс следует искать/обновлять.
Недостатком является то, что разные клиенты могут производить разные объемы документов (и, соответственно, разные размеры шардов). Это можно в некоторой степени компенсировать, регулируя количество шардов для каждого клиента, но при большом количестве клиентов может возникнуть обратная проблема (избыточное количество шардов).
Подход на основе диапазона идентификаторов
Это возможно, если документы имеют идентификатор, полученный из другой системы или приложения (например, sql-идентификатор или идентификатор клиента), что позволяет равномерно распределять документы.
Например, myindex-<последний_цифровой_идентификатор_ID>
В результате мы получим 10 индексов, которые, вероятно, будут равномерно распределены, а также детерминированы (мы знаем, какой индекс нам нужно обновить).