算法高级(25)-分布式TopN算法玄机
面试题:请问,某视频点播网站,希望实时展现热门视频,比如近8小时点击量最大的前100个视频。如果由你来开发这个功能,你怎么做?
一、思路分析
看到这样的一个问题,估计同学们会说,很简单呀,用Redis的SortedSet搞定啊,Score计数,Key是视频ID,不就OK了吗?
回答到这一步,只能说你回答的不错,下一位。too young too simple呀兄弟。
要听清楚题目,有8小时动态时间窗口,计数会过期的。还有,一个视频播放网站的量有这么小吗,一个Redis就搞定了?我告诉你,视频数据起码是百万级别了,用户几个亿,播放量你至少得估计个1000/s吧。
这么看下来,还觉得是一个Redis能解决得了的吗?
二、解决办法
数据量太大,肯定要使用分布式了。关于数据的接收、存储本章我们先不考虑,我们只分析如何统计某个时间段内的播放量排行。
我们需要一张表来记录每条视频的点击记录(包含时间,用户等信息),我们要统计的就是某个时间段的点击总次数。
如果只有一张表,而且数据也存储在数据库中,那这个sql就简单了,语句如下:当天播放量前100视频排行榜
SELECT( e.createTime ) AS HOUR,ROUND( sum( e.score ), 1 ) AS sum,id
FROMt_vedio_play e
WHEREto_days( e.playTime ) = to_days( now( ) )
order by score desc limit 100
视频量太大,一张表放不下所有的记录,就需要用到分治算法,先将表哈希拆分成1024张子表。每张表里有一个字段score,表示这个视频的点击数(其实就是1,我们记录的是每一个时间点的每一次点击行为,后面再对时间进行分段抽象)。
如果是多个子表,你得在每个子表上都进行一次TopN查询,然后聚合结果再做一次TopN查询。子表查询可以多线程并行,提高聚合效率。下面是伪代码:
candidates = []
for k in range(1024):# 每个表都取topnrows = select id, score from vedio_${k} order by score desc limit 100# 聚合结果candidates.extend(rows)
# 根据score倒排
candidates = sorted(candidates, key=lambda t: t[1], reverse=True)
# 再取topn
candidates[:100]
上面这个算法思想,实际上就是分而治之,我们通过把一个大问题拆分成多个小问题并行处理以提高效率。
三、进一步优化
8小时的滑动窗口,意味着新的数据源源不断的进来,旧的数据时时刻刻在淘汰。严格来说,精准的8小时滑动窗口要求每条数据要严格的过期,差了1秒都不行,到点了就立即被淘汰。
精准的代价是我们要为每条点击记录都设置过期时间,过期时间本身也是需要存储的,而且过期策略还需要定时扫描时间堆来确认哪些记录过期了。量大的时候这些都是不容小嘘的负担。
但是在业务上来讲,排行版没有必要做到如此的精准,偏差个几分钟这都不是事。
业务上的折中给服务的资源优化带来了机遇。我们对时间片进行了切分,一分钟一个槽来进行计数。下面是伪代码:
class HitSlot {long timestamp; # earlies timestampmap[int]int hits; # post_id => hitsvoid onHit(int postId, int hits) {this.hits[postId] += hits;}
}
class WindowSlots {HitSlot currentSlot; # current active slotsLinkedList<HitSlot> historySlots; # history unactive slotsmap[int]int topHits; # topn postsvoid onHit(int postId, int hits) { # 因为上游有合并点击,所以有了hits参数long ts = System.currentTimeMillis();if(this.currentSlot == null) { # 创建第一个槽this.currentSlot == new HitSlot(ts);} elif(ts - this.currentSlot.timestamp > 60 * 1000) { # 创建下一个槽,一分钟一个槽this.historySlots.add(this.currentSlot);this.currentSlot = new HitSlot(ts);}this.currentSlot.onHit(postId, hits);}void onBeat() { # 维护窗口,移除过期的槽,然后统计topn,30s~60s调用一次if(historySlots.isEmpty()) {return;}HitSlot slot = historySlots[0];long ts = System.currentTimeMillis();if(ts - slot.timestamp > 8 * 60 * 60 * 1000) { # 过期了8小时,移掉第一个historySlots.remove(0);# 计算topn的帖子 topHits = topn(aggregateSlots(historySlots)); }}
}
上面的代码代表着每个分布式子节点的逻辑,它的目标就是定时维持一个8小时的统计窗口,并汇聚TopN的热门视频放在内存里。这个TopN的数据并不是特别实时,有一个大约1分钟的短暂的时间窗口。
四、统计中用到的Hash
按照视频的数据至少几百万,如果每个子节点都要对所有的播放量统计】,似乎也会占用不少内存,聚合和排序也会有不少计算量。最好的想法是每个子节点只负责一部分视频播放量的统计,这样可以明显节省计算资源。
我的微信公众号:架构真经(id:gentoo666),分享Java干货,高并发编程,热门技术教程,微服务及分布式技术,架构设计,区块链技术,人工智能,大数据,Java面试题,以及前沿热门资讯等。每日更新哦!
参考资料:
- https://blog.csdn.net/bntX2jSQfEHy7/article/details/80276225
算法高级(25)-分布式TopN算法玄机相关推荐
- 算法高级(1)-概述
算法是对特定问题求解步骤的描述.对于同一个问题,我们可能会用不同的算法来求解,我们可以根据算法的可读性.效率等进行取舍.针对不同的数据保存方式,也会有不同的算法. 很多同学会觉得,我工作经验五年,工作 ...
- 【Flink】分布式快照算法—— Chandy-Lamport 算法
文章目录 1.概述 2. Overview 3. Global Snapshot 4.Chandy-Lamport 算法 5.例子 6.总结 7.Refer 1.概述 转载:https://blog. ...
- 分布式一致性算法——Paxos 和 Raft 算法
写在前面 本文隶属于专栏<100个问题搞定大数据理论体系>,该专栏为笔者原创,引用请注明来源,不足和错误之处请在评论区帮忙指出,谢谢! 本专栏目录结构和参考文献请见100个问题搞定大数据理 ...
- 分布式优化算法的背景,应用场景,研究动态
文章目录 0.写在前面 1.背景介绍 ① 概念解释 ② 应用背景 ③ 小结 2.研究动态与现状 ①分布式优化算法的数学模型 ②分布式优化算法的分类 ③ 有中心节点VS无中心节点 ④有向图和无向图 ⑤静 ...
- [Spark的TopN算法实现]
一.TopN算法 MapReduce中的TopN算法是一个经典的算法,由于每个map都只是实现了本地的TopN算法,而假设map有M个,在归约的阶段只有M x N次运算,这个结果是可以接受的并不会造成 ...
- TopN算法实战 排序算法RangePartitioner解密
1.基础TopN算法实战 2.分组TopN算法实战 3.排序算法RangePartitioner内幕解密 知识点: *只要是改变每一行列的数据,一般都是用Map操作 *RangePartitioner ...
- 分布式共识算法丨Raft丨Raft-Extended 论文翻译
Raft-Extended 翻译 原文:https://pdos.csail.mit.edu/6.824/papers/raft-extended.pdf 辨析 consensus vs consis ...
- Thrill: 基于C++的高性能分布式批处理算法
Thrill: 基于C++的高性能分布式批处理算法 摘要 1.介绍 概述 我们的贡献 A 相关工作 2.Thrill设计 A. 分布式的不可变数组 B. 示例:WordCount C. DIA操作总览 ...
- 一致性hash算法_分布式寻址算法
一.分布式寻址算法简介 分布式寻址算法是很重要的内容,不了解这些算法,也就不能透彻的了解各种分布式中间件的原理.简单说一下这些高大上的寻址到底是个啥意思,比如在elasticsearch中,采用的是多 ...
最新文章
- 基于OpenCV实战的图像处理:色度分割
- IBM斥资3.6亿美元建史上最复杂云计算中心
- mongoose操作mongodb
- 网页html语言怎么看,怎样查看网页的css代码?
- Minio服务限制/租户
- Apache 和 Tomcat 的 关系
- 大前端技术选型 Native原生iOS, Android, React-Native, Flutter, 微信小程序, HTML5
- 以风险管理思想构建关键信息基础设施风险评估重器
- Adobe Dreamweaver CS6(或者CC 2018.2 SP)安装失败解决方案
- 文科生 python 简书_文科生学 Python 系列 15:泰坦尼克数据 1
- 竟有比双十一更令人发指的福利……
- word中统一修改mathtype公式和大小对应
- 如何在线压缩PDF文件大小?
- Log slf4j+logback配置
- 70 告别了,2013-2021【2021-06-05 1854】
- MySQL修改自增字段的自增值
- 一文查看公信宝查封始末,CEO此前曾表示获利数千万
- Advanced Installer多语言包安装
- PooledDataSource forcefully closed/removed all connections的解决
- invoke,十分钟搞定强大的Python任务自动化工具