大家好,我系渣渣骥,今天跟大家分享的面试题是:如何使用Redis统计用户的独立访问量。
这里的独立访问量是说,不同的用户才算多次,假设用户A访问了3次,也只算1次“独立访问量”;A,B各访问一次,则算两次。说白了,就是有多少个不同的用户访问过。
1. 使用HASH
这是最容易想到、也是最简单的办法。每个用户登录都有唯一的标识符userId,将userId作为key, 单个用户的访问量作为value即可。例如:
127.0.0.1:6379> hset users zzj 3
(integer) 1
127.0.0.1:6379> hset users zzy 1
(integer) 1
127.0.0.1:6379> hlen users
(integer) 2
127.0.0.1:6379>
这样就统计了用户的访问数量2。
但是对于有千万级甚至过亿用户的大型网站来说,这种方法占用的内存空间太大。假设一个int占用4字节(即32bit),当有一亿用户时,占用的内存将达到约1000000000*4/ 1024/ 1024/ 1024= 3.7G,不仅对硬件要求很高,当用户数量不断上升时性能也会下降,使用hset显然不能满足大型网站的需求。
2. 使用BitMap
Redis从2.2.0版本开始新增了setbit,getbit,bitcount等几个Bitmap相关命令。虽然是新命令,但是并没有新增新的数据类型,因为setbit等命令只不过是在set上的扩展。
指令 SETBIT key offset value 复杂度 O(1)
Bitmap可以一定程度解决Hash使用内存多的问题。比如,一个int类型32比特,那么用每一bit表示一个用户,一个int就可以表示32个用户,这样就节省了空间。
例如:
127.0.0.1:6379>setbit users1 111 1
(integer)0
127.0.0.1:6379>bitcount users1
(integer)1
127.0.0.1:6379>setbit users1 1 1
(integer)0
127.0.0.1:6379>bitcount users1
(integer)2
这样,理想情况下,1亿个用户,只需要约1000000000/8/1024/1024= 0.116G内存。
3. 使用HyperLoglog
当独立访问量统计不需要十分精确时,我们可以考虑使用封装了概率算法的HyperLoglog去进行统计。比如一个电商网站通过概率算法算出3亿访问量即可,并不需要准确的统计出3亿零80万零500访问量(注意:PFCOUNT只是一个概率算法,所以可能存在 0.81% 的误差)。
127.0.0.1:6379> pfadd users2 zzjzzy zzh
(integer) 1
127.0.0.1:6379> pfcount users2
(integer) 3
对于一个 key,HyperLoglog只需要 12kb的内存。
用户评论