Bitmap方案
所谓的Bitmap就是用一个bit位来标记某个元素对应的Value,比如ID为2的用户,就用第2个bit位来表示,然后用该位的值来表示该用户是否访问过。如果要计算UV,那就只要数一下有多少个1就可以了。该方案有一个限制就是用户的ID只能为数值型的,不能基于非数值型进行统计,如UUID。Redis提供了相关命令可以实现bitmap,如下:
// 插入
setbit key offset value
//获取
getbit key offset
//计数
BITCOUNT key [start] [end]
这里offset最大值就是2^32,比如ID为2的用户可以setbit uv 2 1,来记录。最后要计算UV,就直接 BITCOUNT uv. 这步计数非常快,复杂度是O(1)。
HyperLogLog方案
Redis提供了命令实现了该方案:
redis 127.0.0.1:6379> PFADD runoobkey "redis"
1) (integer) 1
redis 127.0.0.1:6379> PFADD runoobkey "mongodb"
1) (integer) 1
redis 127.0.0.1:6379> PFADD runoobkey "mysql"
1) (integer) 1
redis 127.0.0.1:6379> PFCOUNT runoobkey
(integer) 3
参考实现:
stream.foreachRDD { rdd =>
//统计人数
rdd.foreachPartition { partition =>
//从分区所属executor的redis线程池获取一个连接.
val redis = RedisUtil.getRedis