大纲

  • TopK on single node
  • TopK on multiple nodes
  • Realtime topK with low QPS
  • Realtime topK with high QPS
  • Approx TopK
  • MapReduce

一、TopK on single node

  从几个关于TopK的算法引出 TopK 系列问题

1. 给你一个无序整数数组,要求求出TopK (Order By Value)

  题目地址:http://www.lintcode.com/zh-cn/problem/top-k-largest-numbers/

  数据结构:优先队列(minHeap) (当然如果不是数据流的话,使用QuickSelect效率更高)

  时间复杂度:O(nlogk)

  空间复杂度: O(k)

2. 给你一个微博话题组成的列表,要求求出TopK(Order by Frequency)

  题目地址:http://www.lintcode.com/zh-cn/problem/top-k-frequent-words/

  分析:这里需要按照String出现的频数来求解TopK,自然不能像刚刚一样直接使用一个PriorityQueue来实现。但基本原理还是一致的。

     使用一个HashMap,HashMap<String, Integer> 表明某个String 出现的频数。然后在PQ中存储的是我们自定义的一个数据结构Pair, Pair包含String 和 频数两个变量,自定义一个Comparator按照频数升序排序就可以了。

  数据结构:HashMap PriorityQueue

  时间复杂度:O(n + nlog(k)) -> O(nlogk)

  空间复杂度: O(|n| + k)  其中 |n|表示unique string数目

二、TopK on multiple nodes

1. 现在假设这样一个场景:给你一组10T的文件,文件内容是10million用户当天的搜索记录,求微博今日话题热搜?

  这个场景就不能再使用single node 因为一方面文件太大,单机无法处理,另一方面处理速度太慢

  这时候就要采用 分&和 的思想

  OverView 如下:

  • 分成小文件
  • 分发给不同的机器处理
  • 每个机器分别获得TopK
  • 组合这些TopK获得总的TopK

  

注意这里一个比较关键的地方:怎么来拆分文件呢?

一种思路是按照文件的先后顺序来拆分,这是有问题的,因为假如某个String比较分散,而总次数是能够进入TopK的,但是在SlaveNode上,这个slaveNode可能并没有入选TopK,这就导致了错误。

所以,我们这里采用 Divide by hash value. 这样相同的String都被分给了同一个slaveNode处理。

2. 假设场景二: 有N台机器, 每台机器各自存储单词文件,求所有单词出现频率的TopK

同样的道理,假如直接求各个单机的TopK在合并的话也是会出现问题的。

这里需要ReHash!

三、 Realtime TopK with Low QPS

之前讨论的情况都是 offline 的,那么实时数据又怎么样呢?

想法一:

步骤:新数据来,存储到磁盘,服务器请求计算TopK的时候再运行算法求解。

缺点:重复计算、运行速度慢。

想法二:

新数据来,把它写到hashmap,hashmap更新的时候同时更新PQ,获取TopK。

缺点:OOM 节点宕机或者停电的时候数据丢失

想法三:

不使用hashMap,取代他的是把数据存储在database中。

以上是使用database来取代hashmap的分析,那么PQ有没有什么需要处理的呢?

当然是需要的,新加入数据之后,需要删除PQ中已经存储了的数据。而PQ是不支持高效删除节点操作的,所以这里使用treeMap来代替PQ。

四、 Realtime TopK with High QPS

QPS过高的话,数据库相应存在high latency

解决办法也是 分&和

各个节点get TopK 然后再合并。

可能带来这样一个问题:假如某个key太热了,导致某个节点write key 负荷太重怎么办?这也会带来高延迟

流程图:

由图可知,当某个key过热的话,这个节点就很频繁的在写数据,导致treeMap被锁。high latency

解决办法是就是:Cache

这其实是在准确性和延迟之间找一个平衡。

五、Approx TopK Algorithm

准确性和使用空间的TradeOff

如果我们把所有词都存入disk,那么那些那些低频词将浪费较多的空间。

接下来介绍的这种算法可以自定义使用的空间大小,并且时间复杂度为O(logK)

基本步骤:

新单词来的时候,更新hashMap

更新treeMap

这和之前是一样的,区别之处在于:

HashMap:

key = word_hashvalue

Value = frequency

但是这是会带来问题的,分析如下:

1、假如好多低频词都被hash到同一个value,那么这个value就很可能被选中了。

2、假如后来的低频词hash到高频的那个value,误把这个低频词选中。

解决办法:bloom filter 布隆过滤器

Bloom Filter:

HashMap 拥有三个不同的hash函数,取hash到的最小的count。这样一来,低频词虽然有可能某一个hash hash到和高频词的那个value,但三个hash取小的counter 还是有很大作用来处理这个问题的。

六、Use Mapreduce to solve it

TopK-微博今日热门话题的更多相关文章

  1. 用 Python 监控知乎和微博的热门话题

    前言 文的文字及图片来源于网络,仅供学习.交流使用,不具有任何商业用途,版权归原作者所有,如有问题请及时联系我们以作处理. 作者: TED Crossin的编程教室 PS:如有需要Python学习资料 ...

  2. 用python+selenium抓取微博24小时热门话题的前15个并保存到txt中

    抓取微博24小时热门话题的前15个,抓取的内容请保存至txt文件中,需要抓取排行.话题和阅读数 #coding=utf-8 from selenium import webdriver import ...

  3. Python知乎热门话题爬取

    本例子是参考崔老师的Python3网络爬虫开发实战写的 看网页界面: 热门话题都在 explore-feed feed-item的div里面 源码如下: import requests from py ...

  4. 5-46 新浪微博热门话题 (30分)——unfinished HASH

    5-46 新浪微博热门话题   (30分) 新浪微博可以在发言中嵌入“话题”,即将发言中的话题文字写在一对“#”之间,就可以生成话题链接,点击链接可以看到有多少人在跟自己讨论相同或者相似的话题.新浪微 ...

  5. 生活常用类API调用的代码示例合集:邮编查询、今日热门新闻查询、区号查询等

    以下示例代码适用于 www.apishop.net 网站下的API,使用本文提及的接口调用代码示例前,您需要先申请相应的API服务. 邮编查询:通过邮编查询地名:通过地名查询邮编 今日热门新闻查询:提 ...

  6. java-新浪微博开放平台——话题跟踪

    代码 网盘地址:http://pan.baidu.com/s/1pJ1D0Kz

  7. 对于996.ICU这个热门话题,一个在校学生的思考

    最近GitHub上的项目996.ICU一经发布就得巨大的回响,看了这么说法和评论,作为一个准程序猿也有自己的一些想法. 1 其实看得出来,很大一部分人认为的是付出与回报不对等.简单说就是工资对于工作量 ...

  8. Python知乎热门话题数据的爬取实战

    import requestsfrom pyquery import PyQuery as pq url = 'https://www.zhihu.com/explore'headers = { 'u ...

  9. Python 获取新浪微博的热门话题 (API)

    Code: #!/usr/bin/python # -*- coding: utf-8 -*- ''' Created on 2014-06-27 @author: guaguastd @name: ...

随机推荐

  1. 百倍性能的PL/SQL优化案例(r11笔记第13天)

    我相信你是被百倍性能的字样吸引了,不过我所想侧重的是优化的思路,这个比优化技巧更重要,而结果嘛,其实我不希望说成是百倍提升,“”自黑“”一下. 有一个真实想法和大家讨论一下,就是一个SQL语句如果原本 ...

  2. Java栈,PC寄存器,本地方法栈,堆,方法区(静态区)和运行常量池

    详情参考:https://my.oschina.net/wangsifangyuan/blog/711329 前言:当要判断一个变量存在什么空间上哪儿时,先分析它是哪一种(是实例变量还是局部变量),实 ...

  3. a low memory warning should only destroy the layer’s bitmap

    https://stablekernel.com/view-controller-in-ios-6/ Some of you may have noticed that your view contr ...

  4. CUDA实现数组倒序

    数组倒序,将在主机上初始化的数组传输到设备上,然后用CUDA并行倒序,此时在全局内存上操作,再将结果返回到主机并验证. #include <stdio.h> #include <as ...

  5. z-index、absolute、marquee滚动条的问题

    1.z-index 层次叠加 ,元素叠加,谁的权重大谁就在上面 1).父级出现position:relation:的时候,失效: 2).层叠元素出现float的时候失效: 3).层次元素也得设置pos ...

  6. 03_14_final关键字

    03_14_final关键字 1. Final关键字 final的变量的值不能够被改变 final的成员变量 final的局部变量(形参) final的方法不能够被重写 final的类不能够被继承

  7. mysql中如何不重复插入,mysql 重复的不插入,mysql唯一的插入

    INSERT INTO new_schedules_spider_shipsname ( ID,SCAC,VESSEL,VOYAGE,SERVICE_NAME,MD5 ) SELECT NULL,%s ...

  8. python2, 3环境变量配置(win10下)

    1.找到此电脑,右击点击属性 2.左边侧栏,高级系统设置 3.系统属性中点击高级 4.点击环境变量 5.可以看到 某某某用户变量和系统变量两个方框 其中,系统变量是要你在打开cmd是用管理员身份运行所 ...

  9. http 实战练习

    http 实战练习 建立httpd服务器,要求提供两个基于名称的虚拟主机: (1)www.X.com,页面文件目录为/web/vhosts/x:错误日志为/var/log/httpd/x.err,访问 ...

  10. setInterval与setTimeout

    在自己用canvas画一个时钟时,画秒钟用的是利用图片将重复的线条遮住,但是会出现有两个秒钟线条同时存在,才想起setInterval有那么个坑,查了点资料,记录下,若有不对的或者未写到的点,还请大家 ...