Redis®*: ユーザーをリアルタイムでランク付けする

Redisを使用して2百万ユーザーをスコアでリアルタイムにランク付けする方法を学ぶ

👋 Stackheroのドキュメントへようこそ!

Stackheroは、数多くの利点を提供する、すぐに使えるRedisクラウドソリューションを提供しています。

  • Redis Commander Web UIを含む。
  • メッセージサイズと転送が無制限
  • ワンクリックで簡単にアップデート
  • プライベートで専用のVMによる最適なパフォーマンスと強力なセキュリティ

時間を節約し、生活を簡素化:StackheroのRedisクラウドホスティングソリューションを試すのに5分しかかかりません!

あるお客様から興味深い課題をいただきました。彼はスポーツサイトを運営しており、ユーザーはベットに勝ったり様々なアクションを完了することでポイントを獲得します。

彼の目標は、各ユーザーのランクを表示し、すぐ上と下のユーザーを示し、トップ100のリーダーボードを生成することでした。2百万ユーザーのコミュニティがあるため、データはリアルタイムで処理される必要がありました!

Stackheroでは、このような課題に取り組むことが大好きです。この記事では、私たちの解決策をステップバイステップでご紹介します。

MySQLPostgreSQL、またはElasticsearchのような従来のデータベースは、低レイテンシーのランキングタスクには設計されていません。これが別のオプションを探るきっかけとなりました。

私たちはRedisを選びました。これは非常に高速で信頼性の高いインメモリデータベースです。DB-Enginesによると、世界で7番目に使用されているデータベースであり、「Key-value store」カテゴリのリーディングオプションです。

Redisは複数のデータモデルを提供しています。このシナリオでは、「sorted sets」が際立っています。

Sorted setsはキーとスコアを組み合わせます。私たちの場合、キーはユーザーIDで、スコアはユーザーのポイントを表します。

StackheroでRedisサービスを開始することから始めました。このサービスは最新の安定版でわずか2分で稼働し、時間単位の請求を提供し、便利なWeb GUIであるRedis Commanderを備えています。このインターフェースを使用してコンセプトを検証しました。

以下のようにサンプルIDとスコアを持つ3人のユーザーを追加しました:

| ユーザー名 | スコア | | - | - | | userId1 | 11 | | userId2 | 54 | | userId3 | 24 |

これらのユーザーは、以下のRedisコマンドを使用してusersScoresというsorted setに追加されました:

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

Redis Commander, Stackheroで提供されるRedisインスタンスのWeb GUIRedis Commander, Stackheroで提供されるRedisインスタンスのWeb GUI

次に、userId1のスコアを取得しました:

ZSCORE usersScores "userId1"
> 11

これにより、userId1のスコアが確かに11であることが確認されました。その後、userId1のランクを確認しました:

ZREVRANK usersScores "userId1"
> 2

ランクは0から始まることを覚えておいてください。これは、ランクが次のようになることを意味します:

| ユーザー名 | スコア | ランク | | - | - | - | | userId1 | 11 | 2 | | userId2 | 54 | 0 | | userId3 | 24 | 1 |

ZREVRANKコマンドは2を返し、これはuserId1に対して期待していた結果です。

トップエントリーを取得することもできます。例えば、最初の2人のユーザー(ランク0からランク1まで)を取得するには、次のように実行します:

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

トップ100ユーザーを取得するには、単に次のように実行します:

ZREVRANGE usersScores 0 99 WITHSCORES

このアプローチは効率的で、高性能なリアルタイムランキングに完全に適しています。

以下は、クライアントのウェブサイトで使用される追加のRedisコマンドです:

  • 50位から100位までのユーザーを取得する:ZREVRANGE usersScores 50 100 WITHSCORES
  • ユーザーを追加する:ZADD usersScores 40 "userId4"
  • ユーザーのスコアを更新する(既存のuserId4エントリを置き換えます):ZADD usersScores 42 "userId4"
  • ユーザーを削除する:ZREM usersScores "userId4"

Redis Commanderでコンセプトを検証した後、実際のコードにRedisを統合する時が来ました。お客様はNode.jsを使用しており、以下はioredisをクライアントとして使用した例です:

const Redis = require('ioredis');

(async () => {
  // Redisの認証情報を設定
  // Stackheroを使用する場合、これらはStackheroダッシュボードで見つけることができます
  const redis = new Redis({
    host: '<redisServerHost>',
    password: '<redisServerPassword>',
    port: <PORT_TLS>, // <PORT_CLEAR>はクリア接続用で、<PORT_TLS>はTLS用です。TLSを使用するべきです。
    tls: {}, // TLSを有効にするために空のオブジェクトを提供
    lazyConnect: true
  });

  // Redisに接続
  await redis.connect();

  // ユーザーを追加
  await redis.zadd('usersScores', 11, 'userId1');
  await redis.zadd('usersScores', 54, 'userId2');
  await redis.zadd('usersScores', 24, 'userId3');

  // userId1のスコアを取得
  const score = await redis.zscore('usersScores', 'userId1');
  console.log('userId1 has ' + score + ' points');

  // userId1のランク位置を取得
  const rankPosition = await redis.zrevrank('usersScores', 'userId1');
  console.log('userId1 is ranked at position ' + rankPosition);

  // Redisから切断
  await redis.disconnect();
})();

このシンプルでありながら強力なコードスニペットは、リアルタイムのランキングデータを管理するのに理想的です。

この問題に取り組むことは興味深く、挑戦的でした。私たちの場合、Redisは使いやすく、強力で、非常に高速であるため、理想的なソリューションであることが証明されました。

Redisを試してみたい場合は、Stackheroでわずか2分でインスタンスを開始できます。最新の安定版、Web GUI、バックアップ、そして印象的なパフォーマンスをすぐに体験できます。

Stackheroダッシュボードに表示されるNode.jsとRedisサービスの実行Stackheroダッシュボードに表示されるNode.jsとRedisサービスの実行