Case
- 用户发布一篇文章,服务将文章推送给关注者(发送消息通知与邮件)
- 用户浏览用户时间轴(用户最新的活动)
- 用户浏览主页时间轴(用户关注的人的最近活动)
- 用户搜索关键词
- 服务需要有高可用性
假设
- 网络流量不是均匀分布的
- 发布文章的速度需要足够快(除非有上百万的关注者)
- 亿万活跃用户
- 每月需处理的亿万的读写、搜索请求
时间轴功能
- 浏览时间轴需要足够快
- 读负载 > 写负载
- 存入文章是高写入负载功能
搜索功能
- 搜索速度需要足够快
- 搜索是高负载读取功能
概要设计
组件设计
发布一篇文章存储是用SQL还是NoSQL
- 写 API服务器将推特使用 SQL 数据库存储于用户时间轴中
- 查询用户 图 服务找到存储于内存缓存中的此用户的粉丝
- 将推特存储于内存缓存中的此用户的粉丝的主页时间轴中
- 将特推存储在搜索索引服务中,以加快搜索
- 将媒体存储于对象存储中
- 使用队列异步推送通知
Redis 原生的 list 作为其数据结构
搜索 API服务器
- 从内存缓存读取时间轴数据,其中包括推特 id 与用户 id - O(1)
- 通过 multiget 向推特信息服务进行查询,以获取相关 id 推特的额外信息 - O(n)
- 通过 muiltiget 向用户信息服务进行查询,以获取相关 id 用户的额外信息 - O(n)
搜索 API调用搜索服务进行以下操作: 对输入进行转换与分词,弄明白需要搜索什么东西 移除标点等额外内容 将文本打散为词组 修正拼写错误 规范字母大小写 将查询转换为布尔操作 查询搜索集群(例如Lucene)检索结果: 对集群内的所有服务器进行查询,将有结果的查询进行发散聚合(Scatter gathers) 合并取到的条目,进行评分与排序,最终返回结果