Redis HyperLogLog

HyperLogLogはカーディナリティ推定に使用される確率的データ構造です。このレッスンでは、その使用方法について解説します。

HyperLogLogとは

HyperLogLogの特徴:

💡 比較:

  • Setを使用:すべての要素を保存、メモリ使用量大
  • HyperLogLogを使用:わずか12KB、ただし結果は近似値
Set:100万の一意な要素を保存 → 約10MBのメモリ
HyperLogLog:100万の一意な要素をカウント → わずか12KBのメモリ

PFADD:要素の追加

基本的な使用方法

REDIS
# 単一の要素を追加
PFADD uv:20260623 "user:1"
(integer) 1  # カーディナリティが変更された可能性がある場合は1を返す

# 複数の要素を追加
PFADD uv:20260623 "user:2" "user:3" "user:4"
(integer) 1

# 既存の要素を追加
PFADD uv:20260623 "user:1"
(integer) 0  # カーディナリティが変更されていない場合は0を返す

自動重複排除

REDIS
# HyperLogLogは自動的に重複を排除
PFADD uv:20260623 "user:1" "user:1" "user:2"
(integer) 0  # user:1は既に存在、user:2のみ新規
⚠️ 補足: HyperLogLogは要素自体を保存しません。内部統計のみを更新します。実際の要素リストを取得することはできません。

PFCOUNT:カーディナリティを取得

REDIS
PFADD uv:20260623 "user:1" "user:2" "user:3" "user:4"

# 一意な要素の数を取得
PFCOUNT uv:20260623
(integer) 4

# 重複要素を追加
PFADD uv:20260623 "user:1" "user:5"

# カーディナリティが1増加(user:5)
PFCOUNT uv:20260623
(integer) 5

複数のHyperLogLogの和集合をカウント

REDIS
# 複数のHyperLogLogを作成
PFADD uv:20260622 "user:1" "user:2" "user:3"
PFADD uv:20260623 "user:2" "user:3" "user:4"

# 2日間のUVの和集合をカウント
PFCOUNT uv:20260622 uv:20260623
(integer) 4  # user:1, user:2, user:3, user:4
💡 使用例: PFCOUNTは、事前にマージしなくても複数のHyperLogLogの和集合をカウントできます。

PFMERGE:HyperLogLogのマージ

PFMERGEは複数のHyperLogLogを1つにマージします。

基本的な使用方法

REDIS
# 複数のHyperLogLogを作成
PFADD uv:20260622 "user:1" "user:2"
PFADD uv:20260623 "user:2" "user:3"
PFADD uv:20260624 "user:3" "user:4"

# 新しいHyperLogLogにマージ
PFMERGE uv:week uv:20260622 uv:20260623 uv:20260624
OK

# マージされたカーディナリティを表示
PFCOUNT uv:week
(integer) 4  # user:1, user:2, user:3, user:4

既存のHyperLogLogにマージ

REDIS
# 既存のHyperLogLogにマージ(上書き)
PFMERGE uv:20260622 uv:20260623
OK

PFCOUNT uv:20260622
(integer) 3  # user:1, user:2, user:3

HyperLogLogのユースケース

ユースケース1:WebサイトのUV統計

REDIS
# 日次UV
PFADD uv:daily:20260623 "user:1"
PFADD uv:daily:20260623 "user:2"
PFADD uv:daily:20260623 "user:3"

# 今日のUVを表示
PFCOUNT uv:daily:20260623
(integer) 3

# 週次UV
PFMERGE uv:weekly:2026w25 uv:daily:20260617 uv:daily:20260618 ... uv:daily:20260623
PFCOUNT uv:weekly:2026w25

ユースケース2:記事の読者数

REDIS
# 記事の読者数
PFADD article:123:readers "user:1"
PFADD article:123:readers "user:2"
PFADD article:123:readers "user:3"

# 読者数を表示
PFCOUNT article:123:readers
(integer) 3

ユースケース3:検索キーワード統計

REDIS
# 今日の検索キーワード(一意)
PFADD search:keywords:20260623 "redis"
PFADD search:keywords:20260623 "mysql"
PFADD search:keywords:20260623 "redis"

# 一意なキーワード数を表示
PFCOUNT search:keywords:20260623
(integer) 2

ユースケース4:オンラインユーザー数

REDIS
# 現在のオンラインユーザー
PFADD online:users "user:1"
PFADD online:users "user:2"
PFADD online:users "user:3"

# オンラインユーザー数を表示
PFCOUNT online:users
(integer) 3

# ユーザーがオフライン(HyperLogLogを再構築する必要がある、面倒)
# HyperLogLogは個々の要素の削除をサポートしていない

ユースケース5:API呼び出し統計

REDIS
# API呼び出しユーザー
PFADD api:users:get:user 1001
PFADD api:users:get:user 1002
PFADD api:users:get:user 1003

# 一意な呼び出し元の数を表示
PFCOUNT api:users:get:user
(integer) 3

HyperLogLogとSetの比較

メモリ比較

データサイズ Setのメモリ HyperLogLogのメモリ
10K ~800KB 12KB
100K ~8MB 12KB
1M ~80MB 12KB
10M ~800MB 12KB
💡 結論: HyperLogLogのメモリ使用量はデータサイズに関係なく一定の12KBです。

精度比較

データ構造 精度 使用例
Set 正確 正確なカウントが必要、要素リストが必要
HyperLogLog 近似(0.81%の誤差) 大規模データ、カーディナリティのみ、メモリ制約あり

機能比較

機能 Set HyperLogLog
要素の追加 ✅ SADD ✅ PFADD
要素の削除 ✅ SREM ❌ 非サポート
要素リストの取得 ✅ SMEMBERS ❌ 非サポート
要素の存在確認 ✅ SISMEMBER ❌ 非サポート
カーディナリティ取得 ✅ SCARD ✅ PFCOUNT
マージ ✅ SUNIONSTORE ✅ PFMERGE

HyperLogLogの精度テスト

テストコード

REDIS
# 100万の異なる要素を追加
for i in range(1000000):
    PFADD test:hll f"user:{i}"

# 結果を表示
PFCOUNT test:hll
(integer) 1000123  # わずかに誤差あり、誤差約0.012%
ℹ️ 補足: HyperLogLogの標準誤差は約0.81%ですが、実際の誤差はより小さいことがよくあります。

HyperLogLogの制限

1. 要素を削除できない

REDIS
# HyperLogLogは個々の要素の削除をサポートしていない
# 削除が必要な場合は、HyperLogLog全体を再構築する必要がある

2. 要素リストを取得できない

REDIS
# HyperLogLogは要素自体を保存しない
# SetのSMEMBERSのようにすべての要素を取得することはできない

3. 結果は近似値

REDIS
# HyperLogLogは近似のカーディナリティを返す
# 正確ではなく、約0.81%の誤差がある

4. 要素の存在を確認できない

REDIS
# HyperLogLogは要素の存在確認をサポートしていない
# SetのSISMEMBERのように使用することはできない

HyperLogLogを使用するタイミング

HyperLogLogを使用する場合:

Setを使用する場合:

❓ よくある質問

Q HyperLogLogの誤差はどのくらいですか?
A 標準誤差は約0.81%です。100万のデータポイントでは、誤差は約8000です。実際の誤差はより小さいことが多いです。
Q HyperLogLogはどのくらいのメモリを使用しますか?
A 各HyperLogLogはデータサイズに関係なく、固定の12KBのメモリを使用します。
Q HyperLogLogはいくつの要素を保存できますか?
A 理論上は無制限(2^64)ですが、実際には精度によって制限されます。データセットが大きいほど相対誤差は小さくなります。
Q HyperLogLogから要素を削除するにはどうすればよいですか?
A サポートされていません。HyperLogLog全体を削除するか(DELコマンド)、再構築するしかありません。
Q HyperLogLogとSetの選び方は?
A 正確なカウントや要素リストが必要な場合はSetを使用します。大規模なカーディナリティ推定にはHyperLogLogを使用します。

📖 まとめ

📝 練習問題

  1. UV統計: HyperLogLogを使用して日次UVを追跡し、複数のユーザー訪問をシミュレートしましょう
  2. 複数日の統計: 複数日のUV HyperLogLogを作成し、PFMERGEを使用して週次UVを取得しましょう
  3. 精度テスト: 1000の異なる要素を追加し、PFCOUNTの結果と実際のカウントを比較しましょう
  4. 比較テスト: 同じデータでSetとHyperLogLogのメモリ使用量を比較しましょう

次のレッスン

次のレッスンでは、Redis Pub/Subについて学びます。メッセージの公開と購読について解説します。

100%