题目

你有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台不同的机器,同时要做到操作无误。这可能不太现实(特别是对于数据量更大、机器更多的情况),我们需要开始考虑如何处理机器故障。此外,设计那么多机器,无疑大幅增加了系统的复杂性。

careercup-扩展性和存储限制10.6的更多相关文章

  1. careercup-扩展性和存储限制10.4

    题目 有一个数组,里面的数在1到N之间,N最大为32000.数组中可能有重复的元素(即有的元素 存在2份),你并不知道N是多少.给你4KB的内存,你怎么把数组中重复的元素打印出来. 解答 我们有4KB ...

  2. careercup-扩展性和存储限制10.3

    题目 给你一个文件,里面包含40亿个整数,写一个算法找出该文件中不包含的一个整数, 假设你有1GB内存可用. 如果你只有10MB的内存呢? 解答 我们先来做个算术题,40亿个整数大概有多大? * ^ ...

  3. OpenStack 企业私有云的若干需求(6):大规模扩展性支持

    本系列会介绍OpenStack 企业私有云的几个需求: 自动扩展(Auto-scaling)支持 多租户和租户隔离 (multi-tenancy and tenancy isolation) 混合云( ...

  4. 使用Lua脚本语言开发出高扩展性的系统,AgileEAS.NET SOA中间件Lua脚本引擎介绍

    一.前言 AgileEAS.NET SOA 中间件平台是一款基于基于敏捷并行开发思想和Microsoft .Net构件(组件)开发技术而构建的一个快速开发应用平台.用于帮助中小型软件企业建立一条适合市 ...

  5. MySQL - 扩展性 3 负载均衡:眼花缭乱迷人眼

    负载均衡的基本思路很简单: 在一个服务器集群中尽可能地的平均负载量. 基于这个思路,我们通常的做法是在服务器前端设置一个负载均衡器.负载均衡器的作用是将请求的连接路由到最空闲的可用服务器上.如图 1, ...

  6. Atitit.软件架构高扩展性and兼容性原理与概论实践attilax总结

    Atitit.软件架构高扩展性and兼容性原理与概论实践attilax总结 1. 什么是可扩展的应用程序?1 2. 松耦合(ioc)2 3. 接口的思考 2 4. 单一用途&模块化,小粒度化2 ...

  7. jetbrick,新一代 Java 模板引擎,具有高性能和高扩展性

    新一代 Java 模板引擎,具有高性能和高扩展性. <!-- Jetbrick Template Engineer --> <dependency> <groupId&g ...

  8. Android ImageCache图片缓存,使用简单,支持预取,支持多种缓存算法,支持不同网络类型,扩展性强

    本文主要介绍一个支持图片自动预取.支持多种缓存算法的图片缓存的使用及功能.图片较大需要SD卡保存情况推荐使用ImageSDCardCache. 与Android LruCache相比主要特性:(1). ...

  9. Java并发编程:性能、扩展性和响应

    1.介绍 本文讨论的重点在于多线程应用程序的性能问题.我们会先给性能和扩展性下一个定义,然后再仔细学习一下Amdahl法则.下面的内容我们会考察一下如何用不同的技术方法来减少锁竞争,以及如何用代码来实 ...

随机推荐

  1. javascript实现文本框标签验证

    < !DOCTYPE html > <html lang = "en" > <head > <meta charset = "U ...

  2. cf1043F. Make It One(dp 容斥原理)

    题意 题目链接 给出\(n\)个数,问最少选几个数,使他们的\(gcd = 1\) Sol 好神仙啊qwq. 首先,如果答案存在,那么最多为\(7\)(因为前\(7\)个质数乘起来\(>= 3e ...

  3. JS函数动作分层结构详解及Document.getElementById 释义 js及cs数据类型区别 事件 函数 变量 script标签 var function

    html +css 静态页面 js     动态 交互   原理: js就是修改样式, 比如弹出一个对话框. 弹出的过程就是这个框由disable 变成display:enable. 又或者当鼠标指向 ...

  4. dotnet watch+vs code提升asp.net core开发效率

    在园子中,已经又前辈介绍过dotnet watch的用法,但是是基于asp.net core 1.0的较老版本来讲解的,在asp.net core 2.0的今天,部分用法已经不太一样,所以就再写一篇文 ...

  5. nodejs项目windows下开机自启动

    Nodejs项目开机自启动 1. 在需要自启动的项目中安装 node-windows 模块 npm install node-windows --save 2. 在项目根目录创建nw.js文件 代码截 ...

  6. 基础架构之GitLab

    Git几乎是软件开发人员的必备工具了,关于代码管理,公司都一般都会搭建自己的仓库,关于GitLab的详细介绍参见官方网站详见 https://about.gitlab.com,这篇文章主要介绍安装及使 ...

  7. Ubuntu 18.04 的网络配置

    netplan简介 目前,ubuntu18.04上使用了netplan 作为网络配置工具:在终端上配置网络参数跟之前的版本有比较大的差别 Netplan工作流程如下图所示:通过读取  /etc/net ...

  8. Linux制作deb

    1.新建一个我们临时的工作目录mkdir deb 2.新建我们程序的目录mkdir hello 3.编写我们的程序 我们以我们最熟悉的helloworld程序做起,hello.c代码如下#includ ...

  9. 关于实现XX系统设计时所实现的质量属性战术

    可用性: 1)使用Try-catch对抛出的异常进行处理 2)使用Spring事务管理 易用性: 1)在类似删除相关选项时,弹出提示框,防止误操作 2)在不编辑基本信息时,对其进行折叠或者隐藏 3)提 ...

  10. htm5 手机自适应问题 文本框被激活(获取焦点)时,页面会放大至原来尺寸。

    加上这句话就ok啦 <meta name="viewport" content="width=device-width, initial-scale=1.0, mi ...