Hyperloglog(基数统计的算法,Redis2.8.9版本就已经更新出来了Hyperloglog 的数据结构,Hyperloglog有着0.81%的错误率,是可以忽略不计的)
学习之前先知道,什么是基数?
比如我有两个数据集 一个为A{1,3,5,7,8,7} 一个为B{1,3,5,7,8}
那么A和B的基数(不重复的元素)为5(1.3,5,7,8),可以接受误差
Hyperloglog的优点
1.占用的内存是固定的(比如说我想放2的64次方不同元素的基数,只需要费12KB的内存),如果要从内存角度来比较的话,Hyperloglog肯定是我们的首选
应用场景:
1 网页的UV(页面访问量,一个人访问一个网站多次,但是还是算作一个人)Hyperloglog有着0.81%的错误率,用作统计UV任务时,是可以忽略不计的(如果允许容错,那么一定可以使用Hyperloglog,如果不允许容错的话可以使用下面的传统set方式或者自己的数据类型即可)
传统的方式,使用set集合的方式保存用户的id等信息(因为set是不允许重复的,然后就可以统计出set中的元素数量作为标准判断),这个方式如果保存大量的用户id,就会比较麻烦(比较占用内存,我们的目的是为了计数,而不是保存用户信息)
Hyperloglog的命令
1 pfadd(name)(v1)(v2)(v3).....创建一组元素并且可以一次性添加多个值
2 pfcount(name)统计一组元素中的基数数量
3 pfmerge (new)(od1) (od2)统计两个老元素中的并集结果集并创建返回给新元素
127.0.0.1:6379[2]> pfadd mykey a b c d e f g h i j #创建第一组元素一次性添加多个值多个值 (integer) 1 #创建成功 127.0.0.1:6379[2]> pfadd mykey2 i j z x c v b n m #创建第二组元素一次性添加多个值多个值 (integer) 1 #创建成功 127.0.0.1:6379[2]> pfcount mykey #统计mykey中基数数量 (integer) 10 #有10个元素 127.0.0.1:6379[2]> pfcount mykey2 #统计mykey2中基数数量 (integer) 9 #有9个元素 127.0.0.1:6379[2]> pfmerge mykey3 mykey mykey2 #合并mykey mykey2把结果集(并集)赋给新元素mykey3 OK 127.0.0.1:6379[2]> pfcount mykey3 #统计mykey3中基数数量 (integer) 15 #有15个元素 127.0.0.1:6379[2]> pfadd k 1 #一次性添加一个值 (integer) 1 127.0.0.1:6379[2]> pfadd k 2 #一次性添加二个值 (integer) 1 127.0.0.1:6379[2]> pfcount k #统计k中基数数量 (integer) 2
3 Bitmap(位图,数据结构,都是操作二进制来进行记录,只有两个状态)
按位存储
Bitmap的使用场景:
1 统计用户信息,活跃,不活跃
2 打卡,两个状态的,都可以使用Bitmap
Bitmap的方法:
场景:使用bitmaps来实现周一到周五的打卡,下表从0开始打卡:1 不打卡:0,判断打卡天数,只需要统计状态为1的即可,例如:周一(0)打卡(1),周二(1)不打卡(0)
1 setbit(name)(sign1) (sign2) 设置元素,一般有两个状态
2 getbit(name)(sign) 根据状态获取某一个值
3 bitcount(name)统计全部的元素个数
1127.0.0.1:6379[2]> setbit sign 0 1 #添加元素例如:周一(0)打卡(1),周二(1)不打卡(0) (integer) 0 127.0.0.1:6379[2]> setbit sign 1 0 #添加元素例如:周一(0)打卡(1),周二(1)不打卡(0) (integer) 0 127.0.0.1:6379[2]> setbit sign 2 0 #添加元素例如:周一(0)打卡(1),周二(1)不打卡(0) (integer) 0 127.0.0.1:6379[2]> setbit sign 3 1 #添加元素例如:周一(0)打卡(1),周二(1)不打卡(0) (integer) 0 127.0.0.1:6379[2]> setbit sign 4 1 #添加元素例如:周一(0)打卡(1),周二(1)不打卡(0) (integer) 0 127.0.0.1:6379[2]> getbit sign 0 #查看周一是否打卡 (integer) 1 #打卡 127.0.0.1:6379[2]> getbit sign 1 #查看周二是否打卡 (integer) 0 #没打卡 127.0.0.1:6379[2]> bitcount sign #查看周一到周五打卡的全部天数 (integer) 3