Redis で現在のオンライン人数をゆるく取得する


概要

たまに見かける「今このページ○人がこのページを見ています」などの人数を Redis のソート済みセット型でカウントしてみました。

完全なリアルタイムではありませんが、直近 N 秒以内にアクセスしたユーザをオンラインユーザと見なすことで比較的簡単&低コストに取得出来ます。

セットする内容

  • キー名: 適当な固定値をセット
  • スコア: 最後にアクセスしたタイムスタンプをセット
  • メンバ: ユーザIDをセット

方法

1. 最終アクセス時間の追加 or 更新

アクセス時にアクセスしたユーザの UserID でメンバを追加します。
既に同じ UserID のメンバが存在する場合は最新のタイムスタンプに更新します。

(例) 2016-10-01 10:00:00 に UserID: 100 のユーザがアクセスした場合:

ZADD last_access_timestamps 1475283600 100 

2. オンライン人数の取得

ZCOUNT を使うと指定した範囲内のスコアのメンバ数をカウントできるので、取得したいタイミングの時刻から一定秒数前の秒数を最小値にしてカウントします。
+inf は限界の最大値を表すキーワードです。

(例) 2016-10-01 09:50:00 以降にアクセスしたユーザをカウントする場合:

ZCOUNT last_access_timestamps 1475283000 +inf

取得時の負荷について補足

ZCOUNT の計算量は以下のようになっています。

計算時間: O(log(N))+O(M) Nはソート済みセット内の要素の数、Mはコマンドによって返される要素の数です。もしMが一定ならO(log(N))となります。(たとえば LIMIT オプションを使って常に最初の要素を取ってくる場合)

オンライン人数が増えすぎると計算量が大きくなるので、場合によっては適当な人数を上限として LIMIT オプションを付けておいた方がいいと思います。