Redis-HyperLogLog 比眉伴天荒 2022-05-22 10:28 160阅读 0赞 HyperLogLog命令是redis在2.8版本中加入的,Redis中HyperLogLog是用来做基数统计的。 HyperLogLog 的优点是,在输入元素的数量或者体积非常非常大时,计算基数所需的空间总是固定的、并且是很小的,因此每个 HyperLogLog 键只需要花费 12 KB 内存,就可以计算接近 264 个不同元素的基数。但是HyperLogLog也存在缺点,就是它是估计基数的算法,所以会有一定误差0.81%,而且无法获取具体的元素值。因此应用在对准确性不是很重要的场景,例如:QQ同时在线人数,网站IP访问数量等等。 详情可以参考:[https://chenjiehua.me/database/hyperloglog-bigdata.html][https_chenjiehua.me_database_hyperloglog-bigdata.html] 和[https://blog.csdn.net/firenet1/article/details/77247649][https_blog.csdn.net_firenet1_article_details_77247649] 顺便附上本地测试的小例子: package com.redis.hyperLoglog; import com.redis.util.RedisUtil; import org.junit.jupiter.api.Test; import redis.clients.jedis.Jedis; /** * HyperLoglog * 基数计数(cardinality counting)通常用来统计一个集合中不重复的元素个数,例如统计某个网站的UV, * 或者用户搜索网站的关键词数量。数据分析、网络监控及数据库优化等领域都会涉及到基数计数的需求。 * 要实现基数计数,最简单的做法是记录集合中所有不重复的元素集合Su,当新来一个元素xi,若Su中不包含元素xi,则将xi * 加入Su,否则不加入,计数值就是Su的元素数量。这种做法存在两个问题: * 1.当统计的数据量变大时,相应的存储内存也会线性增长; * 2.当集合Su变大,判断其是否包含新加入元素xi的成本变大 * 大数据量背景下,要实现基数计数,首先需要确定存储统计数据的方案,以及如何根据存储的数据计算基数值; * 另外还有一些场景下需要融合多个独立统计的基数值,例如对一个网站分别统计了三天的UV, * 现在需要知道这三天的UV总量是多少,怎么融合多个统计值。 * */ public class HyperLoglogTest { /** * 数据结构为HyperLoglog的数据存储 */ @Test public void pfadd(){ Jedis jedis = RedisUtil.getJedis(); Long log1 = jedis.pfadd("log1", "1", "2", "3", "4"); System.out.println("返回值:"+log1); Long log2 = jedis.pfadd("log2", "5", "6", "7", "7", "7"); System.out.println("返回值:"+log2); Long log3 = jedis.pfadd("log3", "7","8"); System.out.println("返回值:"+log3); } /** * 数据结构为HyperLoglog的数据长度(基数) */ @Test public void pfcount(){ Jedis jedis = RedisUtil.getJedis(); long log1 = jedis.pfcount("log1"); System.out.println("返回值:"+log1); long log2 = jedis.pfcount("log2"); System.out.println("返回值:"+log2); long log3 = jedis.pfcount("log3"); System.out.println("返回值:"+log3); } /** * 将多个HyperLoglog合并,合并到log1中,log2和log3为原始值。 * 从后台查看log1会发现log1占用的空间会明显的增大 */ @Test public void pfmerge(){ Jedis jedis = RedisUtil.getJedis(); String pfmerge = jedis.pfmerge("log1", "log2","log3"); System.out.println("返回值:pfmerge:"+pfmerge); System.out.println("================================"); long log1 = jedis.pfcount("log1"); System.out.println("返回值:"+log1); long log2 = jedis.pfcount("log2"); System.out.println("返回值:"+log2); long log3 = jedis.pfcount("log3"); System.out.println("返回值:"+log3); } } [https_chenjiehua.me_database_hyperloglog-bigdata.html]: https://chenjiehua.me/database/hyperloglog-bigdata.html [https_blog.csdn.net_firenet1_article_details_77247649]: https://blog.csdn.net/firenet1/article/details/77247649
还没有评论,来说两句吧...