1. HyperLogLogとは
1. 初期の HyperLogLog
Redis の HyperLogLog は、カーディナリティ推定に基づいたアルゴリズムであり、いわゆるカーディナリティ推定とは、データ バッチ内の固有の要素の数です。
カーディナリティ カウントとは、セットのカーディナリティを計算することを指します。これは、count-discint を意味します。カーディナリティの計算には、Web サイトのアクセス UV の計算や、ネットワーク攻撃の重要な指標としてのネットワーク トラフィック パケット要求ヘッダー内の送信元アドレスの個別の数の計算など、幅広いシナリオがあります。カーディナリティ カウントを実現する最も直接的な方法は、辞書/HashSet を使用することです。各データが流入した後、対応するキーを直接保存し、最終的にセットのサイズを統一することでセットのカーディナリティを取得します。ただし、この方法の空間の複雑さは非常に高く、大規模なデータのシナリオに直面してそのような統計を実行するコストは非常に高くなります。ここ数十年で,一部の学者はカーディナリティ推定アルゴリズムを多数提案してきました.一定の誤差を許容するという条件の下で,推定は統計的確率に基づいています.本稿のHyperLogLogはカーディナリティ推定に基づいたアルゴリズムです.
2. HyperLogLog でできること
- 統計登録IP番号
- 日々のアクセスIP数の統計
- 統計ページのリアルタイム UV 数
- オンラインユーザーの数を数える
- ユーザーが毎日検索したさまざまな用語の数をカウントします
3. Redis の HyperLogLog
久しぶりに出てきて、Redis での HyperLogLog の使い方を長々と説明しましたが、HyperLogLog には現在PFADD (要素の追加)、PFCOUNT (指定されたカーディナリティの推定値を返す)、PFMERGE (複数の要素のマージ) の 3 つのメソッドがあります。 HyperLog は 1 つの HyperLogLog にログインします)。各メソッド コマンドの意味を文字通りの意味から理解するのは難しくありません (曲がったナットの名前は今でもよく知られています)。
ヒント: =Redis HyperLogLog を使用する場合は、redis バージョン >=2.8.9 を使用してください。
1、パスハードディスク
redis> PFADD hll1 foo bar zap a
(integer) 1
2、PFCOUNT
redis> PFCOUNT hll1
(integer) 4
3、プマージ
redis> PFADD hll2 a b c foo
(integer) 1
redis> PFMERGE hll3 hll1 hll2
"OK"
redis> PFCOUNT hll3
(integer) 6
4、HyperLogLog原則
上記では HyperLogLog の使用シナリオとコマンドを簡単に紹介しましたが、次に HyperLogLog の原理について説明します。
HyperLogLog アルゴリズムの基本的な考え方は、ベルヌーイ プロセスから来ています。ベルヌーイ過程はコインを投げるプロセスです。通常のコインを投げた場合、表が出る場合も裏が出る場合もあり、両方の確率は 1/2 です。ベルヌーイ プロセスでは、表が出るまでコインを投げ、投げた回数 k を記録します。たとえば、コインを 1 回投げて表が出た場合、k は 1 です。
では、ベルヌーイ法を使用してコイントスが何回行われたかをどのように推定するのでしょうか? また、1 は表、0 は裏を意味すると仮定します。0が2回連続して現れる数列は「001」とすると、その出現確率は2分の1を3回掛けた8分の1になります。すると、コイントスは約8回あったと推定できます。
HyperLogLog の原理的な考え方は、指定された n 個の要素セット内のデジタル ビット列の最初の 1 個の出現位置の最大値 k を記録することです。これは、連続してゼロであるバイナリの下位ビットの最大数をカウントすることとしても理解できます。 (先行ゼロ)。セット内の固有の要素の数 m は k の値によって推定でき、m は 2^k にほぼ等しくなります。ただし、この計算は概算にすぎず、あまり正確ではありません。Redis の HyperLogLog はバケットの最適化に基づいています。
バケット化とは、ラウンドを何回に分割するかです。コンピュータのストレージに抽象化すると、ビット (bit) 単位、長さ L の大きな配列 S を格納し、S を平均して m 個のグループに分割します。ただし、m 個のグループはラウンド数に対応し、各グループは占有ビット数は平均であり、P に設定されます。次の関係を導き出すのは簡単です。
- L = Sの長さ
- L = m * p
- K 単位で、S = L / 8 / 1024 が占めるメモリ
Redis の HyperLogLog 設定は、m=16834、p=6、L=16834 * 6 です。占有メモリは =16834 * 6 / 8 / 1024 = 12K
次のように視覚化されます。
第0组 第1组 .... 第16833组
[000 000] [000 000] [000 000] [000 000] .... [000 000]
現実に戻ってバケットがどのように割り当てられているかを確認する
- 挿入された値は 11613999 です
- ハッシュ値を422726274として計算します。
- バケットの添字が次の 6 ビットで計算されると仮定すると、バイナリ変換は 2、つまりバケット M の位置は 2 になります。
- 残りのビット列の下位から上位までの最初の 1 は 2 です。つまり、2 をバケットに入れます。
- 設定する前に、バケット内の値がバケット内の古い値より大きいかどうかを設定する必要があり、大きい場合のみ設定し、そうでない場合は設定しません。
- 最後に、カーディナリティの推定値がすべてのバケットから取得されます。
最後に、各バケットの値を次の DV 式に代入して、最終的なカーディナリティの推定値を計算します。
上記の動的に生成されたツールに興味がある方は、「今日のスケッチ: HyperLogLog — ビッグ データ インフラストラクチャの基礎 – AK Tech Blog」にアクセスして視聴できます。
五、終わり
Redis の HyperLogLog については、ここに書かれています。この記事では、HyperLogLog を通じて関連する対応するナレッジ ポイントのみをリストします。具体的で詳細なナレッジ ポイントに興味がある場合は、学習を続けることができます。
参考記事
HyperLogLogJAVAアルゴリズム実装プロジェクト