InfraGuard

Концепции настройки Redis (обучение по сессиям)

Как читать метрики Redis на экране Сервисы ▸ Сессии (Redis) — 7 причин роста slowlog, доля попаданий, здоровый диапазон фрагментации памяти, а также истечение TTL против вытеснения.

Обзор — что это даёт

Эта статья учит тому, как читать метрики экрана Сервисы ▸ Сессии (Redis) (/service/session) и как на них реагировать. Тот экран — это консоль мониторинга в реальном времени; здесь же объясняются стоящие за ним эксплуатационные концепции Redis — slowlog, доля попаданий в keyspace, фрагментация памяти, а также истечение TTL против вытеснения.

InfraGuard никогда не подключается к Redis напрямую. Представительный коллектор внутренней сети (scripts/infr_redis_vts_collector.cjs, запускаемый под pm2 как ежеминутный cron) снимает с каждого узла срез redis-cli INFO и записывает его в центральную таблицу MySQL infr_redis_metric; приложение эту таблицу только читает. Поэтому все приведённые здесь значения берутся из стандартных полей INFO.

Точная терминология и советы по улучшению для каждой метрики хранятся в единственном экземпляре в обучающих всплывающих подсказках (при наведении) экрана «Сессии» (edu.* в resources/lang/{ko,en}/redis.php). Эта статья обобщает и связывает эти концепции, а не переопределяет их — наведите курсор на живые подсказки, чтобы увидеть все подробности.

Когда применять

Компоновка

Одна карточка сессии соответствует одному узлу (node_alias = infr_instance.alias, 1:1) и наследует повествование экрана Сервисы ▸ База данных.

Область Что показывает Исходные поля INFO
① Ёмкость · Свободно Кольцо ёмкости памяти (занято / предел) · клиенты (подключено/максимум) · заблокировано used_memory, maxmemory, total_system_memory, connected_clients, maxclients, blocked_clients
② Пропускная способность Спарклайн ops/s · доля попаданий за недавнее окно · сетевой ввод-вывод instantaneous_ops_per_sec, keyspace_hits/misses, instantaneous_input/output_kbps
Эффективность в подвале Оценка доли попаданий · оценка памяти (фрагментация) hit_rate, mem_fragmentation_ratio
Поток жизненного цикла сессий Истекающие (с TTL) → поток → всего истекло keyspace_expires, expired_keys
Детали (сворачиваемые) Временной ряд управления памятью + наложение потолка ёмкости + отметки эпизодов вытеснения · анализ keyspace/сессий ряд used_memory, evicted_keys, INFO keyspace

Верхние KPI: число узлов · Работают/Деградация/Недоступны · суммарные ops/s · всего ключей · сумма клиентов.

Как определяется ёмкость (потолок)

Опорное значение 100 % (бюджет) для кольцевого индикатора и графика памяти выбирается в таком порядке:

  1. Если maxmemory задан, он и есть жёсткий потолок (Redis его соблюдает). Оценка свободного = maxmemory − used.
  2. Если не задан (без ограничения), бюджет = total RAM − DB buffer pool − OS/other reserve (%). Резерв по умолчанию составляет 20 % (Операционная политика redis_reserve_pct); буферный пул базы данных вычитается по данным коллектора access=database того же узла.

Для узла с maxmemory 0 (без ограничения) выводится примечание «maxmemory не задан — показано относительно ОЗУ ОС/сервера». Для выделенного экземпляра под сессии задайте явный maxmemory (долю ОЗУ ОС), чтобы политика вытеснения вела себя предсказуемо.

Как пользоваться

1) slowlog — почему он растёт (7 причин, кратко)

Redis однопоточный, поэтому одна медленная команда блокирует весь сервер. slowlog_len — это накопительный счётчик команд, превысивших slowlog-log-slower-than (по умолчанию 10 мс). Начиная с самых частых:

  1. Команды O(N) — KEYS *, SMEMBERS, HGETALL, LRANGE 0 -1 сканируют коллекции целиком. Главная причина.
  2. Операции с большими ключами — строки в несколько МБ или затраты на сериализацию и передачу крупных Hash/Set/ZSet.
  3. Нехватка памяти / своп — выделение памяти застопоривается по мере приближения занятого объёма к пределу.
  4. Задержка fork при персистентности — bgsave RDB / перезапись AOF, latest_fork_usec.
  5. Тяжёлые скрипты Lua/функции — тяжёлый EVAL блокирует сервер на всё время выполнения.
  6. Большие конвейеры / MULTI — тысячи команд разом ставят всё остальное в очередь.
  7. DEL больших ключей — используйте асинхронный UNLINK вместо DEL.

Проверьте, какие команды сработали на самом деле, прямо на узле:

# Последние 10 медленных команд (redis-cli)
redis-cli SLOWLOG GET 10
# Порог + число хранимых записей (микросекунды · например, 10 мс)
redis-cli CONFIG SET slowlog-log-slower-than 10000
redis-cli CONFIG SET slowlog-max-len 128
redis-cli SLOWLOG RESET

Никогда не выполняйте KEYS * в производственной среде — пока команда обходит весь keyspace, все остальные команды ждут. Замените её курсорными итераторами SCAN / HSCAN / SSCAN / ZSCAN.

2) Доля попаданий в keyspace — низкое значение не является дефектом

Доля попаданий за недавнее окно = Δkeyspace_hits / (Δhits + Δmisses). Когда выборка мала (знаменатель дельты < 20), выполняется откат к накопленной за всё время hit_rate. Оценки: Отлично ≥99% · Хорошо ≥95% · Удовлетворительно ≥80%.

Доля попаданий — НЕ та ось состояния, которая окрашивает узел в красный. У хранилища сессий доля попаданий низка по своей природе: каждый новый вход, каждое истечение TTL и каждый выход — это промах, поэтому 40–60 % считается нормой (например, blue с 44,75 % — совершенно здоровый узел сессий). Именно поэтому порог redis_hit_rate_min (по умолчанию 50) хотя и существует, но не используется для определения состояния — он показывается лишь для интерпретации. Настоящие проблемы кэша выявляются независимо от нагрузки через насыщение памяти, вытеснение и фрагментацию, описанные ниже.

Чтобы реально повысить долю попаданий: удерживайте рабочий набор в памяти (запас по ОЗУ/maxmemory), подберите правильные TTL, смягчите лавину промахов кэша (TTL с джиттером) и прогревайте префиксы с большим числом промахов. Подробности — во всплывающей подсказке по попаданиям.

3) Фрагментация памяти — здоровый диапазон от 1,0 до 1,5

mem_fragmentation_ratio = used_memory_rss / used_memory — отношение физической памяти, выданной Redis операционной системой, к той, что Redis фактически использует.

Коэффициент Значение Действие
1.0 – 1.5 Здоровый диапазон Норма
> 1.5 Фрагментировано (ОЗУ расходуется впустую) activedefrag yes (нужен jemalloc), сократить частое создание/удаление крупных значений
< 1.0 Идёт своп (опасно) Немедленно добавить ОЗУ или снизить maxmemory, чтобы прекратить своп, — признак резкого замедления

Оценки: Отлично 0,95–1,4 · Хорошо ~1,6 · Удовлетворительно ~2,5. Порог состояния redis_frag_ratio по умолчанию равен 1,6.

На небольшом экземпляре, где used_memory меньше 64MB, в коэффициенте преобладают постоянные накладные расходы, и значение фрагментации становится ложноположительным. В этом случае InfraGuard исключает фрагментацию из оценки (frag_score = null) — значение по-прежнему отображается, но узел в красный не окрашивается.

4) Истечение TTL против вытеснения — суть жизненного цикла сессий

Термин Значение Сигнал
Истекло (expired_keys) TTL прошёл, естественное удаление = нормальный жизненный цикл сессии Обновление состава · обычно норма
Вытеснено (evicted_keys) Принудительное удаление при достижении maxmemory согласно политике Нехватка памяти · риск потери сессий

В хранилище сессий истечение TTL — это норма, но устойчивое вытеснение выше 0 означает, что отбрасываются живые сессии. Действуйте так:

# Просмотр / изменение политики вытеснения
redis-cli CONFIG GET maxmemory-policy
redis-cli CONFIG SET maxmemory-policy volatile-lru
# Дефрагментация на лету (при фрагментации > 1.5 · нужен jemalloc)
redis-cli CONFIG SET activedefrag yes

График управления памятью в разделе деталей накладывает на used_pct линию потолка ёмкости на уровне 100 % и отмечает эпизоды вытеснения метками crit — так вы можете визуально проследить, когда узел упёрся в потолок и отбросил сессии.

5) Чтение логических БД (keyspace)

INFO keyspace сообщает количество ключей в пронумерованных независимых пространствах ключей (логических БД, по умолчанию 16, индексы 0–15).

# INFO keyspace example
db0:keys=48213,expires=48213,avg_ttl=1680000
db1:keys=126,expires=0,avg_ttl=0

БД с наибольшим числом ключей — это основное хранилище сессий, и если для неё выполняется keys = expires (все с TTL), то это чистое хранилище сессий (ключи угасают естественным образом). В примере выше db0 читается как сессии (все с TTL), а db1 — как другое применение (кэш/блокировки).

Источники данных

Элемент Значение
Исходная таблица infr_redis_metric (центральный MySQL · модель только для чтения, $timestamps=false)
Питающий коллектор scripts/infr_redis_vts_collector.cjs (pm2, ежеминутно) — redis-cli INFO
Создание таблицы Коллектор создаёт её сам через CREATE TABLE IF NOT EXISTS (без миграции)
Ключ соединения instance_id (сначала целочисленный внешний ключ) → запасной вариант node_alias ↔ infr_instance.alias
Построитель App\Services\Redis\RedisMetricService (один пакетный запрос · кэш 20 с)
Недавнее окно 30 мин (WINDOW_MIN) · до 60 точек графика · опрос каждые 30 с (/service/session/live)
SOT порогов App\Support\OpsPolicy::redisThresholds()

Пороги состояния (Операционная политика infr_setting group=ops):

Ключ По умолчанию Вердикт
redis_mem_pct 85 ёмкость(%) ≥ → Деградация (mem_saturation)
redis_frag_ratio 1.6 фрагментация ≥ → Деградация (fragmentation, только когда used ≥ 64MB)
redis_blocked 1 заблокированных клиентов ≥ → Деградация (blocked_clients)
redis_stale_min 5 последняя выборка старше N мин → Недоступен (stale)
redis_hit_rate_min 50 только отображение/интерпретация (не используется для состояния)
redis_reserve_pct 20 резерв ОС/прочего (%) для расчёта оценки свободной памяти

master_link_status=down (связь с репликой потеряна) и rdb_last_bgsave_status=err (сохранение RDB не удалось) также распознаются как причины Деградации. Детализация keyspace по каждой БД, total_system_memory и суммы ключей — это расширенные столбцы коллектора; на устаревшем коллекторе такие разделы аккуратно скрываются («будет показано после переустановки коллектора»).

Доступ

Устранение неполадок и ответы на вопросы

В. Отображается только «Узлы Redis ещё не собраны». О. Таблица infr_redis_metric пуста. Зарегистрируйте узлы redis_host у коллектора redis_vts в разделе Администрирование ▸ Коллекторы и разверните scripts/infr_redis_vts_collector.cjs под pm2 на представительном хосте. Коллектор создаёт таблицу через CREATE TABLE IF NOT EXISTS и собирает данные каждую минуту.

В. Узел остаётся Недоступен с причиной stale. О. Последняя выборка старше 5 мин (redis_stale_min) — коллектор pm2 завершился (pm2 ls) либо сетевой доступ или доступ через redis-cli к узлу заблокирован. Проверьте журналы коллектора.

В. Разделы анализа keyspace/сессий и потолка памяти отсутствуют. О. Столбцы total_system_memory, keyspace по каждой БД и суммы ключей являются расширениями коллектора. На устаревшем коллекторе они равны null, поэтому разделы скрываются — переустановите последнюю версию коллектора, чтобы они появились.

В. Доля попаданий 45 % — почему состояние не Деградация? О. Так задумано. У хранилища сессий доля попаданий обычно низка, поэтому она никогда не переводит узел в состояние Деградации. Настоящие проблемы (насыщение памяти, вытеснение, фрагментация) отслеживаются по отдельным осям.

В. Фрагментация показывает 3,0, но экземпляр совсем маленький. О. Когда used_memory меньше 64MB, постоянные накладные расходы искажают коэффициент. В этом случае InfraGuard исключает фрагментацию из оценки — считайте значение справочным. Если это не настоящий своп (<1,0), поводов для беспокойства почти нет.

Связанные материалы

세션 화면의 튜닝 교육 패널
세션 화면의 튜닝 교육 패널