Comandos lentos en Redis Redis blocking commands (single-threaded)
ID de la causa db-redis-block · Responsable principal Desarrollo de servidor (Equipo de desarrollo) · También Infraestructura de BD (Equipo de infraestructura)
Redis procesa los comandos de uno en uno, así que un solo comando lento bloquea todas las solicitudes que vienen detrás.
Por qué En producción se busca en todo el keyspace con KEYS, o se lee o borra de una vez un ranking o una lista de millones de elementos → Efecto Todas las demás solicitudes esperan hasta que termina ese comando (de decenas de ms a varios segundos) → En pantalla Tirones a la vez en todas las funciones que usan sesiones, rankings o caché; inicios de sesión lentos
Responsable principal Desarrollo de servidor (Equipo de desarrollo) · También Infraestructura de BD (Equipo de infraestructura)
Tareas (Equipo de desarrollo)
Sustituir KEYS por SCAN, dividir las claves grandes, borrar con UNLINK (borrado en segundo plano), repartir las caducidades que coinciden en el mismo segundo.
Tareas (Equipo de infraestructura)
Vigilar el registro de comandos lentos (SLOWLOG), bloquear en los servidores de producción los comandos peligrosos como KEYS, revisar periódicamente las claves grandes, desactivar THP y dejar memoria libre para el fork, hacer los guardados RDB y AOF en una réplica.
Cifras de referencia
Un comando normal tarda menos de 1 ms. Manejar millones de elementos de una vez puede tardar de cientos de ms a varios segundos.
En el gráfico
Picos aleatorios · Latencia de respuesta de Redis, número de comandos lentos
Dónde mirar
Ver con SLOWLOG GET los comandos que superan slowlog-log-slower-than; activar el monitor de latencia (desactivado por defecto) con CONFIG SET latency-monitor-threshold y revisar con LATENCY LATEST y LATENCY DOCTOR la latencia por evento, como fork o expire-cycle. Comprobar también el tiempo de fork con latest_fork_usec de INFO y las claves grandes con redis-cli --bigkeys
Se confirma si
A la hora de la detención, SLOWLOG tiene un KEYS o un comando que maneja una clave grande entera, o LATENCY registra a esa misma hora eventos fork o expire-cycle de decenas de ms o más
Se descarta si
Si SLOWLOG y LATENCY están vacíos y solo va lento desde el servidor del juego, apunta a la red o a esperas dentro del servidor del juego (SLOWLOG solo mide el tiempo de ejecución del comando, sin el intercambio con el cliente)
Se verifica con
Con herramientas de infraestructura (no hace falta código del juego)
Para saber más
También se detiene en el momento de duplicar el proceso (fork) para crear el archivo de guardado (instantánea RDB) o reescribir el AOF. En servidores actuales cuesta unos 10 ms por GB de memoria, así que con 30 GB son unos 300 ms. Con las páginas grandes (THP) activadas, después del fork cada escritura copia una página grande entera (copy-on-write), y las detenciones y el uso de memoria crecen mucho; por eso normalmente se desactiva THP y se deja memoria libre de sobra. Redis también se detiene un momento cuando caducan muchísimas claves en el mismo segundo y tiene que borrarlas.
Fuentes
Diagnosing latency issuesRedis Un solo hilo procesa las solicitudes en orden y un comando lento bloquea a todos los que vienen detrás; sustituir KEYS por SCAN; fork medido en servidores físicos y VM modernas: unos 9–13 ms por GB; con THP, la copia tras el fork dispara la latencia y la memoria; muchas caducidades en el mismo segundo provocan detenciones
KEYSRedis Usar con extrema precaución en producción: puede arruinar el rendimiento en BD grandes (medido en una computadora portátil de gama básica: 40 ms con 1 millón de claves)
UNLINKRedis Borrado asíncrono que desvincula la clave al instante y libera la memoria en otro hilo
SLOWLOGRedis Log de comandos lentos que registra los comandos que superan slowlog-log-slower-than; el tiempo de ejecución no incluye la E/S con el cliente
Redis latency monitoringRedis latency-monitor-threshold es 0 (desactivado) por defecto; LATENCY LATEST y LATENCY DOCTOR; registra la latencia por evento, como fork o expire-cycle
INFORedis latest_fork_usec: tiempo que tardó el último fork (microsegundos)
Redis CLIRedis --bigkeys: recorre el keyspace para encontrar claves grandes