こんにちは。エンジニアの世界へようこそ。
今日は、Redisが持つ「魔法の道具箱」の中でも、特に異彩を放つHyperLogLog(ハイパーログログ)という仕組みについてお話しします。
「何十億ものユーザーの中から、今日ログインしたユニークな人数を数えたい」……もしこれを普通のプログラムでやろうとしたら、膨大なメモリを食いつぶし、サーバーは悲鳴を上げてダウンしてしまいます。
でも、RedisのHyperLogLogを使えば、驚くほど小さなメモリで、ほぼ正確な数字を導き出せます。なぜそんなことができるのか? 一緒に紐解いていきましょう。
—
1. 「正確さ」を少しだけ捨てて、「手軽さ」を手に入れる
まず、HyperLogLogは「確率的データ構造」です。
これを聞いて「えっ、正確じゃないの?」と不安になるかもしれませんね。でも、安心してください。
日常の例えで説明しましょう。
あなたは大きな砂浜で、何万個もの貝殻が落ちているとします。全ての貝殻を一つずつ拾い集めて数えるのは地獄ですよね? でも、「砂の山を崩して、特定の模様の貝殻がどのくらいの割合で混ざっているか」を調べれば、全体の数は「だいたいこのくらい」と推測できます。
HyperLogLogは、まさにこの「推測の天才」です。わずかな誤差(通常1%未満)を許容する代わりに、12KBという極小のメモリで、何十億ものデータでもカウントできてしまうのです。
2. 基本のコマンドを使いこなそう
RedisでHyperLogLogを扱うコマンドは、たった3つだけ。これだけで、高度な統計処理ができてしまいます。
① PFADD:データを登録する
「このユーザー(ID: 101)が来たよ!」と記録するコマンドです。
ユーザーIDを「daily_log」という箱に追加
PFADD daily_log “user:101” “user:102” “user:103”
出力: 1 (新しく追加されたら1、既にあれば0が返る)
② PFCOUNT:人数を数える
今、何人いるかを推測します。
「daily_log」に何人いるか確認
PFCOUNT daily_log
出力: 3 (だいたいの人数が返ってくる)
③ PFMERGE:データを合体させる
「昨日のログ」と「今日のログ」を合体させて、2日間のユニーク合計を出したいときに使います。
daily_log_1 と daily_log_2 をあわせて total_log に統合
PFMERGE total_log daily_log_1 daily_log_2
—
3. なぜこんなに効率的なのか?(設計思想の本質)
さて、ここからがエンジニアとしての「魂」の話です。
なぜ12KBで何億もの数を扱えるのか。それは、「中身を覚える」のではなく「ハッシュ値の並び方の傾向」だけを記録しているからです。
HyperLogLogは、入力されたデータをハッシュ化(複雑な変換)し、その数値の「先頭に0が何個並んでいるか」を記録します。
- 0が1つも並ばないような稀な数値が出たとき、「お、これは珍しいデータが来たな」と判断する。
- それを積み重ねていくと、全体のデータ量に対して「0が何個並ぶか」という偏りが決まってくる。
この「偏りの統計」をとっているだけなので、元のデータ(ユーザーIDなど)を一切保存する必要がない。だから、メモリが爆発しないのです。
4. 最後に:使い所の見極めが「一流」への一歩
HyperLogLogを使う上で、これだけは覚えておいてください。
「厳密に1人単位でカウントしなければならない場面には使わない」
例えば、銀行の残高管理や、特定のユーザーIDをリストアップしてメールを送るような場面には向きません。一方で、「Webサイトのアクセス数」「記事のユニークビュー数」「広告のリーチ数」のように、「大まかなトレンドを高速かつ省エネで知りたい」という場面では、これ以上の武器はありません。
—
いかがでしたか?
「正確さ」をあえて手放し、統計的な推測に委ねる。この潔い設計こそが、Redisが世界中の巨大サービスで愛されている理由です。
ここをクリアしたあなたは、もうRedisの「知恵」に触れました。次はぜひ、自分のプロジェクトで「この数、数えるの面倒だな……」と思った時に、そっとHyperLogLogを思い出してみてください。
それでは、素晴らしいコードライフを!
コメント