Redis®*: Klasyfikowanie użytkowników w czasie rzeczywistym

Dowiedz się, jak klasyfikować 2 miliony użytkowników według punktów w czasie rzeczywistym za pomocą Redis

👋 Witamy w dokumentacji Stackhero!

Stackhero oferuje gotowe do użycia rozwiązanie Redis cloud, które zapewnia wiele korzyści, w tym:

  • Włączony web UI Redis Commander.
  • Nieograniczona wielkość i transfer wiadomości.
  • Bezproblemowe aktualizacje za pomocą jednego kliknięcia.
  • Optymalna wydajność i solidne zabezpieczenia dzięki prywatnej i dedykowanej VM.

Oszczędzaj czas i upraszczaj sobie życie: wystarczy 5 minut, aby wypróbować rozwiązanie hostingu Redis cloud Stackhero!

Jeden z naszych klientów zgłosił się do nas z interesującym wyzwaniem. Prowadzi stronę sportową, gdzie użytkownicy zdobywają punkty, wygrywając zakłady lub wykonując różne działania.

Jego celem było wyświetlenie rankingu każdego użytkownika, pokazanie użytkowników bezpośrednio powyżej i poniżej oraz wygenerowanie listy top-100. Przy społeczności liczącej 2 miliony użytkowników, dane musiały być przetwarzane w czasie rzeczywistym!

W Stackhero uwielbiamy podejmować takie wyzwania. W tym artykule przeprowadzimy Cię krok po kroku przez nasze rozwiązanie.

Tradycyjne bazy danych, takie jak MySQL, PostgreSQL czy Elasticsearch, nie są zaprojektowane do zadań klasyfikacji o niskim opóźnieniu. To skłoniło nas do poszukiwania innej opcji.

Wybraliśmy Redis, bazę danych w pamięci, która jest niezwykle szybka i niezawodna. Według DB-Engines jest to 7. najczęściej używana baza danych na świecie i wiodąca opcja w kategorii "Key-value store".

Redis oferuje wiele modeli danych. W tym scenariuszu wyróżnia się jeden: "sorted sets".

Sorted sets łączą klucz i wynik. W naszym przypadku kluczem jest ID użytkownika, a wynik reprezentuje punkty użytkownika.

Zaczęliśmy od uruchomienia usługi Redis na Stackhero. Usługa jest gotowa w zaledwie 2 minuty z najnowszą stabilną wersją, oferuje rozliczenia godzinowe i posiada Redis Commander, wygodny interfejs webowy. Zweryfikowaliśmy koncepcję za pomocą tego interfejsu.

Dodaliśmy trzech użytkowników z przykładowymi ID i wynikami, jak pokazano poniżej:

| Nazwa użytkownika | Wynik | | - | - | | userId1 | 11 | | userId2 | 54 | | userId3 | 24 |

Ci użytkownicy zostali dodani do sorted set o nazwie usersScores za pomocą następujących poleceń Redis:

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

Redis Commander, interfejs webowy dostarczany na Stackhero z instancjami RedisRedis Commander, interfejs webowy dostarczany na Stackhero z instancjami Redis

Następnie pobraliśmy wynik userId1:

ZSCORE usersScores "userId1"
> 11

To potwierdziło, że wynik dla userId1 wynosił rzeczywiście 11. Następnie sprawdziliśmy pozycję userId1 w rankingu:

ZREVRANK usersScores "userId1"
> 2

Pamiętaj, że ranking zaczyna się od 0. Oznacza to, że rankingi są następujące:

| Nazwa użytkownika | Wynik | Pozycja | | - | - | - | | userId1 | 11 | 2 | | userId2 | 54 | 0 | | userId3 | 24 | 1 |

Polecenie ZREVRANK zwróciło 2, co jest dokładnie tym, czego oczekiwaliśmy dla userId1.

Możesz również pobrać najlepsze wpisy. Na przykład, aby pobrać pierwszych 2 użytkowników (od pozycji 0 do 1) uruchom:

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

Aby uzyskać top 100 użytkowników, po prostu uruchom:

ZREVRANGE usersScores 0 99 WITHSCORES

To podejście jest wydajne i doskonale nadaje się do wysokowydajnej klasyfikacji w czasie rzeczywistym.

Poniżej znajdują się dodatkowe polecenia Redis używane na stronie naszego klienta:

  • Pobierz użytkowników sklasyfikowanych między pozycjami 50 a 100: ZREVRANGE usersScores 50 100 WITHSCORES
  • Dodaj użytkownika: ZADD usersScores 40 "userId4"
  • Zaktualizuj wynik użytkownika (to zastępuje istniejący wpis userId4): ZADD usersScores 42 "userId4"
  • Usuń użytkownika: ZREM usersScores "userId4"

Po zweryfikowaniu koncepcji w Redis Commander, nadszedł czas na integrację Redis z rzeczywistym kodem. Nasz klient używa Node.js i poniżej znajduje się przykład z użyciem ioredis jako klienta:

const Redis = require('ioredis');

(async () => {
  // Ustaw dane uwierzytelniające Redis
  // Jeśli używasz Stackhero, znajdziesz je na pulpicie Stackhero
  const redis = new Redis({
    host: '<redisServerHost>',
    password: '<redisServerPassword>',
    port: <PORT_TLS>, // <PORT_CLEAR> jest dla połączeń nieszyfrowanych, a <PORT_TLS> dla TLS. TLS powinien być używany.
    tls: {}, // Podaj pusty obiekt, aby aktywować TLS
    lazyConnect: true
  });

  // Połącz się z Redis
  await redis.connect();

  // Dodaj użytkowników
  await redis.zadd('usersScores', 11, 'userId1');
  await redis.zadd('usersScores', 54, 'userId2');
  await redis.zadd('usersScores', 24, 'userId3');

  // Pobierz wynik userId1
  const score = await redis.zscore('usersScores', 'userId1');
  console.log('userId1 ma ' + score + ' punktów');

  // Pobierz pozycję rankingu userId1
  const rankPosition = await redis.zrevrank('usersScores', 'userId1');
  console.log('userId1 jest na pozycji ' + rankPosition);

  // Rozłącz się z Redis
  await redis.disconnect();
})();

Ten prosty, ale potężny fragment kodu jest idealny do zarządzania danymi klasyfikacji w czasie rzeczywistym.

Podjęcie tego problemu było zarówno interesujące, jak i wymagające. W naszym przypadku Redis okazał się idealnym rozwiązaniem, ponieważ jest łatwy w użyciu, potężny i wyjątkowo szybki.

Jeśli chcesz poeksperymentować z Redis, możesz uruchomić instancję na Stackhero w zaledwie 2 minuty. Ciesz się najnowszą stabilną wersją, interfejsem webowym, kopiami zapasowymi i imponującą wydajnością na wyciągnięcie ręki.

Pulpit Stackhero pokazujący działające usługi Node.js i RedisPulpit Stackhero pokazujący działające usługi Node.js i Redis