Статус кластера: красный или жёлтый
Статус кластера «красный» или «жёлтый» указывает на то, что один или несколько фрагментов не назначены узлу.
- Красный статус: в кластере есть неназначенные первичные фрагменты, что означает, что некоторые операции, такие как поиск и индексирование, могут завершиться ошибкой.
- Жёлтый статус: в кластере нет неназначенных первичных фрагментов, но есть неназначенные фрагменты-копии. Это повышает риск потери данных и может ухудшить производительность кластера.
Когда в вашем кластере статус «красный» или «жёлтый», он будет продолжать обрабатывать поисковые запросы и индексирование, где это возможно, но может отложить определённые управляющие и очистительные действия до тех пор, пока статус кластера не станет зелёным. Например, некоторые действия ILM требуют, чтобы индекс, над которым они выполняются, имел зелёный статус.
Во многих случаях ваш кластер восстановит зелёный статус автоматически. Если кластер не восстанавливается автоматически, вам необходимо руководственно устранить оставшиеся проблемы, чтобы управляющие и очистительные действия могли продолжиться. См. это видео для ознакомления с процессом мониторинга состояния распределения.
Диагностика состояния кластера
Проверка состояния кластера
Используйте API состояния кластера.
resp = client.cluster.health(
filter_path="status,*_shards",
)
print(resp) response = client.cluster.health( filter_path: 'status,*_shards' ) puts response
const response = await client.cluster.health({
filter_path: "status,*_shards",
});
console.log(response); GET _cluster/health?filter_path=status,*_shards
Здоровый кластер имеет зелёный status и ноль unassigned_shards. Жёлтый статус означает, что не назначены только фрагменты-копии. Красный статус означает, что один или несколько первичных фрагментов не назначены.
Просмотр неназначенных фрагментов
Для просмотра неназначенных фрагментов используйте API cat shards.
resp = client.cat.shards(
v=True,
h="index,shard,prirep,state,node,unassigned.reason",
s="state",
)
print(resp) response = client.cat.shards( v: true, h: 'index,shard,prirep,state,node,unassigned.reason', s: 'state' ) puts response
const response = await client.cat.shards({
v: "true",
h: "index,shard,prirep,state,node,unassigned.reason",
s: "state",
});
console.log(response); GET _cat/shards?v=true&h=index,shard,prirep,state,node,unassigned.reason&s=state
У неназначенных фрагментов есть state состояния UNASSIGNED. Значение prirep равно p для первичных фрагментов и r для фрагментов-копий.
Чтобы понять, почему неназначенный фрагмент не назначается и какие действия необходимо предпринять, чтобы позволить Elasticsearch назначить его, используйте API объяснения распределения кластера.
resp = client.cluster.allocation_explain(
filter_path="index,node_allocation_decisions.node_name,node_allocation_decisions.deciders.*",
index="my-index",
shard=0,
primary=False,
)
print(resp) response = client.cluster.allocation_explain(
filter_path: 'index,node_allocation_decisions.node_name,node_allocation_decisions.deciders.*',
body: {
index: 'my-index',
shard: 0,
primary: false
}
)
puts response const response = await client.cluster.allocationExplain({
filter_path:
"index,node_allocation_decisions.node_name,node_allocation_decisions.deciders.*",
index: "my-index",
shard: 0,
primary: false,
});
console.log(response); GET _cluster/allocation/explain?filter_path=index,node_allocation_decisions.node_name,node_allocation_decisions.deciders.*
{
"index": "my-index",
"shard": 0,
"primary": false
} Решение проблемы с красным или жёлтым статусом кластера
Фрагмент может стать неназначенным по нескольким причинам. В следующих советах описаны наиболее распространённые причины и их решения.
Кластер из одного узла
Elasticsearch никогда не назначит копию фрагмента тому же узлу, что и первичный фрагмент. Кластер из одного узла всегда будет иметь жёлтый статус. Чтобы изменить статус на зелёный, установите number_of_replicas в 0 для всех индексов.
Следовательно, если количество копий равно или превышает количество узлов, некоторые фрагменты не будут распределены.
Восстановление потерянных узлов
Фрагменты часто становятся неназначенными, когда узел данных покидает кластер. Это может произойти по нескольким причинам:
- Перезапуск узла вручную приведёт к временному нездоровому состоянию кластера до тех пор, пока узел не восстановится.
- Когда узел перегружается или выходит из строя, это может временно нарушить состояние здоровья кластера, что приведёт к нездоровому состоянию. Длительные паузы при сборе мусора (GC), вызванные ошибками недостатка памяти или высоким использованием памяти во время интенсивных поисков, могут вызвать это состояние. См. снижение нагрузки на JVM-память для решения проблем, связанных с JVM.
- Проблемы с сетью могут препятствовать надёжной связи узлов, что приведёт к тому, что фрагменты перестанут синхронизироваться. Проверьте журналы на наличие повторяющихся сообщений о выходе и возвращении узлов в кластер.
После решения проблемы и восстановления узла он присоединится к кластеру. После этого Elasticsearch автоматически распределит все неназначенные фрагменты.
Вы можете отслеживать этот процесс, проверяя состояние вашего кластера. Количество нераспределённых фрагментов должно постепенно уменьшаться до тех пор, пока не будет достигнут зелёный статус.
Чтобы избежать потерь ресурсов на временные проблемы, Elasticsearch откладывает распределение по умолчанию на одну минуту. Если вы восстановили узел и не хотите ждать периода отложенного распределения, вы можете вызвать API перенаправления кластера без аргументов, чтобы запустить процесс распределения. Этот процесс выполняется асинхронно в фоновом режиме.
response = client.cluster.reroute( metric: 'none' ) puts response
POST _cluster/reroute?metric=none
Решение проблем с настройками распределения
Неправильно настроенные параметры распределения могут привести к тому, что первичный фрагмент не будет назначен. К таким параметрам относятся:
- Параметры распределения фрагментов уровня индекса .
- Фильтр распределения фрагментов для настроек кластера.
- Осведомлённость о распределении фрагментов для настроек кластера.
Чтобы проверить настройки распределения, используйте получение настроек индекса и получение настроек кластера.
resp = client.indices.get_settings(
index="my-index",
flat_settings=True,
include_defaults=True,
)
print(resp)
resp1 = client.cluster.get_settings(
flat_settings=True,
include_defaults=True,
)
print(resp1) response = client.indices.get_settings( index: 'my-index', flat_settings: true, include_defaults: true ) puts response response = client.cluster.get_settings( flat_settings: true, include_defaults: true ) puts response
const response = await client.indices.getSettings({
index: "my-index",
flat_settings: "true",
include_defaults: "true",
});
console.log(response);
const response1 = await client.cluster.getSettings({
flat_settings: "true",
include_defaults: "true",
});
console.log(response1); GET my-index/_settings?flat_settings=true&include_defaults=true GET _cluster/settings?flat_settings=true&include_defaults=true
Вы можете изменить настройки, используя обновление настроек индекса и обновление настроек кластера.
Распределение или сокращение копий
Для защиты от сбоя оборудования Elasticsearch не будет назначать копию фрагмента тому же узлу, что и первичный фрагмент. Если других узлов данных нет для размещения копии, она остаётся неназначенной. Для решения этой проблемы вы можете:
- Добавить узел данных в тот же уровень для размещения копии.
- Изменить
index.number_of_replicasнастройку индекса для уменьшения количества копий для каждого первичного фрагмента. Рекомендуется поддерживать как минимум одну копию на каждый первичный фрагмент для высокой доступности.
resp = client.indices.put_settings(
settings={
"index.number_of_replicas": 1
},
)
print(resp) response = client.indices.put_settings(
body: {
'index.number_of_replicas' => 1
}
)
puts response const response = await client.indices.putSettings({
settings: {
"index.number_of_replicas": 1,
},
});
console.log(response); PUT _settings
{
"index.number_of_replicas": 1
} Освобождение или увеличение дискового пространства
Elasticsearch использует нижний порог заполнения диска для обеспечения того, чтобы узлы данных имели достаточно дискового пространства для входящих фрагментов. По умолчанию Elasticsearch не распределяет фрагменты на узлы с более чем 85% заполненностью дискового пространства.
Чтобы проверить текущее дисковое пространство ваших узлов, используйте API cat allocation.
resp = client.cat.allocation(
v=True,
h="node,shards,disk.*",
)
print(resp) response = client.cat.allocation( v: true, h: 'node,shards,disk.*' ) puts response
const response = await client.cat.allocation({
v: "true",
h: "node,shards,disk.*",
});
console.log(response); GET _cat/allocation?v=true&h=node,shards,disk.*
Если на ваших узлах низкий уровень свободного дискового пространства, у вас есть несколько вариантов:
- Увеличьте объём дискового пространства узлов.
- Добавьте больше узлов в кластер.
- Удалите ненужные индексы, чтобы освободить место. Если вы используете ILM, вы можете обновить политику жизненного цикла, чтобы использовать поисковые снимки, или добавить фазу удаления. Если вам больше не нужно искать данные, вы можете использовать снимок, чтобы сохранить их вне кластера.
-
Если вы больше не записываете в индекс, используйте API слияния фрагментов или действие слияния фрагментов ILM, чтобы объединить его фрагменты в более крупные.
resp = client.indices.forcemerge( index="my-index", ) print(resp)response = client.indices.forcemerge( index: 'my-index' ) puts response
const response = await client.indices.forcemerge({ index: "my-index", }); console.log(response);POST my-index/_forcemerge
-
Если индекс является только для чтения, используйте API уменьшения индекса или действие уменьшения ILM, чтобы уменьшить количество первичных фрагментов.
resp = client.indices.shrink( index="my-index", target="my-shrunken-index", ) print(resp)response = client.indices.shrink( index: 'my-index', target: 'my-shrunken-index' ) puts response
const response = await client.indices.shrink({ index: "my-index", target: "my-shrunken-index", }); console.log(response);POST my-index/_shrink/my-shrunken-index
-
Если ваш узел имеет большой объём диска, вы можете увеличить нижний порог дискового пространства или установить его в явное значение в байтах.
resp = client.cluster.put_settings( persistent={ "cluster.routing.allocation.disk.watermark.low": "90%", "cluster.routing.allocation.disk.watermark.high": "95%" }, ) print(resp)const response = await client.cluster.putSettings({ persistent: { "cluster.routing.allocation.disk.watermark.low": "90%", "cluster.routing.allocation.disk.watermark.high": "95%", }, }); console.log(response);PUT _cluster/settings { "persistent": { "cluster.routing.allocation.disk.watermark.low": "90%", "cluster.routing.allocation.disk.watermark.high": "95%" } }
Это обычно временное решение и может вызвать нестабильность, если дисковое пространство не будет освобождено.
Возобновить выделение фрагментов
Вы обычно отключаете выделение во время перезапуска или других операций по обслуживанию кластера. Если вы забыли после этого возобновить выделение, Elasticsearch не сможет назначить фрагменты. Чтобы возобновить выделение, сбросьте значение настройки кластера cluster.routing.allocation.enable.
resp = client.cluster.put_settings(
persistent={
"cluster.routing.allocation.enable": None
},
)
print(resp) response = client.cluster.put_settings(
body: {
persistent: {
'cluster.routing.allocation.enable' => nil
}
}
)
puts response const response = await client.cluster.putSettings({
persistent: {
"cluster.routing.allocation.enable": null,
},
});
console.log(response); PUT _cluster/settings
{
"persistent" : {
"cluster.routing.allocation.enable" : null
}
} Посмотрите это видео для пошагового руководства по устранению неполадок с сообщением "no allocations are allowed".
Снизить нагрузку на память JVM
Выделение фрагментов требует памяти кучи JVM. Высокая нагрузка на память JVM может активировать разрывы цепи, которые останавливают выделение и оставляют фрагменты без назначения. См. Высокая нагрузка на память JVM.
Восстановление данных для потерянного первичного фрагмента
Если узел с первичным фрагментом потерян, Elasticsearch обычно может заменить его с помощью реплики на другом узле. Если вы не можете восстановить узел, и реплики отсутствуют или не подлежат восстановлению, Allocation Explain сообщит no_valid_shard_copy, и вам нужно будет сделать одно из следующего:
- восстановить отсутствующие данные из снимка
- индексировать отсутствующие данные из исходного источника данных
- принять потерю данных на уровне индекса, выполнив Удаление индекса
-
принять потерю данных на уровне фрагмента, выполнив Cluster Reroute команду allocate_stale_primary или allocate_empty_primary с
accept_data_loss: trueИспользуйте этот вариант только если восстановление узла более невозможно. Этот процесс выделяет пустой первичный фрагмент. Если узел позже присоединится к кластеру, Elasticsearch перезапишет его первичный фрагмент данными из этого более нового пустого фрагмента, что приведёт к потере данных.
POST _cluster/reroute?metric=none { "commands": [ { "allocate_empty_primary": { "index": "my-index", "shard": 0, "node": "my-node", "accept_data_loss": "true" } } ] }
См. это видео для пошагового руководства по устранению неполадок no_valid_shard_copy.
© 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/8.17/red-yellow-cluster-status.html