时间轴设计和搜索

31 阅读2分钟

Case

  • 用户发布一篇文章,服务将文章推送给关注者(发送消息通知与邮件)
  • 用户浏览用户时间轴(用户最新的活动)
  • 用户浏览主页时间轴(用户关注的人的最近活动)
  • 用户搜索关键词
  • 服务需要有高可用性

假设

  • 网络流量不是均匀分布的
  • 发布文章的速度需要足够快(除非有上百万的关注者)
  • 亿万活跃用户
  • 每月需处理的亿万的读写、搜索请求

时间轴功能

  • 浏览时间轴需要足够快
  • 读负载 > 写负载
  • 存入文章是高写入负载功能

搜索功能

  • 搜索速度需要足够快
  • 搜索是高负载读取功能

概要设计

image.png

组件设计

发布一篇文章存储是用SQL还是NoSQL

  • 写 API服务器将推特使用 SQL 数据库存储于用户时间轴中
  • 查询用户 图 服务找到存储于内存缓存中的此用户的粉丝
  • 将推特存储于内存缓存中的此用户的粉丝的主页时间轴
  • 将特推存储在搜索索引服务中,以加快搜索
  • 将媒体存储于对象存储
  • 使用队列异步推送通知

Redis 原生的 list 作为其数据结构

image.png

搜索 API服务器

  • 内存缓存读取时间轴数据,其中包括推特 id 与用户 id - O(1)
  • 通过 multiget 向推特信息服务进行查询,以获取相关 id 推特的额外信息 - O(n)
  • 通过 muiltiget 向用户信息服务进行查询,以获取相关 id 用户的额外信息 - O(n)

搜索 API调用搜索服务进行以下操作: 对输入进行转换与分词,弄明白需要搜索什么东西 移除标点等额外内容 将文本打散为词组 修正拼写错误 规范字母大小写 将查询转换为布尔操作 查询搜索集群(例如Lucene)检索结果: 对集群内的所有服务器进行查询,将有结果的查询进行发散聚合(Scatter gathers) 合并取到的条目,进行评分与排序,最终返回结果