场景
以微博为例
功能:在下拉列表中展示我关注的所有人发布的微博
场景复杂度分析:
一天 = 86400秒
- 读QPS = DAU * 每个用户平均每天的查询次数 / 86400
- 写QPS = DAU * 每个用户平均每天发布微博的次数 / 86400
服务
需要三个不同的服务
| 服务 | 职能 |
|---|---|
| User Service | 用户基础信息 |
| Friendship Service | 好友关系 |
| Tweet Service | 推文信息 |
存储
表设计
-
User Table | column | notes | | --------- | ----------- | | id | primary key | | user_name | 用户名 | | phone | 手机 | | password | 密码 |
-
FriendShip Table
| column | notes |
|---|---|
| from_user_id | 关注人 |
| to_user_id | 被关注人 |
- tweet table
| column | notes |
|---|---|
| user_id | 用户id |
| contetent | 内容 |
| publish_time | 发布时间 |
News Feed 系统设计有两种不同的模型,读扩撒与写扩散
Pull Model(读扩散)
-
发布微博 将发布的微博写入到tweet table
-
读取News Feed 假如我要读取10条微博,需要做如下操作
- 查询我的好友关系
- 获取每个好友的前10条微博
- k路归并出前10条微博
- 模型缺陷
需要获取所有好友的前n条数据并做计算,速度相对较慢
Push Model (写扩散)
这种模型需要新建一张表,存储用户可以看到的news feed 信息
- News Feed table | column | notes | | ------------ | ----- | | user_id | 用户id | | tweet_id | 推文主键 |
- 发布微博
- 存储微博信息
- 获取用户好友关系
- 为每个好友生成一条记录并存储
- 由于一个用户的粉丝可能会特别多,数据fanout的过程要异步进行
- 读取 News Feed 单次查询搞定
select * from News Feed table where user_id = xx and xxx
- 模型缺陷 服务写入压力较大,如果一个人有10亿粉丝,当他发布一条微博时,News Feed table 需要插入10亿条数据。