美文网首页
系统设计面试题 - 设计 Pastebin.com (或者 Bi

系统设计面试题 - 设计 Pastebin.com (或者 Bi

作者: 专职跑龙套 | 来源:发表于2018-04-26 13:13 被阅读142次

引用:
系统设计入门

设计 Pastebin.com (或者 Bit.ly)

解答

什么是 Pastebin.com,提供文本分享服务,例如用户A将某段文本复制进去,生成一个网址URL,用户B访问这个网址URL可以看到用户A输入的文本。
例子:https://pastebin.com/r4tkgw7M

什么是 Bit.ly,提供短地址服务,例如用户A将某个网址URL复制进去,生成一个短地址URL,用户B访问这个短地址URL可以自动跳转到原网址URL。
例子:https://bit.ly/1CjWhlk

第一步:通过讨论,明确限制及用例,确定Scope

支持的用例:

  • 用户输入一段文本,得到一个link
    • 默认该link没有截止日期
    • 用户可以手动设定截止日期,例如1天,1周,1个月等等
  • 用户在浏览器中访问link,可以看到之前输入的文本
  • 系统统计页面的访问信息(每月)
  • 系统删除已过期的link
  • 系统高可用 high availability

不支持的用例:

  • 不支持用户注册及登录
  • 不支持用户设置link的可见性
  • 不支持用户修改link

Constraints and assumptions:

  • 访问不均匀
  • 输入只能是纯文本,不能是图片及其他
  • 页面访问信息的统计不需要是实时的
  • 10 million 用户
  • 每月 10 million 写操作,每秒4次 (每月2.5 million 秒
  • 每月 100 million 读操作,每秒40次
  • 读写比例 10 :1

计算规模:
对于每一个文本:

  • 文本内容:1 KB
  • 短网址:7 bytes
  • 截止时间:4 bytes
  • 创建时间:5 bytes
  • 文本路径:255 bytes
  • 总共: ~1.27 KB

对于每一个月:

  • 新文本内容:12.7 GB = 1.27 KB * 10 million
  • 三年:~450 GB = 12.7 GB * 36

第二步:高层次设计

设计 Pastebin.com (或者 Bit.ly)

第三步:设计核心组件

使用关系型数据库SQL存储短网址与文本的对应关系。例如创建一个表pastes,结构如下:

shortlink char(7) NOT NULL
expiration_length_in_minutes int NOT NULL
created_at datetime NOT NULL
paste_path varchar(255) NOT NULL
PRIMARY KEY(shortlink)

文本的具体内容存储在 Object Store 中,可以是 Amazon S3,或者文档型的NoSQL,例如 MongoDB,key为 paste_path

此处可以讨论讨论 SQL VS NoSQL。

对于shortlink的产生,使用MD5加密算法:

  • 使用用户的 IP + timestamp 进行 MD5 哈希
  • 均匀分布,产生128位的哈希值(32 bytes,32个字符)
  • 取前7个字符作为 shortlink,大概有627中取值,够用了。为啥是62?62=26 + 26 + 10(字母大小写及数字)。

对于Write API:设计为一个REST API

  • 利用上述方法,产生shortlink。查询数据表 pastes,判断是否重复了,如果有重复,需要重新生成shortlink。
  • 插入一条数据到数据表 pastes
  • 将文本的具体内容存储在 Object Store中。
  • 返回shortlink。

对于Read API:设计为一个REST API

  • 通过shortlink查询数据表 pastes:
    • 如果存在,利用paste_path查询Object Store,返回文本的具体内容。
    • 如果不存在,返回错误信息。

对于Analytics:
由于页面访问信息的统计不需要是实时的,我们可以使用 MapReduce 来分析 Web Server 的日志文件。Map 主要对日志做简单的拆分计数,Reduce 对 Map 的结果求和
例如:

class HitCounts(MRJob):

    def extract_url(self, line):
        """Extract the generated url from the log line."""
        ...

    def extract_year_month(self, line):
        """Return the year and month portions of the timestamp."""
        ...

    def mapper(self, _, line):
        """Parse each log line, extract and transform relevant lines.

        Emit key value pairs of the form:

        (2016-01, url0), 1
        (2016-01, url0), 1
        (2016-01, url1), 1
        """
        url = self.extract_url(line)
        period = self.extract_year_month(line)
        yield (period, url), 1

    def reducer(self, key, values):
        """Sum values for each key.

        (2016-01, url0), 2
        (2016-01, url1), 1
        """
        yield key, sum(values)

删除过期的link:

  • 扫描数据库中的所有行,比较截止日期。

第四步:扩展设计

设计 Pastebin.com (或者 Bit.ly)
  • 为了服务不同区域的用户,加快访问的速度,使用CDN加速,并缓存文本内容。
  • 为了同时响应更多请求,对服务器水平扩展,并使用Load Balancer做负载均衡。
  • 存储分析结果的数据 SQL Analytics 可以使用数据仓库,例如Amazon Redshift 或者 Google BigQuery.
    • BigQuery 是 Google 推出的可扩展性强、成本低廉的无服务器企业数据仓库,可让您的所有数据分析人员更加高效地工作。不到一分钟便可设置好您的数据仓库并立即开始查询您的数据。Google BigQuery 可对 GB 级到 PB 级的数据执行极快速的 SQL 查询,并可轻松地将公共数据集或商业数据集与您的数据融合在一起。
  • 为了加快读取效率,使用Memory Cache,存储 shortlink 和 paste_path 的对应关系,避免频繁访问数据库。
  • 由于是读多写少,可以采用主从复制的数据库模式。主库同时负责读取和写入操作,并复制写入到一个或多个从库中,从库只负责读操作。

相关文章

网友评论

      本文标题:系统设计面试题 - 设计 Pastebin.com (或者 Bi

      本文链接:https://www.haomeiwen.com/subject/wgiylftx.html