继续浏览精彩内容
慕课网APP
程序员的梦工厂
打开
继续
感谢您的支持,我会继续努力的
赞赏金额会直接到老师账户
将二维码发送给自己后长按识别
微信支付
支付宝支付

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

公众号_程序员的成长之路
关注TA
已关注
手记 62
粉丝 42
获赞 244

阅读本文大概需要 2.8 分钟。

作者:沙茶敏碎碎念

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

当然,拼多多加班也是出名的,一周上 6 天班是常态,每天工作时间基本都是超过 12 个小时,也是相当辛苦的。

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

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

使用 Hash

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

当一个用户访问的时候,如果用户登陆过,那么我们就使用用户的 id,如果用户没有登陆过,那么我们也能够前端页面随机生成一个 key 用来标识用户。

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

当我们要统计某一个网站某一天的访问量的时候,就可以直接使用 HLEN 来得到最终的结果了。

5d006183000105b509410290.jpg

优点:简单,容易实现,查询也是非常方便,数据准确性非常高。

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

使用 Bitset

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

对于有大量数据的场景,如果我们使用 bitset,那么,可以节省非常多的内存。

对于没有登陆的用户,我们也可以使用哈希算法,把对应的用户标识哈希成一个数字 id。

bitset 非常的节省内存,假设有 1 亿个用户,也只需要 100000000/8/1024/1024 约等于 12 兆内存。

5d0061830001cd3705180103.jpg

Redis 已经为我们提供了 SETBIT 的方法,使用起来非常的方便。

我们可以看看下面的例子:

我们在 item 页面可以不停地使用 SETBIT 命令,设置用户已经访问了该页面,也可以使用 GETBIT 的方法查询某个用户是否访问。

最后我们通过 BITCOUNT 可以统计该网页每天的访问数量。

5d0061830001726610800194.jpg

优点占用内存更小,查询方便,可以指定查询某个用户,数据可能略有瑕疵,对于非登陆的用户,可能不同的 key 映射到同一个 id,否则需要维护一个非登陆用户的映射,有额外的开销。

缺点如果用户非常的稀疏,那么占用的内存可能比方法一更大。

使用概率算法

对于拼多多这种多个页面都可能非常多访问量的网站,如果所需要的数量不用那么准确,可以使用概率算法,事实上,我们对一个网站的 UV 的统计,1 亿跟 1 亿零 30 万其实是差不多的。

在 Redis 中,已经封装了 HyperLogLog 算法,他是一种基数评估算法。

这种算法的特征,一般都是数据不存具体的值,而是存用来计算概率的一些相关数据。

5d00618300014a5f09980179.jpg

当用户访问网站的时候,我们可以使用 PFADD 命令,设置对应的命令,最后我们只要通过 PFCOUNT 就能顺利计算出最终的结果,因为这个只是一个概率算法,所以可能存在 0.81% 的误差。

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

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

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


·END·

程序员的成长之路

路虽远,行则必至


打开App,阅读手记
0人推荐
发表评论
随时随地看视频慕课网APP