Пример диагностики перегруженных шардов

В этой статье рассматривается пример диагностики перегруженных шардов и решения этой проблемы.

Дополнительную информацию о перегруженных шардах и причинах их перегрузки см. в статье Перегруженные таблетки data shard.

Статья начинается с описания возникшей проблемы. Затем мы проанализируем графики в Grafana и информацию на вкладке Diagnostics в Embedded UI, чтобы найти решение, и проверим его эффективность.

В конце статьи приводятся шаги по воспроизведению проблемы.

Описание проблемы

Вас уведомили о задержках при обработке пользовательских запросов в вашей системе.

Примечание

Речь идёт о запросах к строковой таблице, управляемой data shard'ом.

Рассмотрим графики Latency на панели мониторинга Grafana DB overview и определим, имеет ли отношение наша проблема к кластеру YDB:

DB Overview > Latencies > R tx server latency percentiles

См. описание графика

График отображает процентили задержек транзакций. Примерно в 10:19:30 эти значения выросли в два-три раза.

DB Overview > Latencies > Read only tx server latency

См. описание графика

График отображает тепловую карту (heatmap) задержек транзакций. Транзакции группируются на основании их задержек, каждая группа (bucket) окрашивается в свой цвет. Таким образом, этот график показывает как количество транзакций, обрабатываемых YDB в секунду (по вертикальной оси), так и распределение задержек среди транзакций (цветовая дифференциация).

К 10:20:30 доля транзакций с минимальными задержками (Группа 1, тёмно-зелёный) упала в четыре-пять раз. Группа 4 выросла примерно в пять раз, а также выделилась новая группа транзакций с ещё более высокими задержками — Группа 8.

Таким образом, мы видим, что задержки действительно выросли. Теперь нам необходимо локализовать проблему.

Диагностика

Давайте определим причину роста задержек. Могли ли они увеличиться из-за возросшей нагрузки? Посмотрим на график Requests в секции API details панели мониторинга Grafana DB overview:

API details

Количество пользовательских запросов выросло приблизительно с 27 000 до 35 000 в 10:20:00. Но может ли YDB справиться с увеличившейся нагрузкой без дополнительных аппаратных ресурсов?

Загрузка CPU увеличилась, что видно на графике CPU by execution pool.

CPU

См. графики на панели мониторинга Grafana CPU

Графики на панели мониторинга Grafana CPU показывают рост нагрузки на CPU в пуле ресурсов пользователей и интерконнекта:

CPU

CPU

CPU

Мы также можем взглянуть на общее использование CPU на вкладке Diagnostics в Embedded UI:

CPU diagnostics

Кластер YDB не использует все ресурсы CPU.

Взглянув на секции DataShard и DataShard details на панели мониторинга Grafana DB overview, мы увидим, что после роста нагрузки на кластер один из data shard'ов был перегружен.

Throughput

См. описание графика

Этот график показывает, что количество читаемых строк в базе данных YDB увеличилось с ~26 000 до ~33 500 строк в секунду.

Shard distribution by load

См. описание графика

Этот график отображает тепловую карту распределения data shard'ов по нагрузке. Каждый data shard потребляет от 0% до 100% ядра CPU. Data shard'ы делятся на десять групп по занимаемой ими доле ядра CPU — 0-10%, 10-20% и т.д. Эта тепловая карта показывает количество data shard'ов в каждой группе.

График показывает только один data shard, нагрузка на который изменилась примерно в 10:19:30 — data shard перешёл в Группу 70, содержащую шарды, нагруженные на 60–70%.

Overloaded shard

См. описание графика

По аналогии с предыдущим графиком, Overloaded shard count — это тепловая карта распределения data shard'ов по нагрузке. Однако этот график отображает только data shard'ы с нагрузкой, превышающей 60%.

График показывает, что нагрузка на один data shard увеличилась до 70% примерно в 10:19:30.

Чтобы определить, какую таблицу обслуживает перегруженный data shard, откроем вкладку Diagnostics > Top shards во встроенном UI:

Diagnostics > shards

Мы видим, что один из data shard'ов, обслуживающих таблицу kv_test, нагружен на 67%.

Далее давайте взглянем на информацию о таблице kv_test на вкладке Info:

stock table info

Важно

Таблица kv_test была создана с отключённым партиционированием по нагрузке и содержит только одну партицию.

Это означает, что все запросы к этой таблице обрабатывает один data shard. Учитывая, что data shard'ы — это однопоточные компоненты, обрабатывающие за раз только один запрос, такой подход неэффективен.

Решение

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

  1. Во встроенном UI выберите базу данных.

  2. Откройте вкладку Query.

  3. Выполните следующий запрос:

    ALTER TABLE kv_test SET (
        AUTO_PARTITIONING_BY_LOAD = ENABLED
    );
    

Результат

После включения автоматического партиционирования для таблицы kv_test перегруженный data shard разделился на два.

Shard distribution by load

См. описание графика

График показывает, что количество data shard'ов выросло примерно в 10:28:00. Судя по цвету групп, их нагрузка не превышает 40%.

Overloaded shard count

См. описание графика

Перегруженный шард исчез с графика примерно в 10:28:00.

Теперь два data shard'а обрабатывают запросы к таблице kv_test, и ни один из них не перегружен:

Overloaded shard count

Давайте убедимся, что задержки транзакций вернулись к прежним значениям:

Final latency percentiles

См. описание графика

Примерно в 10:28:00 процентили задержек p50, p75 и p95 упали практически до прежних значений. Задержки p99 сократились не настолько значительно, но всё же уменьшились в два раза.

Final latencies

См. описание графика

Транзакции на этом графике теперь распределены по шести группам. Примерно половина транзакций вернулась в Группу 1, то есть их задержки не превышают одной миллисекунды. Более трети транзакций находятся в Группе 2 с задержками от одной до двух миллисекунд. Одна шестая транзакций — в Группе 4. Размеры остальных групп незначительны.

Задержки практически вернулись к уровню до увеличения нагрузки. При этом мы не увеличили расходы на приобретение дополнительных аппаратных ресурсов, а просто включили автоматическое партиционирование по нагрузке, что позволило более эффективно использовать доступные ресурсы.

Имя группы

Задержки, мс

Один перегруженный data shard,
транзакций в секунду

Несколько data shard'ов,
транзакций в секунду

1

0-1

2110

16961

2

1-2

5472

13147

4

2-4

16437

6041

8

4-8

9430

432

16

8-16

98.8

52.4

32

16-32

0.578

Тестовый стенд

Топология

Для этого примера мы использовали кластер YDB из трёх серверов на Ubuntu 22.04 LTS. На каждом сервере был запущен один узел хранения и три узла баз данных, обслуживающих одну и ту же базу данных.

Аппаратная конфигурация

Аппаратные ресурсы серверов (виртуальных машин) приведены ниже:

  • Платформа: Intel Broadwell
  • Гарантированный уровень производительности vCPU: 100%
  • vCPU: 28
  • Память: 32 GB
  • Диски:
    • 3 × 93 GB SSD на каждом узле YDB
    • 20 GB HDD для операционной системы

Тест

Нагрузка на кластер YDB была запущена с помощью команды CLI ydb workload. Дополнительную информацию см. в статье Нагрузочное тестирование.

Чтобы воспроизвести нагрузку, выполните следующие шаги:

  1. Проинициализируйте таблицы для нагрузочного тестирования:

    ydb workload kv init --min-partitions 1 --auto-partition 0
    

    Мы намеренно отключаем автоматическое партиционирование для создаваемых таблиц используя опции --min-partitions 1 --auto-partition 0.

  2. Воспроизведите стандартную нагрузку на кластер YDB:

    ydb workload kv run select -s 600 -t 100
    

    Мы запустили простую нагрузку, используя базу данных YDB как Key-Value хранилище. Точнее, мы использовали нагрузку select для выполнения SELECT-запросов, возвращающих строки по точному совпадению primary ключа.

    Параметр -t 100 используется для запуска нагрузочного тестирования в 100 потоков.

  3. Создайте перегрузку на кластере YDB:

    ydb workload kv run select -s 1200 -t 250
    

    Как только первый тест завершился, мы немедленно запустили тот же самый тест в 250 потоков, чтобы создать перегрузку.

Смотрите также

Предыдущая