4s

4s是指 Scenario(场景) Service(服务) Storgae(储存) Scale(升级)

Scenario(场景)

DAU(https://yueqingsheng.github.io/post-images/1590461765777.png)
MAU(月活跃用户 ) 估计 MAU约等于2*DAU

  1. Enumerate(列举)列出所有功能
  2. Sort 筛选核心功能

    Timeline(用户发布的内容)
    News Feed(用户关注的内容/信息流)
    3.分析 QPS(Queries per second)
    QPS = DAU*用户平均每天请求次数/每天多少秒(86400)
    PEAK(峰值) 约等于= QPS *3
    快速增长 Fast Growing 将来的增长
    读频率
    写频率 <=1 每个用户

    QPS
    Single point failure(一个坏了,快速切换到另一台服务器)
    普通web server 只能达到 10QPS
    SQL Databsase 1k QPS (join index很慢)
    NoSQL 10k ~ 1m

Service(服务) Service oriented(微服务化,大系统拆分小服务)

  1. Replay 每个需求添加一个服务
  2. Merge 归并相同的服务

Storage 存储

  1. 每个Service 选择存储结构
    Database File System Cache
  2. Schema 细化表结构
    primary key 一般使用id作为primary key,因为username和email有可能被修改,导致连串修改。

News Feed

pull model: merge k sorted arrays
缺点: 现算,每次发送请求

push model:

fanout: In message-oriented middleware solutions, fan-out is a messaging pattern used to model an information exchange that implies the delivery (or spreading) of a message to one or multiple destinations possibly in parallel, and not halting the process that executes the messaging to wait for any response to that message.(在面向消息的中间件解决方案中,fan-out是一种用于建模的消息交换体式格局,它意味着向一个或多个目的地可能并行地传递(或传播)一个消息,而不是让执行消息的进程停止等待对该消息的任何响应。)

Denormalized 叫去标准化。通俗的解释是,通过在不同的 Table 中存储同一份数据的(也就是说至少一份是冗余数据)的形式,来加速数据的查询。因为当数据只存储在一个固定的 Table A 的时候,其他 Table B访问时如果需要同时取得关联的 Table A 的数据,则需要进行 join 操作之类的,会比较慢。一个例子就是在,统计有多少人点赞了一个帖子,可以通过 select count() from like_table where post_id= 的方式来获取,但是也可以在 post table 中新增一个 like_count,每次点赞就 +1。这里 like_count 就是一个 denormalized field,因为是可以通过 select count() 在 like table 中获得的。
fanout 过程异步执行 async

缺点

粉丝过多,创建的记录会变多
push 对1对特别多的 现象速度很慢,每次加一个新的内容,通知所有关注的人。

Scale

Pull 改进:

Cache N cache请求(N是关注的好友数)
Trade off: Cache 1000条,或200条

Push 改进:

在现有基础上做尽可能小的改动

Push+ Pull

普通用户 push
明星用户 pull
在获取更新之前,主动merge明星的更新

定义明星问题

掉粉前,明星不push,掉粉后状态改变,不pull。数据丢失 =》永久状态,只要达到过就固定状态

Done is than perfect

课后习题分析以及改进



我的数据结构设计:
Tweet_extend 扩展tweet加上创建时间。
tweet 储存每个用户的tweet list
follow_relation 储存了用户的关注关系表

答案中关系用了map<int, set> 用户id到这个用户关注的人的id的映射,这样设计1对多关系的映射少了在代码中loop判断用户。提升了查询速度。

Push model:

把每个人建立一个newsfeed map<int, newsfeed>, 每当新建一个新twitter,给所有关注的 newsfeed里添加一个。如果Push的时候是按照时间顺序,获取newsfeed的时候就不用sort,拿头10个就行了。

I am a real pikachu!