Обзор — что это даёт
Эта статья учит тому, как читать метрики экрана Сервисы ▸ Сессии (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). Эта статья обобщает и связывает эти концепции, а не переопределяет их — наведите курсор на живые подсказки, чтобы увидеть все подробности.
Когда применять
- Карточка сессии перешла в состояние Деградация / Недоступен, и вы хотите разобраться в коде причины (
mem_saturation,fragmentation,blocked_clients,replica_link_down,rdb_save_failed,stale). - Доля попаданий выглядит низкой, но узел кажется исправным (нужно решить, нормально ли это для хранилища сессий).
- Коэффициент фрагментации поднялся выше 1,5 или опустился ниже 1,0, и вам нужны причина и способ исправления.
- Вытеснение начало расти выше 0, и вы опасаетесь потери сессий.
- Slowlog продолжает расти, и нужно найти, какой шаблон команд следует исправить.
Компоновка
Одна карточка сессии соответствует одному узлу (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 % (бюджет) для кольцевого индикатора и графика памяти выбирается в таком порядке:
- Если
maxmemoryзадан, он и есть жёсткий потолок (Redis его соблюдает). Оценка свободного =maxmemory − used. - Если не задан (без ограничения), бюджет =
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 мс). Начиная с самых частых:
- Команды O(N) —
KEYS *,SMEMBERS,HGETALL,LRANGE 0 -1сканируют коллекции целиком. Главная причина. - Операции с большими ключами — строки в несколько МБ или затраты на сериализацию и передачу крупных Hash/Set/ZSet.
- Нехватка памяти / своп — выделение памяти застопоривается по мере приближения занятого объёма к пределу.
- Задержка fork при персистентности —
bgsaveRDB / перезапись AOF,latest_fork_usec. - Тяжёлые скрипты Lua/функции — тяжёлый
EVALблокирует сервер на всё время выполнения. - Большие конвейеры / MULTI — тысячи команд разом ставят всё остальное в очередь.
- 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 означает, что отбрасываются живые сессии. Действуйте так:
- Скорость вытеснения > 0 → добавьте ОЗУ / поднимите
maxmemory. - Проверьте политику:
allkeys-lruвытесняет и сессии тоже;volatile-*вытесняет только ключи с TTL. - Если одновременно растёт
rejected_connections, вы одновременно упёрлись вmaxclientsи в предел памяти.
# Просмотр / изменение политики вытеснения
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и суммы ключей — это расширенные столбцы коллектора; на устаревшем коллекторе такие разделы аккуратно скрываются («будет показано после переустановки коллектора»).
Доступ
- Чтение (просмотр экрана «Сессии»): ролевая область Сервисы
min_req 1— любой вошедший пользователь (demo=1 и выше). Экран только для чтения, поэтому барьера на запись нет (нет ни прямого подключения к Redis, ни команд записи). - Изменение порогов: скорректируйте значения
redis_*в разделе Операционная политика — администраторlevel≥5(admin=10, контроль черезinfr.level). - Регистрация коллектора: добавление узлов redis_host к коллектору redis_vts выполняется в разделе Коллекторы при
level≥5.
Устранение неполадок и ответы на вопросы
В. Отображается только «Узлы 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), поводов для беспокойства почти нет.
Связанные материалы
- Экран «Сессии (Redis)» — живая консоль, применяющая эти концепции
- Мониторинг нагрузки базы данных — монитор БД с тем же повествованием (соединения, QPS, медленные запросы)
- Концепции настройки БД (обучение) — блокировки, кэш и индексы на стороне БД
- Операционная политика — изменение порогов
redis_*и процента резерва - Коллекторы — коллектор redis_vts и регистрация узлов
- Обзор сервисов — размещение карточек сессий на доске
