深度解析某头条的一道面试题
首先,某头条的文章量、用户量都是很大的,点击量那就更恐怖了。
请问,如果实时展现热门文章,比如近8小时点击量大的文章前100名。
如果是你来开发这个功能,你怎么做?
> 这个好办啊,redis一个sortedset搞定啊,score计数,key是文章ID,不就ok了么?
> 回答的不错,你可以走了!
要听清题目,说好的8小时动态时间窗口,计数是会过期的。还有,头条的量有这么小么,一个redis就搞定了?同学啊,我告诉你,文章的量你起码得估计个几十万,用户你得估计几个亿,点击量你至少得估计个1M/s吧。
数据接收
1M/s的点击并发量,肯定是需要分布式了。客户端可能会为了减轻服务器的压力而选择延迟合并点击请求进行批量发送。简单起见,这里就使用HTTP协议吧。我们先不考虑恶意用户刷点击的行为。
服务器肯定会有多台机器多进程部署来接受点击请求,接收到的请求在进行参数解析后,被发送到存储单元。为了减轻存储的压力,每个进程可能会使用小窗口聚合数据,每隔一小段时间将窗口内的数据聚合起来一起发给存储单元。
数据存储
点击数据是很重要的数据,用户的兴趣偏好就靠它了。这么大的点击数据如果全部用内存装的话,成本太高。所以别指望完全使用redis了。
拿kafka存是一个好办法,ZeroCopy机制并发量很高,数据持久化在磁盘里成本低。不过kafka的数据一般是有过期时间的,如果想完全记住用户的点击以便做长期的数据分析,少不了要使用hdfs了。
但是因为要做准实时统计,hdfs可不适合干这个,hdfs适合做离线统计的数据源。所以还得靠kafka接数据,然后消费者一边入hdfs,一边做实时统计。
实时统计可以使用spark stream、storm接受kafka的输入,也可以自己手写。
分布式TopN算法
用户太多,用户表按用户ID哈希分成了1024张子表。用户表里有一个字段score,表示这个用户的积分数。现在我们要计算前100名积分多的用户以及积分数,该怎么查询?
如果是单个表,一个SQL也就搞定了
select id, score from user order by score desc limit 100
相关文章