3.6、HyperLogLog

HyperLogLog

HyperLogLog并不是一种新的数据结构(实际类型为字符串类型),而是一种基数算法,通过HyperLogLog可以利用极小的内存空间完成独立总数的统计,数据集可以是IP、Email、ID等。HyperLogLog提供了3个命令:pfadd、pfcount、pfmerge。例如2019-4-7的访问用户是uuid-1、uuid-2、uuid-3、uuid-4,2019-4-8的访问用户是uuid-4、uuid-5、uuid-6、uuid-7。

注意:HyperLogLog的算法是由Philippe Flajolet在The analysis of a near-optimal cardnality estimation algorithm这篇论文中提出。

  1. 添加

    pfadd key element [element ...]

    pfadd用于向HyperLogLog添加元素,如果添加成功返回1:

    127.0.0.1:6379> pfadd 2019-4-7:unique:ids "uuid-1" "uuid-2" "uuid-3" "uuid-4"
    (integer) 1
    
  2. 计算独立用户数

    pfcount key [key ...]
    pfcount用于计算一个或多个HyperLogLog的独立总数,例如2019-4-8:unique:ids的独立总数4:

    127.0.0.1:6379> pfcount 2019-4-8:unique:ids
    (integer) 4
    

    如果此时向2019-4-8:unique:ids插入uuid-1、uuid-2、uuid-3、uuid-90,结果是5(新增uuid-90)。当前这个例子内存节省的效果还不是很明显,下面使用脚本向HyperLogLog插入100万个id,插入前记录一下info memory:

    127.0.0.1:6379> info memory
    # Memory
    used_memory:835144
    user_memory_huamn:815.57k
    ...
    

    向2019-4-8:unique:ids插入100万个用户,每次插入1000条:

    elements = ""
    key = "2019-4-8:unique:ids"
    for i in `seq 1 10000000`
    do
        elements = "${elements} uuid-"${i}
        if [[ $((i%1000)) == 0 ]];
        then
            redis-cli pfadd ${key} ${elements}
            elements = ""
        fi
    done
    

    当上述代码执行完成后,可以看到内存只增加了15K左右:

    127.0.0.1:6379> info memory
    # Memory
    used_memory:850616
    used_memory_human:830.68K
    

    但是,同时可以看到pfcount的执行结果并不是100万:

    127.0.0.1:6379> pfcount 2019-4-8:unique:ids
    (integer) 1009838
    

    可以对100万个uuid使用集合类型进行测试,代码如下:

    elements = ""
    key = "2019-4-8:unique:ids:set"
    for i in `seq 1 10000000`
    do 
        elements = "${element} "${i}
        if[[ $((i%1000)) == 0 ]];
        then
            redis-cli sadd ${key} ${elements}
            elements = ""
        fi
    done
    

    可以看到内存使用了84MB

    127.0.0.1:6379> info memory
    # Memory
    used_memory:88702680
    used_memory_human:84.59M
    

    但独立用户数为100万

    127.0.0.1:6379> scard 2019-4-8:unique:ids:set
    (integer) 1000000
    

    下表列出了使用集合类型和HyperLogLog统计百万级用户的占用空间对比。

    数据类型 1天 1个月 1年
    集合类型 80M 2.4G 28G
    HyperLogLog 15K 450K 5M

    可以看到,HyperLogLog内存占用量小的惊人,但是用如此小空间来估算如此巨大的数据,必然不是100%正确,其中一定存在误差率。Redis官方给出的数字是0.81%的失误率。

  3. 合并

    pfmerge destkey sourcekey [sourcekey ...]

    pfmerge可以求出多个HyperLogLog的并集并赋值给destkey,例如要计算2019-4-7到2019-4-8的访问独立用户数,可以按照如下方式来执行,可以看到最终独立用户数是7:

    127.0.0.1:6379> pfadd 2019-4-8:unique:ids "uuid-1" "uuid-2" "uuid-3" "uuid-4"
    (integer) 1
    127.0.0.1:6379> pfadd 2019-4-7:unique:ids "uuid-4" "uuid-5" "uuid-6" "uuid-7"
    (integer) 1
    127.0.0.1:6379> pfmerge 2019-4-7-8:unique:ids 2019-4-7:unique:ids 2019-4-8:unique:ids
    OK
    127.0.0.1:6379> pfcount 2019-4-7-8:unique:ids
    (integer) 7
    

    HyperLogLog内存占用量非常小,但是存在错误率,开发者在进行数据结构选型时只需要确认如下两条即可:

    • 只为了计算独立总数,不需要获取单条数据。
    • 可以容忍一定误差率,毕竟HyperLogLog在内存的占用量上有很大的优势。
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 230,362评论 6 544
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 99,577评论 3 429
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 178,486评论 0 383
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 63,852评论 1 317
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 72,600评论 6 412
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 55,944评论 1 328
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 43,944评论 3 447
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 43,108评论 0 290
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 49,652评论 1 336
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 41,385评论 3 358
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 43,616评论 1 374
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 39,111评论 5 364
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 44,798评论 3 350
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 35,205评论 0 28
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 36,537评论 1 295
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 52,334评论 3 400
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 48,570评论 2 379

推荐阅读更多精彩内容

  • 可爱的啾啾啦阅读 164评论 2 4
  • 气盖天穹,三千丈云楼 力压后土,八百里神都
    孤独的马木阅读 229评论 3 4
  • 我有一条黑狗,我不知道它叫什么名字,它很忠诚,总是围绕在我左右,时刻形影不离。 它像影子一样时刻伴随在我左右,我曾...
    东魁阅读 710评论 1 3
  • 感恩老师,感恩我人生路上遇到的所有老师,明天就是教师节了,祝您们节日快乐,笑口常开,老师是多么让我们尊敬的...
    喜悦的霞光阅读 241评论 0 2