※リアルタイムランキングはランキングの変動を瞬時に表すことと定義します
現在のプロジェクトでは、Redisのソート済みセット型を応用してバッチ処理などの集計が必要ないランキングを実装しています。
- Redis http://redis.shibu.jp/
Redisのソート済みセット型について
row | member | score |
---|---|---|
1 | user1 | 200 |
2 | user2 | 100 |
3 | user3 | 300 |
4 | user4 | 200 |
5 | user5 | 400 |
上記のようなテーブルがあった際にメンバの順位を求めようと思うと、通常なら「スコアを元に並べ替え」をした後に「順位を知りたいユーザが何件目」にあるかという処理の流れになります。
Redisのソート済みセット型では、スコアを用いて並び替えが内部で行われるので、ソート済みセット型を利用した取得(zrank)で順位を求めるだけで、並び替えを意識することなく結果が得られます。
keyとは任意の文字列でランキング1つにつき1つのキーを使います。
zrank key user2 => 4(zrankを使った取得ではインデックスが返ってくる)
rank = 4 + 1(インデックスに+1したものが順位)
同率順位を加味した順位を取得する実装はこちら
http://qiita.com/devhiroki/items/2fe81d691b94b6db795d
リアルタイムランキング結果の取得実装について
- 順位を取得する
- アプリケーションの処理をする(ランキングのスコア加算を含む)
- 順位を取得する
ソート済みセット型を使うだけで集計を意識する必要は無いので、処理の前後に順位を取得する処理をするだけで、ランキングの変動を表現することが出来ます。
中間・最終ランキングに分かれている際の実装について
ランキングが中間・最終の2つに分けたいというアプリケーション要件の際は、下記のようにキーを分けることによって実現できます。
最終は中間までのスコアも含めた状態ということは、中間の時から常に加算しておけば良いという考え方です。
中間ランキング
- 中間キーの順位を取得する
- 中間キーに対して加算する、最終キーに対して加算する
- 中間キーの順位を取得する
最終ランキング
- 最終キーの順位を取得する
- 最終キーに対して加算する
- 最終キーの順位を取得する
ランキング確定について
よくあるランキングの確定とは、バッチ処理を走らせて処理が終わったタイミングでランキングが確定するというものが一般的だと思います。ランキング確定のためのバッチ処理後は、その後にスコアが加算されてもランキングは変動しません。
しかし、Redisで上記のような実装をする場合はソート済みセット型の性質から、スコアを加算されたら必ずランクが変動してしまいますので、本質的なランキング確定をさせることができません。要件に応じて、他のデータストア等に結果を書き出すことをお勧めしますが、現在のプロジェクトでは、スコアを加算されない時間帯に入ることでランキング確定としています。スコアが加算さえされなければ順位が変動することが無いという考え方です。