Redisの旅--Redis HyperLog(六)

4326 ワード

一、Redis HyperLog概要


Redis HyperLogは基数統計を行うアルゴリズムであり、HyperLogの利点は、入力要素の数や体積が非常に大きい場合、基数を計算するのに必要な空間が常に固定され、小さいことである.Redisでは、HyperLogキーごとに12 KBのメモリを消費するだけで、2^64個近くの異なる要素の基数を計算することができます.これは,基数を計算する際,要素が多ければ多いほどメモリを消費する集合とは対照的である.ただし、HyperLogは入力要素に基づいて基数を計算するだけであり、入力要素自体は格納されないため、HyperLogは集合のように入力された各要素を返すことはできない.
基数とは?たとえば、データセット{1,3,5,7,5,7,8}では、このデータセットの基数セットは{1,3,5,7,8}であり、基数(要素を繰り返さない)は5である.基数推定とは,誤差が許容できる範囲で基数を迅速に計算することである.
HyperLogLogは基数推定に基づくアルゴリズムであり,基数を比較的正確に推定することしかできず,一定のメモリを少量使用して集合中の一意の要素を格納し識別することができる.また,この推定の基数は必ずしも正確ではなく,0.81%の標準エラー(standard error)を伴う近似値である.
応用シーン:統計登録IP数/統計毎日アクセスIP数/統計ページリアルタイムUV数/統計オンラインユーザー数など注意:それにも限界があり、基数数数数しか統計できず、具体的な内容が何なのか分からない.これはbitmapと比較して、2つの特定の統計状況に属し、簡単に言えば、HyperLogLogの重量除去はbitmapよりずっと便利である.

二、命令


シーケンス番号コマンドおよび記述1 PFDD key element[element...]HyperLogLogに指定した要素を追加します.2 PFCOUNT key [key ...] 与えられたHyperLogの基数推定値を返します.3 PFMERGE destkey sourcekey [sourcekey ...] 複数のHyperLogを1つのHyperLogに統合
  • Redis PfaddコマンドRedis PfaddコマンドHyperLogデータ構造にすべての要素パラメータを追加します.
  • 127.0.0.1:6379> PFADD mykey a b c d e f g h i j
    (integer) 1
    127.0.0.1:6379> PFCOUNT mykey
    (integer) 10
    
  • Redis PfcountコマンドRedis Pfcountコマンド指定したHyperLogの基数推定値を返します.整数は、与えられたHyperLogの基数値を返し、複数のHyperLogの場合は基数推定値の和を返します.コマンドが単一のキーに作用すると、このキーの基数推定値が返されます.キーが存在しない場合は0を返します.複数のキーとして使用する場合は、これらのキーの並列推定値を返します.これらのキーを統合した後、このコマンド出力を呼び出すのと同じです.
  • redis 127.0.0.1:6379> PFADD hll foo bar zap
    (integer) 1
    redis 127.0.0.1:6379> PFADD hll zap zap zap
    (integer) 0
    redis 127.0.0.1:6379> PFADD hll foo bar
    (integer) 0
    redis 127.0.0.1:6379> PFCOUNT hll
    (integer) 3
    
    redis> PFADD  ip:20160929  "1.1.1.1"  "2.2.2.2"  "3.3.3.3"
    (integer) 1
    redis> PFCOUNT  ip:20160929
    (integer) 3
    redis> PFADD  ip:20160928  "1.1.1.1"  "4.4.4.4"  "5.5.5.5"
    (integer) 1
    redis> PFCOUNT  ip:20160928  ip:20160929
    (integer) 5
    
    
  • Redis PFMERGEコマンドRedis PFMERGEコマンド複数のHyperLogを1つのHyperLogにマージします.マージ後のHyperLogの基数推定値は、与えられたすべてのHyperLogを並列して計算します.構文redis PFMERGEコマンドの基本構文は、
  • です.
    PFMERGE destkey sourcekey [sourcekey ...]
    

    例:
    redis> PFADD hll1 foo bar zap a
    (integer) 1
    redis> PFADD hll2 a b c foo
    (integer) 1
    redis> PFMERGE hll3 hll1 hll2
    "OK"
    redis> PFCOUNT hll3
    (integer) 6
    redis>  
    

    三、基数の応用例

  • レコードサイトが毎日アクセスする独立IP数1)集合実装:集合を使用して各訪問者のIPを格納し、集合の性質(集合の各要素が異なる)によって複数の独立IPを得、SCARDコマンドを呼び出すことによって独立IPの数を得る.例えば、プログラムは、2014年8月15日、各サイトの訪問者のIP:SADD'2014.8.15:unique::ip'ipを使用して、当日の唯一のIP数を取得するために以下のコードを使用することができる:SCARD'2014.8.15:unique::ip'
  • 2)集合実装の問題は、各IPv 4アドレスを格納するために文字列を使用するには、最大15バイト(フォーマットは'XX.XX.XX.XX.XX.XXX'であり、例えば'202.189.128.186'である).以下の表は、集合記録の異なる数の独立IPを使用する場合、消費するメモリの数を示しています.独立IPの数は1日1ヶ月に1万15 MB 450 MB 5.4 GB 1千万150 MB 4.5 GB 54 GB 1億1.5 GB 45 GB 540 GBです.集合記録のIPがますます多くなるにつれて、消費するメモリもますます多くなります.
    redis> PFADD  ip:20160929  "1.1.1.1"  "2.2.2.2"  "3.3.3.3"
    (integer) 1
    redis> PFADD  ip:20160929 "2.2.2.2"  "4.4.4.4"  "5.5.5.5"  #        
    (integer) 1
    redis> PFCOUNT  ip:20160929  #           
    (integer) 5
    redis> PFADD  ip:20160929 "2.2.2.2"  #        
    (integer) 0
    
    
    
  • リアルタイムデータストリーム統計分析は、淘宝網店が店舗のトップページに10個の宝物リンクを配置し、それぞれItem 01からItem 10までが10個のリンク番号であると仮定している.店主は、今日の0時から現在までの10の宝物リンクがそれぞれ何人の独立訪問者にクリックされたかを一日でいつでも調べることを望んでいる.独立訪問者(Unique Visitor、略称UV)とは、何人かの自然人がいることを意味し、例えば、私が今日5回Item 01を注文しても、Item 01へのUV貢献は5ではなく1です.用語で言えば、これは実際にはリアルタイムデータストリーム統計分析の問題である.この統計的ニーズを実現するには.以下の3点を行う必要がある:1、独立した訪問者を識別する2、訪問者がリンクをクリックする時にリンク番号と訪問者マークを記録する3、統計するリンクごとに1つのデータ構造と1つの現在のUV値を維持し、あるリンクが1回クリックした時、このユーザーが今日このリンクをクリックしたことがあるかどうかを迅速に位置決めすることができ、もしなければこのリンクのUVは1
  • 増加する
    実現手順:1)独立した訪問者を識別する客観的に言えば,インターネット上で自然人を正確に識別する方法はまだなく,一般的に近似案を採用している.例えば、ログインユーザ+cookie追跡により、あるユーザがログインした場合、会員ID識別を採用する.ログインしていないユーザについては、クッキーを追跡する方式で識別される.簡単にするために、独立した訪問者を完全に追跡クッキーで識別すると仮定します.2)レコードリンク番号および訪問者タグは、JavaScript埋め込みポイントおよびレコードaccesslogによって行うことができる.3)リアルタイムUV計算各リンクがクリックされたログ内の訪問者識別フィールドを1つのセットと見なすと,このリンクの現在のUVはこのセットの基数であるため,UV計算は本質的に基数カウントの問題である.論理は非常に簡単で、クリックイベントが発生するたびに、対応するリンクが訪問された集合の中でこの訪問者がすでに中にいるかどうかを探し、もしそうでなければ、このユーザーIDを集合に追加し、このリンクのUVを1追加します.