API разделения индекса
Разделяет существующий индекс на новый индекс с большим количеством первичных фрагментов.
POST /my-index-000001/_split/split-my-index-000001
{
"settings": {
"index.number_of_shards": 2
}
} Запрос
POST /<index>/_split/<target-index>
PUT /<index>/_split/<target-index>
Предварительные условия
- Если включены функции безопасности Elasticsearch, у вас должна быть
manageпривилегия индекса для индекса. -
Перед тем, как можно будет разделить индекс:
- Индекс должен быть только для чтения.
- Статус кластера должен быть зеленым.
Вы можете сделать индекс только для чтения с помощью следующего запроса:
PUT /my_source_index/_settings
{
"settings": {
"index.blocks.write": true
}
} | Препятствует операциям записи в этот индекс, но позволяет изменениям метаданных, таким как удаление индекса. |
Текущий индекс записи в потоке данных разделить нельзя. Для разделения текущего индекса записи поток данных сначала необходимо переключить, чтобы создать новый индекс записи, а затем можно разделить предыдущий индекс записи.
Описание
API split index позволяет разделить существующий индекс на новый индекс, где каждый исходный первичный фрагмент делится на два или более первичных фрагментов в новом индексе.
Количество раз, которое можно разделить индекс (и количество фрагментов, на которые можно разделить каждый исходный фрагмент), определяется параметром index.number_of_routing_shards. Количество фрагментов маршрутизации определяет пространство хеширования, которое используется внутри для распределения документов по фрагментам с помощью консистентного хеширования. Например, индекс из 5 фрагментов с параметром number_of_routing_shards, установленным на значение 30 (5 x 2 x 3), можно разделить на множитель 2 или 3. Другими словами, его можно разделить следующим образом:
-
5→10→30(разделить на 2, затем на 3) -
5→15→30(разделить на 3, затем на 2) -
5→30(разделить на 6)
index.number_of_routing_shards — это статическое свойство индекса. Вы можете установить index.number_of_routing_shards только при создании индекса или для закрытого индекса.
Пример создания индекса
Следующий API создания индекса создает индекс my-index-000001 с параметром index.number_of_routing_shards, установленным на значение 30.
PUT /my-index-000001
{
"settings": {
"index": {
"number_of_routing_shards": 30
}
}
} Значение параметра index.number_of_routing_shards по умолчанию зависит от количества первичных фрагментов в исходном индексе. Значение по умолчанию разработано, чтобы позволить вам разделить на множители 2 до максимального значения в 1024 фрагмента. Однако необходимо учитывать исходное количество первичных фрагментов. Например, индекс, созданный с 5 первичными фрагментами, может быть разделен на 10, 20, 40, 80, 160, 320 или максимальное значение 640 фрагментов (с одним действием разделения или несколькими действиями разделения).
Если исходный индекс содержит один первичный фрагмент (или многофрагментный индекс был сжатый до одного первичного фрагмента), то индекс может быть разделен на любое количество фрагментов, большее 1. Свойства значения по умолчанию для количества фрагментов маршрутизации затем будут применяться к новому разделенному индексу.
Как работает разделение
Операция разделения:
- Создает новый целевой индекс с тем же определением, что и исходный индекс, но с большим количеством первичных фрагментов.
- Создает жёсткие ссылки на сегменты из исходного индекса в целевой индекс. (Если файловая система не поддерживает жёсткие ссылки, все сегменты копируются в новый индекс, что является гораздо более длительным процессом).
- Пересчитывает хеши всех документов после создания файлов низкого уровня, чтобы удалить документы, которые принадлежат другому фрагменту.
- Восстанавливает целевой индекс, как будто он был закрытым индексом, который только что был повторно открыт.
Почему Elasticsearch не поддерживает инкрементное перераспределение фрагментов?
Переход с N фрагментов на N+1 фрагментов, т.е. инкрементное перераспределение фрагментов, действительно поддерживается многими хранилищами значений. Добавление нового фрагмента и перенос новых данных только в этот новый фрагмент не является вариантом: это, скорее всего, станет узким местом индексирования, и определение того, к какому фрагменту принадлежит документ, учитывая его _id, что необходимо для запросов get, delete и update, станет довольно сложной задачей. Это означает, что нам необходимо перебалансировать существующие данные с использованием другой схемы хеширования.
Наиболее распространенный способ эффективного выполнения этого в хранилищах значений — использование консистентного хеширования. Консистентное хеширование требует только 1/N-й части ключей для перемещения при увеличении количества фрагментов с N до N+1. Однако единицей хранения Elasticsearch являются фрагменты — индексы Lucene. Из-за их ориентированной на поиск структуры данных, взятие значительной части индекса Lucene, будь то только 5% документов, удаление их и индексирование их на другом фрагменте, как правило, сопряжено с гораздо большими затратами, чем в случае хранилища значений. Эти затраты остаются приемлемыми при увеличении количества фрагментов в кратном значении, как описано в предыдущем разделе: это позволяет Elasticsearch выполнять разделение локально, что, в свою очередь, позволяет выполнять разделение на уровне индекса, а не переиндексировать документы, которые нужно переместить, а также использовать жесткие ссылки для эффективного копирования файлов.
В случае данных только для добавления можно получить больше гибкости, создав новый индекс и перенеся в него новые данные, добавив псевдоним, охватывающий как старый, так и новый индекс для операций чтения. Предполагая, что у старого и нового индексов соответственно M и N фрагментов, это не имеет накладных расходов по сравнению с поиском в индексе, у которого было бы M+N фрагментов.
Разделение индекса
Чтобы разделить my_source_index на новый индекс с именем my_target_index, выполните следующий запрос:
POST /my_source_index/_split/my_target_index
{
"settings": {
"index.number_of_shards": 2
}
} Вышеуказанный запрос возвращает результат немедленно, как только целевой индекс добавлен в состояние кластера — он не ожидает начала операции разделения.
Индексы можно разделить только в том случае, если они удовлетворяют следующим требованиям:
- Целевой индекс не должен существовать
- Исходный индекс должен иметь меньше первичных фрагментов, чем целевой индекс.
- Количество первичных фрагментов в целевом индексе должно быть кратно количеству первичных фрагментов в исходном индексе.
- Узел, обрабатывающий процесс разделения, должен иметь достаточно свободного места на диске для размещения второй копии существующего индекса.
API _split аналогичен create index API и принимает параметры settings и aliases для целевого индекса:
POST /my_source_index/_split/my_target_index
{
"settings": {
"index.number_of_shards": 5
},
"aliases": {
"my_search_indices": {}
}
} | Количество фрагментов в целевом индексе. Оно должно быть кратно количеству фрагментов в исходном индексе. |
Карты не могут быть указаны в запросе _split.
Отслеживание процесса разделения
Процесс разделения можно отслеживать с помощью _cat recovery API, или можно использовать cluster health API для ожидания, пока все первичные фрагменты не будут распределены, установив параметр wait_for_status в значение yellow.
_split API возвращает результат, как только целевой индекс добавлен в состояние кластера, прежде чем какие-либо фрагменты будут распределены. В этот момент все фрагменты находятся в состоянии unassigned. Если по какой-либо причине целевой индекс не может быть распределен, его первичный фрагмент останется в состоянии unassigned до тех пор, пока его не удастся распределить на этом узле.
После того как первичный фрагмент будет распределен, он переходит в состояние initializing, и начинается процесс разделения. Когда операция разделения завершается, фрагмент становится active. В этот момент Elasticsearch попытается распределить любые реплики и может принять решение о перемещении первичного фрагмента на другой узел.
Ожидание активных фрагментов
Поскольку операция разделения создает новый индекс для разделения фрагментов, параметр ожидание активных фрагментов при создании индекса также применяется к операции разделения индекса.
Параметры пути
-
<index> - (Обязательно, строка) Название исходного индекса для разделения.
-
<target-index> -
(Обязательно, строка) Название целевого индекса для создания.
Имена индексов должны соответствовать следующим критериям:
- Только строчные буквы
- Не может содержать
\,/,*,?,",<,>,|, пробел,,,# - Индексы до версии 7.0 могли содержать двоеточие (
:), но это устарело и не будет поддерживаться в 7.0+ - Не может начинаться с
-,_,+ - Не может быть
.или.. - Не может быть длиннее 255 байт (обратите внимание, что это байты, поэтому символы с несколькими байтами быстрее достигнут предела в 255)
- Имена, начинающиеся с
., устарели, за исключением скрытых индексов и внутренних индексов, управляемых плагинами скрытых индексов
Параметры запроса
-
wait_for_active_shards -
(Необязательно, строка) Количество копий фрагментов, которые должны быть активны перед выполнением операции. Установите значение
allили любое положительное целое число до общего количества фрагментов в индексе (number_of_replicas+1). По умолчанию: 1, основной фрагмент.См. Активные фрагменты.
-
master_timeout - (Необязательно, единицы времени) Время ожидания подключения к мастер-узлу. Если ответ не получен до истечения срока ожидания, запрос завершается ошибкой. По умолчанию:
30s. -
timeout - (Необязательно, единицы времени) Время ожидания ответа. Если ответ не получен до истечения срока ожидания, запрос завершается ошибкой. По умолчанию:
30s.
Тело запроса
-
aliases -
(Необязательно, объект объектов) Псевдонимы для результирующего индекса.
Свойства объектов
aliases-
<alias> -
(Обязательно, объект) Ключ — имя псевдонима. Имена псевдонимов индексов поддерживают поддержку date math.
Тело объекта содержит параметры для псевдонима. Поддерживается пустой объект.
Свойства
<alias>-
filter - (Необязательно, объект Query DSL) Запрос, используемый для ограничения документов, к которым может получить доступ псевдоним.
-
index_routing - (Необязательно, строка) Значение, используемое для маршрутизации операций индексирования к определенному фрагменту. Если указано, это значение переопределяет значение
routingдля операций индексирования. -
is_hidden - (Необязательно, Булево) Если
true, псевдоним является скрытым. По умолчанию:false. Все индексы для псевдонима должны иметь одинаковое значениеis_hidden. -
is_write_index - (Необязательно, Булево) Если
true, индекс является индексом записи для псевдонима. По умолчанию:false. -
routing - (Необязательно, строка) Значение, используемое для маршрутизации операций индексирования и поиска к определенному фрагменту.
-
search_routing - (Необязательно, строка) Значение, используемое для маршрутизации операций поиска к определенному фрагменту. Если указано, это значение переопределяет значение
routingдля операций поиска.
-
-
-
settings - (Необязательно, объект настроек индекса) Параметры конфигурации для целевого индекса. См. Настройки индекса.
© 2023-2025 Elasticsearch
As of September 2024, Elasticsearch is available under a choice of three licenses: the Server Side Public License (SSPL), the Elastic License, or the AGPLv3 (OSI approved).
Elasticsearch and the Elasticsearch logo are trademarks of Elasticsearch B.V., registered in the U.S. and in other countries.
https://www.elastic.co/guide/en/elasticsearch/reference/7.17/indices-split-index.html