Spec-Zone.ru › Elasticsearch 8
›Elasticsearch Руководство [8.17] ›Устранение неполадок ›Решение распространенных проблем кластера

Высокая концентрация нагрузок

Возможна горячая точка в Elasticsearch, когда использование ресурсов распределено неравномерно между узлами. Временные пики обычно не считаются проблематичными, но постоянное существенно отличное использование может привести к узким местам кластера и должно быть проанализировано.

См. это видео для пошагового решения проблемы горячих точек.

Если вы используете Elastic Cloud Hosted, то можете использовать AutoOps для мониторинга вашего кластера. AutoOps значительно упрощает управление кластером с рекомендациями по производительности, видимостью использования ресурсов, обнаружением проблем в режиме реального времени и путями решения. Для получения дополнительной информации обратитесь к Мониторинг с помощью AutoOps.

Обнаружение горячих точек

Горячие точки чаще всего проявляются как существенно повышенное использование ресурсов (disk.percent, heap.percent или cpu) у подмножества узлов, как сообщается через cat nodes. Отдельные пики не обязательно являются проблематичными, но если использование неоднократно пикирует или постоянно остается высоким со временем (например, дольше 30 секунд), ресурс может испытывать проблематичные горячие точки.

Например, давайте рассмотрим два отдельных вероятных случая, используя cat nodes:

resp = client.cat.nodes(
    v=True,
    s="master,name",
    h="name,master,node.role,heap.percent,disk.used_percent,cpu",
)
print(resp)
response = client.cat.nodes(
  v: true,
  s: 'master,name',
  h: 'name,master,node.role,heap.percent,disk.used_percent,cpu'
)
puts response
const response = await client.cat.nodes({
  v: "true",
  s: "master,name",
  h: "name,master,node.role,heap.percent,disk.used_percent,cpu",
});
console.log(response);
GET _cat/nodes?v&s=master,name&h=name,master,node.role,heap.percent,disk.used_percent,cpu

Предположим, этот же вывод был получен дважды в течение пяти минут:

name   master node.role heap.percent disk.used_percent cpu
node_1 *      hirstm              24                20  95
node_2 -      hirstm              23                18  18
node_3 -      hirstmv             25                90  10

Здесь мы видим два существенно отличных использования: где мастер-узел находится на уровне cpu: 95, а узел с горячей точкой находится на уровне disk.used_percent: 90%. Это указывает на то, что горячие точки возникали на этих двух узлах, и не обязательно от одного и того же корневого причины.

Причины

Исторически кластеры испытывают горячие точки в основном в результате аппаратного обеспечения, распределения фрагментов и/или нагрузки задач. Мы рассмотрим их последовательно в порядке потенциального влияния на масштаб.

Аппаратное обеспечение

Вот некоторые распространенные неправильные конфигурации оборудования, которые могут способствовать возникновению горячих точек:

  • Ресурсы распределяются неравномерно. Например, если одному узлу с горячей точкой предоставлена половина ЦП по сравнению со своими коллегами. Elasticsearch ожидает, что все узлы на уровне данных будут иметь одинаковые аппаратные профили или спецификации.
  • Ресурсы потребляются другой службой на хосте, включая другие узлы Elasticsearch. Обратитесь к нашему рекомендованию по выделенным хостам.
  • Ресурсы испытывают разную пропускную способность сети или диска. Например, если ввод/вывод одного узла ниже, чем у его коллег. Обратитесь к Использованию более быстрого оборудования для получения дополнительной информации.
  • JVM, настроенный с кучей больше 31 ГБ. Обратитесь к установке размера кучи JVM для получения дополнительной информации.
  • Проблемные ресурсы уникально сообщают о свопировании памяти.

Распределение фрагментов

Индексы Elasticsearch делятся на один или несколько фрагментов, которые иногда могут быть плохо распределены. Elasticsearch учитывает это, балансируя количество фрагментов между узлами данных. Как представлено в версии 8.6, Elasticsearch по умолчанию также включает желаемый баланс для учета нагрузки загрузки. Узел может все еще испытывать горячие точки, либо из-за индексов с интенсивными записями, либо из-за общего количества фрагментов, которые он содержит.

Уровень узла

Вы можете проверить баланс фрагментов с помощью cat allocation, хотя с версии 8.6 желаемый баланс больше не гарантирует полную балансировку фрагментов. Обратите внимание, что оба метода могут временно показывать проблематичный дисбаланс во время проблем стабильности кластера.

Например, давайте покажем два отдельных вероятных случая, используя cat allocation:

resp = client.cat.allocation(
    v=True,
    s="node",
    h="node,shards,disk.percent,disk.indices,disk.used",
)
print(resp)
response = client.cat.allocation(
  v: true,
  s: 'node',
  h: 'node,shards,disk.percent,disk.indices,disk.used'
)
puts response
const response = await client.cat.allocation({
  v: "true",
  s: "node",
  h: "node,shards,disk.percent,disk.indices,disk.used",
});
console.log(response);
GET _cat/allocation?v&s=node&h=node,shards,disk.percent,disk.indices,disk.used

Что может вернуть:

node   shards disk.percent disk.indices disk.used
node_1    446           19      154.8gb   173.1gb
node_2     31           52       44.6gb   372.7gb
node_3    445           43      271.5gb   289.4gb

Здесь мы видим две существенно различные ситуации. node_2 недавно перезагрузился, поэтому у него гораздо меньше фрагментов, чем у всех остальных узлов. Это также связано с тем, что disk.indices намного меньше, чем disk.used, в то время как фрагменты восстанавливаются, как видно из cat recovery. Хотя количество фрагментов в node_2 низкое, он может стать узлом с интенсивными записями из-за текущих циклов ILM. Это распространенная причина интенсивных записей, о которой рассказывается в следующем разделе.

Вторая ситуация заключается в том, что у node_3 больше disk.percent, чем у node_1, даже если они содержат примерно одинаковое количество фрагментов. Это происходит, когда фрагменты не имеют одинакового размера (см. Настраивайте фрагменты от 200 млн документов или с размером от 10 ГБ до 50 ГБ) или когда имеется много пустых индексов.

Перебалансировка кластера на основе желаемого баланса в значительной степени решает проблему предотвращения горячих точек на узлах. Она может быть ограничена либо достижением узлами пороговых значений (см. исправление ошибок пороговых значений диска), либо низким количеством фрагментов индекса с интенсивными записями по сравнению с узлами, на которые записываются.

Вы можете подтвердить узлы с горячими точками с помощью API статистики узлов, возможно, выполнив опрос дважды через некоторое время, чтобы проверить только разницу в статистике между ними, а не выполнить опрос один раз, чтобы получить статистику за весь период работы узла работы узла. Например, чтобы проверить статистику индексирования всех узлов:

resp = client.nodes.stats(
    human=True,
    filter_path="nodes.*.name,nodes.*.indices.indexing",
)
print(resp)
response = client.nodes.stats(
  human: true,
  filter_path: 'nodes.*.name,nodes.*.indices.indexing'
)
puts response
const response = await client.nodes.stats({
  human: "true",
  filter_path: "nodes.*.name,nodes.*.indices.indexing",
});
console.log(response);
GET _nodes/stats?human&filter_path=nodes.*.name,nodes.*.indices.indexing
Уровень индекса

Узлы с горячими точками часто обнаруживаются через cat thread pool за счет write и search очереди резервирования. Например:

resp = client.cat.thread_pool(
    thread_pool_patterns="write,search",
    v=True,
    s="n,nn",
    h="n,nn,q,a,r,c",
)
print(resp)
response = client.cat.thread_pool(
  thread_pool_patterns: 'write,search',
  v: true,
  s: 'n,nn',
  h: 'n,nn,q,a,r,c'
)
puts response
const response = await client.cat.threadPool({
  thread_pool_patterns: "write,search",
  v: "true",
  s: "n,nn",
  h: "n,nn,q,a,r,c",
});
console.log(response);
GET _cat/thread_pool/write,search?v=true&s=n,nn&h=n,nn,q,a,r,c

Что может вернуть:

n      nn       q a r    c
search node_1   3 1 0 1287
search node_2   0 2 0 1159
search node_3   0 1 0 1302
write  node_1 100 3 0 4259
write  node_2   0 4 0  980
write  node_3   1 5 0 8714

Здесь вы можете увидеть две существенно разные ситуации. Во-первых, у node_1 сильно заблокирована очередь записи по сравнению с другими узлами. Во-вторых, у node_3 наблюдаются исторически завершенные записи, которые вдвое превышают количество на других узлах. Вероятнее всего, это вызвано либо неравномерным распределением индексов с высокой скоростью записи, либо назначением нескольких индексов с высокой скоростью записи одному узлу. Поскольку операции записи первичных и реплицируемых фрагментов в значительной степени эквивалентны по объему работы кластера, мы обычно рекомендуем установить index.routing.allocation.total_shards_per_node, чтобы принудительно распределить индексы после выравнивания количества фрагментов индекса с общим количеством узлов.

Мы обычно рекомендуем, чтобы индексы с высокой интенсивностью записи имели достаточное количество первичных number_of_shards и реплицированных number_of_replicas для равномерного распределения между узлами индексирования. В качестве альтернативы, вы можете перенаправить фрагменты на более спокойные узлы, чтобы уменьшить нагрузку на узлы с горячими точками.

Если не очевидно, какие индексы являются проблематичными, вы можете провести более глубокий анализ с помощью API статистики индексов, выполнив:

resp = client.indices.stats(
    level="shards",
    human=True,
    expand_wildcards="all",
    filter_path="indices.*.total.indexing.index_total",
)
print(resp)
response = client.indices.stats(
  level: 'shards',
  human: true,
  expand_wildcards: 'all',
  filter_path: 'indices.*.total.indexing.index_total'
)
puts response
const response = await client.indices.stats({
  level: "shards",
  human: "true",
  expand_wildcards: "all",
  filter_path: "indices.*.total.indexing.index_total",
});
console.log(response);
GET _stats?level=shards&human&expand_wildcards=all&filter_path=indices.*.total.indexing.index_total

Для более продвинутого анализа можно выполнять запросы статистики фрагментов, что позволяет сравнивать совокупные данные по индексам и узлам. Этот анализ не учитывает перезагрузку узлов и/или перенаправление фрагментов, но служит обзором:

resp = client.indices.stats(
    metric="indexing,search",
    level="shards",
    human=True,
    expand_wildcards="all",
)
print(resp)
response = client.indices.stats(
  metric: 'indexing,search',
  level: 'shards',
  human: true,
  expand_wildcards: 'all'
)
puts response
const response = await client.indices.stats({
  metric: "indexing,search",
  level: "shards",
  human: "true",
  expand_wildcards: "all",
});
console.log(response);
GET _stats/indexing,search?level=shards&human&expand_wildcards=all

Например, вы можете использовать инструмент JQ стороннего разработчика для обработки выходных данных, сохраненных как indices_stats.json:

cat indices_stats.json | jq -rc ['.indices|to_entries[]|.key as $i|.value.shards|to_entries[]|.key as $s|.value[]|{node:.routing.node[:4], index:$i, shard:$s, primary:.routing.primary, size:.store.size, total_indexing:.indexing.index_total, time_indexing:.indexing.index_time_in_millis, total_query:.search.query_total, time_query:.search.query_time_in_millis } | .+{ avg_indexing: (if .total_indexing>0 then (.time_indexing/.total_indexing|round) else 0 end), avg_search: (if .total_search>0 then (.time_search/.total_search|round) else 0 end) }'] > shard_stats.json

# show top written-to shard simplified stats which contain their index and node references
cat shard_stats.json | jq -rc 'sort_by(-.avg_indexing)[]' | head

Нагрузки задач

Проблемы с распределением фрагментов, скорее всего, проявятся как нагрузка на задачи, как показано выше в примере cat thread pool. Также возможно, что задачи будут концентрироваться на узле из-за индивидуальной качественной дороговизны или общей количественной нагрузки.

Например, если cat thread pool сообщил о большой очереди в warmer пуле потоков, вам нужно будет найти узлы, которые были затронуты, с помощью горячих потоков. Предположим, он сообщил о warmer потоках в 100% cpu, связанных с GlobalOrdinalsBuilder. Это позволит вам проверить глобальные порядковые номера данных поля .

В качестве альтернативы, предположим, что cat nodes показывает перегруженный мастер-узел, а cat thread pool показывает общую очередь на всех узлах. Это говорит о перегрузке мастер-узла. Для решения этой проблемы сначала необходимо убедиться, что настроен высокая доступность оборудования, а затем попытаться найти временные причины. В этом примере API горячих потоков узлов сообщает о нескольких потоках в other, что указывает на то, что они ожидают или заблокированы из-за сбора мусора или операций ввода-вывода.

В любой из этих ситуаций, хороший способ подтвердить проблемные задачи — просмотреть самые длительные не-непрерывные (определенные [c]) задачи с помощью управления задачами cat. Это можно дополнить, проверив самые длительные задачи синхронизации кластера с помощью cat pending tasks. Используя третий пример,

resp = client.cat.tasks(
    v=True,
    s="time:desc",
    h="type,action,running_time,node,cancellable",
)
print(resp)
response = client.cat.tasks(
  v: true,
  s: 'time:desc',
  h: 'type,action,running_time,node,cancellable'
)
puts response
const response = await client.cat.tasks({
  v: "true",
  s: "time:desc",
  h: "type,action,running_time,node,cancellable",
});
console.log(response);
GET _cat/tasks?v&s=time:desc&h=type,action,running_time,node,cancellable

Это может вернуть:

type   action                running_time  node    cancellable
direct indices:data/read/eql 10m           node_1  true
...

Это выявляет проблемный запрос EQL. Мы можем получить дополнительную информацию об этом с помощью API управления задачами,

resp = client.tasks.list(
    human=True,
    detailed=True,
)
print(resp)
response = client.tasks.list(
  human: true,
  detailed: true
)
puts response
const response = await client.tasks.list({
  human: "true",
  detailed: "true",
});
console.log(response);
GET _tasks?human&detailed

Его ответ содержит description, который сообщает об этом запросе:

indices[winlogbeat-*,logs-window*], sequence by winlog.computer_name with maxspan=1m\n\n[authentication where host.os.type == "windows" and event.action:"logged-in" and\n event.outcome == "success" and process.name == "svchost.exe" ] by winlog.event_data.TargetLogonId

Это позволяет узнать, какие индексы следует проверить (winlogbeat-*,logs-window*), а также тело запроса поиска EQL. Скорее всего, это связано с SIEM.

© 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/hotspotting.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API