【入門編】 HyperLogLog:基数推定 – Redis

やあ。Redisの世界へようこそ。
システム開発をしていると、「このWebサイト、今日何人の『ユニークな』ユーザーが訪れたんだろう?」なんて計算をしたくなる場面は必ず訪れるよね。

普通に考えると、ユーザーIDを全部リストに溜め込んで、後で重複を削除して数える……という手順になる。でも、もしそのサイトが数百万、数千万アクセスあったらどうなると思う? メモリを食いつぶし、サーバーは悲鳴を上げ、君の貴重なPCも熱を持ってしまうはずだ。

そんな時、Redisの魔術のようなデータ構造「HyperLogLog(ハイパーログログ)」が、君の悩みを一瞬で解決してくれる。今日は、この「メモリの極限を攻める」魔法の道具について、一緒に深掘りしていこう。

—

HyperLogLogは「大雑把な天才」

まず、HyperLogLogを一言で言うと「誤差を許容する代わりに、メモリを死ぬほど節約するユニークカウント器」だ。

例えるなら、スタジアムにいる観客の数を正確に数えるのではなく、「まあ、大体このくらいだな」と推測する超優秀な観察者のようなもの。しかも、どれだけ人数が増えても、使うメモリ量は常に一定(最大12KB程度!)という凄まじい性質を持っているんだ。

基本の3コマンドを使いこなそう

Redisでの操作は、驚くほどシンプルだ。「PF」という接頭辞は、このアルゴリズムを考案したPhilippe Flajolet教授のイニシャルから来ている。敬意を込めて叩こう。

1. PFADD:記録する

新しいデータ(ユーザーIDなど)をカウント対象に追加するコマンドだ。

「user:101」さんが来た!と記録する
PFADD visits “user:101”
結果:1 (新しいユニークな要素が追加された)

また「user:101」さんが来た!
PFADD visits “user:101”
結果:0 (すでに記録済みなのでカウントされない)

2. PFCOUNT:数える

現在までにおおよそ何個のユニークな要素があるかを算出する。

PFADD visits “user:102” “user:103” “user:104”
PFCOUNT visits
結果:4 (おおよそ4人だと教えてくれる)

3. PFMERGE:まとめる

複数のHyperLogLogを合体させるコマンドだ。「昨日のアクセス」と「今日のアクセス」を合体させて、「この2日間で何人のユニークユーザーがいたか」を知るのに最適だよ。

昨日のデータと今日のデータを合体させて「total_visits」に保存
PFMERGE total_visits visits_yesterday visits_today

—

なぜこれが「伝説的」なのか?

ここがエンジニアとして知っておいてほしい核心部分だ。

通常、10億人のユニークユーザーを数えようとしたら、IDを保持するだけで何ギガバイトものメモリが必要になる。しかし、HyperLogLogは「データの内容」ではなく「データのハッシュ値のパターン」を観測しているんだ。

「0がどれだけ連続して並ぶか」という確率的な性質を利用しているから、どれだけデータが膨大になっても、消費するメモリは12KB程度で固定される。「正確さ」をわずかな誤差(約0.81%)と引き換えに、「圧倒的な速度と省メモリ」を手に入れたわけだね。

どんな時に使うべきか?

  • リアルタイムのPV/UU計測: 正確な数字よりも、トレンドを素早く掴みたい時。
  • 大規模なログ分析: 数億単位のユニーク数をメモリ制限の中で管理したい時。

逆に、「1円単位の厳密さが求められる課金データ」や「ユーザーIDの完全なリストが必要な場合」には使ってはいけない。 それは別のデータ構造(Setなど)の出番だ。

—

先輩からのアドバイス

「完璧」を目指すあまり、すべてのデータを厳密に管理しようとすると、システムは必ずどこかで息切れする。特に大規模なアプリケーションでは、「どこまでなら誤差を許容できるか」を見極めることこそが、一流エンジニアのセンスなんだ。

HyperLogLogは、そのセンスを鍛えるための最高の武器になる。
最初は不思議に思うかもしれないけれど、実際に触って、その軽快なレスポンスを体感してみてほしい。「こんなに少ないメモリで、数百万のデータを数えられるのか!」という感動を、ぜひ君自身の手で味わってくれ。

ここをクリアした君なら、もうRedisの基本的なデータ構造の概念はバッチリマスターしたも同然だ。自信を持って、次のステップへ進もう!

コメント

タイトルとURLをコピーしました