拼多多面试题:如何用 Redis 统计独立用户访问量?

众所周至,拼多多的待遇也是高的可怕,在挖人方面也是竭尽全力,对于一些工做3年的开发,稍微优秀一点的,都给到30K的Offer。前端

固然,拼多多加班也是出名的,一周上6天班是常态,天天工做时间基本都是超过12个小时,也是至关辛苦的。java

废话很少说,今天咱们来聊一聊拼多多的一道后台面试真题,是一道简单的架构类的题目:面试

拼多多有数亿的用户,那么对于某个网页,怎么使用Redis来统计一个网站的用户访问数呢?redis

一、Hash算法

哈希是Redis的一种基础数据结构,Redis底层维护的是一个开散列,会把不一样的key映射到哈希表上,若是是遇到关键字冲突,那么就会拉出一个链表出来。后端

当一个用户访问的时候,若是用户登录过,那么咱们就使用用户的id,若是用户没有登录过,那么咱们也可以前端页面随机生成一个key用来标识用户微信

当用户访问的时候,咱们可使用HSET命令,key能够选择URI与对应的日期进行拼凑,field可使用用户的id或者随机标识,value能够简单设置为1。数据结构

当咱们要统计某一个网站某一天的访问量的时候,就能够直接使用HLEN来获得最终的结果了。多线程

优势:简单,容易实现,查询也是很是方便,数据准确性很是高。架构

缺点:占用内存过大,。随着key的增多,性能也会降低。小网站还行,拼多多这种数亿PV的网站确定受不了。

二、Bitset

咱们知道,对于一个32位的int,若是咱们只用来记录id,那么只可以记录一个用户,但若是咱们转成2进制,每位用来表示一个用户,那么咱们就可以一口气表示32个用户,空间节省了32倍!

对于有大量数据的场景,若是咱们使用bitset,那么能够节省很是多的内存。推荐:Redis 21问,你会几道?

对于没有登录的用户,咱们也可使用哈希算法,把对应的用户标识哈希成一个数字id。bitset很是的节省内存,假设有1亿个用户,也只须要100000000/8/1024/1024约等于12兆内存。

Redis已经为咱们提供了SETBIT的方法,使用起来很是的方便,咱们能够看看下面的例子。

关注微信公众号:Java技术栈,在后台回复:redis,能够获取我整理的 N 篇最新 Redis 教程,都是干货。

咱们在item页面能够不停地使用SETBIT命令,设置用户已经访问了该页面,也可使用GETBIT的方法查询某个用户是否访问。最后咱们经过BITCOUNT能够统计该网页天天的访问数量。

优势: 占用内存更小,查询方便,能够指定查询某个用户,数据可能略有瑕疵,对于非登录的用户,可能不一样的key映射到同一个id,不然须要维护一个非登录用户的映射,有额外的开销。

缺点: 若是用户很是的稀疏,那么占用的内存可能比方法一更大。

三、几率算法

对于拼多多这种多个页面均可能很是多访问量的网站,若是所须要的数量不用那么准确,可使用几率算法

事实上,咱们对一个网站的UV的统计,1亿跟1亿零30万实际上是差很少的。

Redis中,已经封装了HyperLogLog算法,他是一种基数评估算法。这种算法的特征,通常都是数据不存具体的值,而是存用来计算几率的一些相关数据。

当用户访问网站的时候,咱们可使用PFADD命令,设置对应的命令,最后咱们只要经过PFCOUNT就能顺利计算出最终的结果,由于这个只是一个几率算法,因此可能存在0.81%的偏差。

优势: 占用内存极小,对于一个key,只须要12kb。对于拼多多这种超多用户的特别适用。

缺点: 查询指定用户的时候,可能会出错,毕竟存的不是具体的数据。总数也存在必定的偏差。

上面就是常见的3种适用Redis统计网站用户访问数的方法了。

分享一份 2019 最新 Java 架构师学习资料

做者:沙茶敏碎碎念
https://url.cn/5tQPEQg

推荐去个人博客阅读更多:

1.Java JVM、集合、多线程、新特性系列教程

2.Spring MVC、Spring Boot、Spring Cloud 系列教程

3.Maven、Git、Eclipse、Intellij IDEA 系列工具教程

4.Java、后端、架构、阿里巴巴等大厂最新面试题

生活很美好,明天见~

相关文章
相关标签/搜索