Redis HyperLogLog
HyperLogLogはカーディナリティ推定に使用される確率的データ構造です。このレッスンでは、その使用方法について解説します。
HyperLogLogとは
HyperLogLogの特徴:
- カーディナリティ推定:一意な要素の数をカウントします
- 非常に小さなメモリ:各HyperLogLogはわずか12KBを使用します
- 近似カウント:標準誤差約0.81%で、大規模データに適しています
- 要素自体を保存しない:統計情報のみを保存します
💡 比較:
- 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を使用する場合:
- WebサイトのUV(ユニークビジター)のカウント
- 記事の読者数のカウント
- 検索キーワードのカウント
- APIユーザーのカウント
- 大規模なカーディナリティ推定
- メモリ制約のあるシナリオ
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を使用します。
📖 まとめ
- HyperLogLogはカーディナリティ推定用で、一定の12KBメモリを使用
- PFADDで要素を追加、自動重複排除
- PFCOUNTでカーディナリティを取得、複数のHyperLogLogの和集合をカウント可能
- PFMERGEで複数のHyperLogLogをマージ
- 標準誤差は約0.81%、大規模データセットに適している
- 要素の削除不可、要素リストの取得不可、結果は近似値
- 使用例:UV統計、読者数、検索キーワード、オンラインユーザー
📝 練習問題
- UV統計: HyperLogLogを使用して日次UVを追跡し、複数のユーザー訪問をシミュレートしましょう
- 複数日の統計: 複数日のUV HyperLogLogを作成し、PFMERGEを使用して週次UVを取得しましょう
- 精度テスト: 1000の異なる要素を追加し、PFCOUNTの結果と実際のカウントを比較しましょう
- 比較テスト: 同じデータでSetとHyperLogLogのメモリ使用量を比較しましょう
次のレッスン
次のレッスンでは、Redis Pub/Subについて学びます。メッセージの公開と購読について解説します。



