zoukankan      html  css  js  c++  java
  • careercup-扩展性和存储限制10.6

    题目

    你有10亿个url,每个url对应一个非常大的网页。你怎么检测重复的网页?

    解答

    1. 网页大,数量多,要把它们载入内存是不现实的。 因此我们需要一个更简短的方式来表示这些网页。而hash表正是干这事的。 我们将网页内容做哈希,而不是url,这里不同url可能对应相同的网页内容。
    2. 将每个网页转换为一个哈希值后,我们就得到了10亿个哈希值, 很明显,两两对比也是非常耗时的O(n2 )。因此我们需要使用其它高效的方法。

    根据以上分析,我们可以推出满足条件的以下算法:

    1. 遍历网页,并计算每个网页的哈希值。
    2. 检查哈希值是否已经在哈希表中,如果是,说明其网页内容是重复的,输出其url。 否则保存url,并将哈希值插入哈希表。

    通过这种方法我们可以得到一组url,其对应的网页内容都是唯一的。但有一个问题, 一台计算机可以完成以上任务吗?

    1. 一个网页我们要花费多少存储空间?
      • 每个网页转换成一个4字节的哈希值
      • 假设一个url平均是30个字符,那我们至少需要30个字节
      • 因此对应一个url,我们一共要用掉34个字节
    2. 34字节 * 10亿 = 31.6GB。很明显,单机的内存是无法搞定的。

    我们要如何解决这个问题?

    1. 我们可以将这些数据分成多个文件放在磁盘中,分次载入内存处理。 这样一来我们要解决的就是文件的载入/载出问题。
    2. 我们可以通过哈希的方式将数据保存在不同文件,这样一来,大小就不是问题了, 但存取时间就成了问题。硬盘上的哈希表随机读写要耗费较多的时间, 主要花费在寻道及旋转延迟上。关于这个问题, 可以使用电梯调度算法来消除磁头在磁道间的随机移动,以此减少消耗的时间。
    3. 我们可以使用多台机器来处理这些数据。这样一来,我们要面对的就是网络延迟。 假如我们有n台机器。
      • 首先,我们对网页做哈希,得到一个哈希值v
      • v%n 决定这个网页的哈希值会存放在哪台机器
      • v/n 决定这个哈希值存放在该机器上哈希表的位置

    给定100亿个网址,如何检测出重复的文件?这里所谓的“重复”是指两个URL完全相同。

    解法:

    100亿个网址(URL)要占用多少空间呢?如果每个网址评价长度为100个字符,每个字符占4字节,则这份100亿个网址的列表要占用约4TB。在内存中可能放不下这么多的数据。

    不过,不妨假设一下,这些数据奇迹般的放进了内存,毕竟先求解简化的题目是很有用的做法。对于此题的简化版,只要创建一个散列表,若在网址列表中找到某个URL,就映射为true。(另一种做法是对列表进行排序,找出重复项,这需要额外耗费一些时间,但几乎无优点可言)

    至此,我们得到此题简化版的解法,那么,假设我们手上有4000GB的数据,而且无法全部放进内存,该怎么办?到也好办,我们可以将部分数据存储至磁盘,或者将数据分拆到多台机器上。

    解法1:存储至磁盘

    若将所有数据存储在一台机器上,可以对数据进行两次扫描。第一次扫描是将网址列表拆分为4000组,每组1GB。

    简单的做法是将每个网址u存放在名为<x>.txt的文件中,其中x=hash(u)%4000。也就是说,我们会根据网址的散列值(除以分组数量取余数)分割这些网址。这样一来,所有散列值相同的网址都会位于同一文件。

    第二次扫描,我们其实是在实现前面简化版问题的解法:将每个文件载入内存,创建网址的散列表,找出重复的。

    解法2:多台机器

    另一种解法的基本流程是一样的,只不过是要是有多台机器。在这种解法中,我们会将网址发送到机器x上,而不是存储至文件<x>.txt。使用多台机器有优点也有缺点。

    主要优点是可以并行执行这些操作,同时处理4000个分组。对于海量数据,这么做就能迅速有效地解决问题。缺点是现在必须依靠4000台不同的机器,同时要做到操作无误。这可能不太现实(特别是对于数据量更大、机器更多的情况),我们需要开始考虑如何处理机器故障。此外,设计那么多机器,无疑大幅增加了系统的复杂性。

  • 相关阅读:
    C# 图片与Base64的相互转化
    LeetCode 303. Range Sum Query – Immutable
    LeetCode 300. Longest Increasing Subsequence
    LeetCode 292. Nim Game
    LeetCode 283. Move Zeroes
    LeetCode 279. Perfect Squares
    LeetCode 268. Missing Number
    LeetCode 264. Ugly Number II
    LeetCode 258. Add Digits
    LeetCode 257. Binary Tree Paths
  • 原文地址:https://www.cnblogs.com/wuchanming/p/4449578.html
Copyright © 2011-2022 走看看