Почему Redis может отвечать медленно
Что проверяют
Знаете ли вы, что Redis исполняет команды в один поток, и умеете ли делить задержку на три слагаемых: работа сервера, круговые задержки сети, сам клиент. У питониста отдельно проверяют, не блокирует ли его код цикл событий и есть ли пул соединений.
Как отвечать
Идите по слоям.
Сервер: команды исполняются последовательно, поэтому одна тяжёлая операция тормозит всех. Виновники обычно KEYS, HGETALL и LRANGE на огромной коллекции, SORT, долгие скрипты на Lua, удаление большого ключа через DEL вместо UNLINK. Перебирать ключи надо курсором SCAN.
Память и запись на диск: на пороге maxmemory начинается вытеснение при каждой записи, а BGSAVE и перезапись AOF делают fork, и копирование страниц даёт всплеск задержки. Если процесс ушёл в swap, задержки растут на порядки.
Сеть и клиент: сто последовательных GET это сто круговых задержек, лечится MGET и конвейером. В Python добавляются свои грабли: клиент без пула открывает соединение на каждый запрос, синхронный клиент внутри asyncio блокирует цикл, а разбор большого JSON или pickle на стороне приложения легко весит больше самого запроса.
Диагностика: SLOWLOG GET, INFO commandstats, redis-cli --latency и --bigkeys.
Где спотыкаются
Зовут KEYS по шаблону на боевой базе. На миллионах ключей это блокирует сервер на секунды, и падает не один этот вызов, а весь сервис.
Второе: меряют время на стороне приложения и обвиняют Redis, хотя SLOWLOG пуст. Значит дело в количестве обращений или в сети, и лечится это конвейером и укрупнением запросов, а не правкой конфигурации.
Третье: забывают про сохранение на диск и про swap. Всплески раз в несколько минут почти всегда совпадают с fork на снимке, и без графика задержек это выглядит как случайные тормоза.