pcsmartphone【サイトURL】
Which is Hot?
http://WhichisHot.in/

【ブログ記事】
このカテゴリ記事一覧

前回に続きまして、今回はリアルタイム・ランキングついて書きたいと思います。

大勢のプレイヤーが同時にアクセスして遊ぶゲームでは現在自分が何位なのか、ポイントを獲得して今何位に変わったのか、というように、順位をリアルタイム知ることでより面白味が増していきます。プレイヤーが100人程度であれば、単純に100人の得点をソートして順位付けすれば簡単に順位が求められます。しかしプレイヤーが100万人いたらどうでしょう?それだけのデータをリアルタイムに集計していたら、待っている間にカップラーメンが出来てしまいそうです。

Which is Hot?ではTwitterのユーザーを対象にしていますから、1億4千万ユーザーの順位をリアルタイムに集計できるようにしなければなりません(1億4千万も集まるのかというのはまた別の話で)。そこでどうやったら高速且つ簡単にリアルタイムランキングが可能か調べていたところ、以下の記事を見つけました。

gumi Engineer’s Diary
15行で書くソーシャルゲームのリアルタイム・ランキング

この発想は目から鱗です。ものすごく詳しく解説されているので、詳しい仕組みは↑この記事を読んでみてください。変化前の得点の順位を+1するだけです。

最初の時点

<ユーザー別の得点データ>
・Aさんの得点:0点
・Bさんの得点:0点
・Cさんの得点:0点
<得点別の順位データ>
・0点の人:★☆☆☆☆ (1)
・1点の人:☆☆☆☆☆ (0)
・2点の人:☆☆☆☆☆ (0)

→最初の時点では0点の人の順位が1位になっています。全員0点なのだから全員1位です。

Aさんが得点を入れた場合

<ユーザー別の得点データ>
・Aさんの得点:1点
・Bさんの得点:0点
・Cさんの得点:0点
<得点別の順位データ>
・0点の人:★☆☆☆ (2)
・1点の人:☆☆☆☆ (1)
・2点の人:☆☆☆☆☆ (0)

→Aさんの変更前の点数が0点なので、0点の順位を+1します。新しい点数が現れたので、1点の順位も+1(値1で新規作成)します。これで1点の人は1位、0点の人は2位ということがわかります。

Bさんが得点を入れた場合

<ユーザー別の得点データ>
・Aさんの得点:1点
・Bさんの得点:1点
・Cさんの得点:0点
<得点別の順位データ>
・0点の人:★★☆☆ (3)
・1点の人:★☆☆☆☆ (1)
・2点の人:☆☆☆☆☆ (0)

→Bさんの変化前の得点は0なので、0点の順位を+1します。1点の順位はすでにAさんが作成しているので何もしません。これで1点の人は1位、0点の人は3位ということがわかります。

Aさんが得点を入れた場合

<ユーザー別の得点データ>
・Aさんの得点:2点
・Bさんの得点:1点
・Cさんの得点:0点
<得点別の順位データ>
・0点の人:★★★☆☆ (3)
・1点の人:★☆☆☆ (2)
・2点の人:☆☆☆☆ (1)

→Aさんの変更前の点数が1点なので、1点の順位を+1します。新しい点数が現れたので、2点の順位も+1(値1で新規作成)します。これで2点の人は1位、1点の人は2位、0点の人は3位だということがわかります。

いかがでしたでしたでしょうか。2~3件の程度のデータを更新するだけで、簡単に順位が求められました。これならどんなにデータ件数が多くても高速に処理が可能です。

【順位の求め方】現在の得点は何点? → ○点の順位は何位?

デメリットと言えば、得点が1点ずつ増えていくときは良いが、一気にたくさん増えると効率が悪いというところです。もし一気に100点増えた場合は100回繰り返さなくてはなりません。幸いWhich is Hot?は1点ずつ増えていく仕組みになっていますから、この方法がぴったりだったのです。

さて、これで「誰が何位か?」がわかるようになりました。しかし逆に「何位は誰か?」はこの方法ではわかりません。たぶんこの仕組みに+αでできると思いますが、Which is Hot?では、面倒だったのでオーソドックスな集計方法のままいきました、

【順位別のユーザー一覧の求め方】
$ cat logfile | sort | uniq -c | sort -nr

投票されたIDをログファイルに記録していき、それをcronで定期的に集計しているだけです。投票回数が増えれば破綻する方式ですが、破綻しそうになったらちゃんと考えようと思います。中途半端ですいません。

ということで、今日はここまで。
次回はサーバーのハードウェア構成について書いていきたいと思います。

Which is Hot?http://WhichisHot.in/

LINEで送る
Pocket