Redis®*: Clasificar usuarios en tiempo real

Aprenda a clasificar 2 millones de usuarios por puntuación en tiempo real usando Redis

👋 ¡Bienvenido a la documentación de Stackhero!

Stackhero ofrece una solución Redis cloud lista para usar que proporciona una serie de beneficios, incluyendo:

  • Interfaz web Redis Commander incluida.
  • Tamaño y transferencias de mensajes ilimitados.
  • Actualizaciones sin esfuerzo con solo un clic.
  • Rendimiento óptimo y seguridad robusta gracias a una VM privada y dedicada.

Ahorra tiempo y simplifica tu vida: ¡solo toma 5 minutos probar la solución de alojamiento Redis cloud de Stackhero!

Uno de nuestros clientes nos contactó con un desafío interesante. Dirige un sitio web deportivo donde los usuarios ganan puntos al ganar apuestas o completar diversas acciones.

Su objetivo era mostrar el rango de cada usuario, mostrar a los usuarios inmediatamente por encima y por debajo de ellos, y generar una tabla de clasificación de los 100 mejores. Con una comunidad de 2 millones de usuarios, ¡los datos necesitaban ser procesados en tiempo real!

En Stackhero nos encanta enfrentar desafíos como este. En este artículo, le guiaremos a través de nuestra solución paso a paso.

Las bases de datos tradicionales como MySQL, PostgreSQL o Elasticsearch no están diseñadas para tareas de clasificación de baja latencia. Esto nos llevó a explorar otra opción.

Seleccionamos Redis, una base de datos en memoria que es extremadamente rápida y confiable. Según DB-Engines, es la séptima base de datos más utilizada en el mundo y la opción líder en la categoría "Key-value store".

Redis ofrece múltiples modelos de datos. Para este escenario, uno destaca: los "sorted sets".

Los sorted sets combinan una clave y una puntuación. En nuestro caso, la clave es el ID del usuario y la puntuación representa los puntos del usuario.

Comenzamos lanzando un servicio Redis en Stackhero. El servicio está operativo en solo 2 minutos con la última versión estable, ofrece facturación por hora y cuenta con Redis Commander, una práctica interfaz web. Validamos el concepto usando esta interfaz.

Agregamos tres usuarios con IDs y puntuaciones de ejemplo como se muestra a continuación:

| Nombre de usuario | Puntuación | | - | - | | userId1 | 11 | | userId2 | 54 | | userId3 | 24 |

Estos usuarios fueron añadidos a un sorted set llamado usersScores usando los siguientes comandos de Redis:

ZADD usersScores 11 "userId1"
ZADD usersScores 54 "userId2"
ZADD usersScores 24 "userId3"

Redis Commander, la interfaz web proporcionada en Stackhero con instancias de RedisRedis Commander, la interfaz web proporcionada en Stackhero con instancias de Redis

A continuación, recuperamos la puntuación de userId1:

ZSCORE usersScores "userId1"
> 11

Esto confirmó que la puntuación para userId1 era efectivamente 11. Después de eso, verificamos el rango de userId1:

ZREVRANK usersScores "userId1"
> 2

Recuerde, la clasificación comienza en 0. Esto significa que las clasificaciones son las siguientes:

| Nombre de usuario | Puntuación | Rango | | - | - | - | | userId1 | 11 | 2 | | userId2 | 54 | 0 | | userId3 | 24 | 1 |

El comando ZREVRANK devolvió 2, que es exactamente lo que esperábamos para userId1.

También puede obtener las entradas principales. Por ejemplo, para recuperar los primeros 2 usuarios (del rango 0 al rango 1) ejecute:

ZREVRANGE usersScores 0 1 WITHSCORES
> 1) userId2
> 2) 54
> 3) userId3
> 4) 24

Para obtener los 100 mejores usuarios simplemente ejecute:

ZREVRANGE usersScores 0 99 WITHSCORES

Este enfoque es eficiente y perfectamente adecuado para la clasificación en tiempo real de alto rendimiento.

A continuación se presentan algunos comandos adicionales de Redis utilizados en el sitio web de nuestro cliente:

  • Obtener usuarios clasificados entre las posiciones 50 y 100: ZREVRANGE usersScores 50 100 WITHSCORES
  • Añadir un usuario: ZADD usersScores 40 "userId4"
  • Actualizar la puntuación de un usuario (esto reemplaza la entrada existente userId4): ZADD usersScores 42 "userId4"
  • Eliminar un usuario: ZREM usersScores "userId4"

Después de validar el concepto en Redis Commander, es hora de integrar Redis en código real. Nuestro cliente usa Node.js y a continuación se muestra un ejemplo usando ioredis como cliente:

const Redis = require('ioredis');

(async () => {
  // Establecer credenciales de Redis
  // Si usa Stackhero, las encontrará en el panel de Stackhero
  const redis = new Redis({
    host: '<redisServerHost>',
    password: '<redisServerPassword>',
    port: <PORT_TLS>, // <PORT_CLEAR> es para conexiones no seguras y <PORT_TLS> es para TLS. Se debe usar TLS.
    tls: {}, // Proporcione un objeto vacío para activar TLS
    lazyConnect: true
  });

  // Conectar a Redis
  await redis.connect();

  // Añadir usuarios
  await redis.zadd('usersScores', 11, 'userId1');
  await redis.zadd('usersScores', 54, 'userId2');
  await redis.zadd('usersScores', 24, 'userId3');

  // Recuperar puntuación de userId1
  const score = await redis.zscore('usersScores', 'userId1');
  console.log('userId1 tiene ' + score + ' puntos');

  // Recuperar posición de rango de userId1
  const rankPosition = await redis.zrevrank('usersScores', 'userId1');
  console.log('userId1 está clasificado en la posición ' + rankPosition);

  // Desconectar de Redis
  await redis.disconnect();
})();

Este fragmento de código simple pero poderoso es ideal para gestionar datos de clasificación en tiempo real.

Enfrentar este problema fue tanto interesante como desafiante. En nuestro caso, Redis resultó ser una solución ideal porque es fácil de usar, potente y excepcionalmente rápido.

Si desea experimentar con Redis, puede iniciar una instancia en Stackhero en solo 2 minutos. Disfrute de la última versión estable, una interfaz web, copias de seguridad y un rendimiento impresionante al alcance de su mano.

Panel de Stackhero mostrando servicios de Node.js y Redis en ejecuciónPanel de Stackhero mostrando servicios de Node.js y Redis en ejecución