重複排除のための HLL の使用
背景
現実のシナリオでは、データ量が増えるにつれてデータの重複排除の圧力が増します。データサイズがあるレベルに達すると、正確な重複排除のコストが比較的高くなります。この場合、ユーザーは通常、計算の負荷を軽減するために近似アルゴリズムを使用します。このセクションで紹介する HyperLogLog (HLL) は、優れた空間計算量 O(mloglogn) と時間計算量 O(n) を持つ近似重複排除アルゴリズムです。さらに、計算結果 の誤差率は、データセットのサイズや使用されるハッシュ関数に応じて約 1% ~ 10% に制御できます。
HyperLogLog とは
HyperLogLog は、非常に少ないストレージスペースを消費する近似重複排除アルゴリズムです。HLL タイプは、HyperLogLog アルゴリズムを実装するために使用されます。これは、HyperLogLog 計算の中間結果を保持し、データテーブルのインジケーター列タイプとしてのみ使用できます。
HLL アルゴリズムは多くの数学的知識を含むため、実用的な例を用いて説明します。コインを投げて最初に表が出るまで独立した反復を行うランダム化実験 A を設計し、最初に表が出るまでのコイン投げの回数をランダム変数 X として記録するとします。すると:
- X=1, P(X=1)=1/2
- X=2, P(X=2)=1/4
- ...
- X=n, P(X=n)=(1/2)n
テスト A を使用してランダム化テスト B を構築し、N 回の独立したテスト A の反復を行い、N 個の独立した同一分布のランダム変数 X1, X2, X3, ..., XN を生成します。ランダム変数の最大値を Xmax とします。大きな尤度推定を利用して、N の推定値は 2Xmax です。
与えられたデータセットに対してハッシュ関数を使用して上記の実験をシミュレートします:
- テスト A: データセット要素のハッシュ値を計算し、ハッシュ値をバイナリ表現に変換します。バイナリの最下位ビットから始めて、ビット=1 の出現を記録します。
- テスト B: テスト B のデータセット要素に対してテスト A プロセスを繰り返します。各テストの最初のビット 1 の出現の最大位置 "m" を更新します。
- データセット内の重複しない要素の数を m2 として推定します。
実際には、HLL アルゴリズムは要素のハッシュの下位 k ビットに基づいて要素を K=2k バケットに分割します。k+1 ビット目からの最初のビット 1 の出現の最大値を m1, m2,..., mk としてカウントし、バケット内の重複しない要素の数を 2m1, 2m2,..., 2mk として推定します。データセット内の重複しない要素の数は、バケットの数とバケット内の重複しない要素の数を掛けた合計平均です:N = K(K/(2-m1+2-m2,..., 2-mK))。
HLL は推定結果に補正係数を掛けて結果をより正確にします。
StarRocks SQL ステートメントを使用して HLL 重複排除アルゴリズムを実装する方法については、次の記事を参照してください https://gist.github.com/avibryant/8275649 。
SELECT floor((0.721 * 1024 * 1024) / (sum(pow(2, m * -1)) + 1024 - count(*))) AS estimate
FROM(select(murmur_hash3_32(c2) & 1023) AS bucket,
max((31 - CAST(log2(murmur_hash3_32(c2) & 2147483647) AS INT))) AS m
FROM db0.table0
GROUP BY bucket) bucket_values
このアルゴリズムは db0.table0 の col2 を重複排除します。
- ハッシュ関数
murmur_hash3_32を使用して col2 のハッシュ値を 32 ビット符号付き整数として計算します。 - 1024 バケットを使用し、補正係数は 0.721 で、ハッシュ値の下位 10 ビットをバケットの添字として使用します。
- ハッシュ値の符 号ビットを無視し、次の最上位ビットから下位ビットまでを開始し、最初のビット 1 の出現位置を決定します。
- 計算されたハッシュ値をバケットでグループ化し、
MAX集約を使用してバケット内の最初のビット 1 の出現の最大位置を見つけます。 - 集約結果はサブクエリとして使用され、すべてのバケット推定の合計平均にバケットの数と補正係数を掛けます。
- 空のバケット数は 1 です。
このアルゴリズムは、データ量が多い場合に非常に低い誤差率を持ちます。
これが HLL アルゴリズムの核心です。興味がある方は HyperLogLog 論文 を参照してください。
HyperLogLog の使用方法
- HyperLogLog 重複排除を使用するには、テーブル作成ステートメントでターゲットインジケーター列タイプを
HLLに設定し、集約関数をHLL_UNIONに設定する必要があります。 - 現在、集約モデルのみがインジケーター列タイプとして HLL をサポートしています。
- HLL タイプの列で
count distinctを使用する場合、StarRocks は自動的にHLL_UNION_AGG計算に変換します。