4.设计Twitter,微博

这篇文章你需要掌握,分析QPS->定义要做功能-》设计SERVICE-》设计data SCHEMA-》TRADE OFF DB存储。 -》一个可用的SOLUTION
优化部分,你需要掌握, PULL vs PUSH, 2个的优缺点,如何改进。 3种不同SHARDING方式的优缺点。 缓存如何应用。 三种容错模式(备份,监控,负载均衡)

需求和目标

第一步我们应该询问,需要设计哪些功能,并且这些功能需要支持多少的QPS。
也就是初步判定我们系统的重要功能和QPS。
首先我们先讲一下几个指标的意义。

在發現用戶習慣上,作者首先強調了DAU/MAU這個概念。當然,DAU/MAU這個概念很早以前就被提出了,DAU/MAU一般可叫做當前用戶留存率,兩者相比主要比較來看用戶每月訪問遊戲的平均天數是多少。舉個例子,假設一款遊戲擁有50萬DAU,100萬MAU,其DAU/MAU就是50%,也就是說玩家每月平均體驗遊戲的時間是15天。這一數值越高,說明用戶黏著度越高。通常意義上「20%」被認為是一款產品的最低極限,是保證遊戲能夠達到臨界規模的病毒式傳播和用戶黏性。。如果低於20%那就基本可以不用投入大量精力經營了。接下來我們來看看主流SNS的DAU/MAU對比。

功能要求

用户应该能够发布新推文。

用户应该能够关注/取消其他用户。

用户应该能够标记最喜欢的推文。

该服务应该能够创建和显示用户的时间线,该时间线包括来自用户遵循的所有人的热门推文。

推文可以包含照片和视频。

非功能性要求

我们的服务需要高度可用。

对于时间线生成,系统的可接受延迟为200ms。

一致性可能会受到影响(为了可用性),如果用户暂时没有看到推文是可容忍的

扩展要求

搜索推文。

回复推文。

热门话题 - 当前热门话题/搜索。

标记其他用户。

推文通知。

‘关注谁’的建议

存储和性能

这一步我们需要估计DAU,QPS,以及需要多少的存储空间。
有了QPS,我还要分开来思考,要把读和写分开。
我们假设推特有5亿用户,平均每人10天上线一次。那么DAU就是5000W。
平均每人每天读10条推特,每5天写一条推特。
那么读的QPS大概在,5000W * 10/86400 = 50k/s
写的QPS大概在, 1000W/86400 = 1k/s
然后为了应对峰值,我们需要*3处理。
所以读的QPS大概在150K/S
写的峰值QPS在 3K/S

那么有了qps,我们大概知道需要多大性能的设备或者要用多大的集群。
QPS = 100,个人电脑足够了。
1000的话,需要买个好点的服务器
10k, 需要100+的集群

随后一台WEB 服务器大概可以HANDLE 1000的QPS
SQL 数据库也是
NOSQL 可以到10K
内存数据库可以到1M

下面计算存储。每天有1000W的写,假设都是文字的推特的话。大概一条推特需要500字节的存储。
那么每天需要的磁盘容量是0.5G
未来三年600G的大小。
如果要算上照片,假设10条里面会有一条带照片的推特。那么照片是500KB的话大概还需要60T的磁盘大小。

如果还能上传VEDIO,就更大会。
最后们大概可以计算下带宽。
我们就拿文字举例子,我们每天最高有1.5B的读,每个读500字节。除以86400,大概要75M/S
如果图片算进去就更大了。

设计服务

image.png

设计架构


image.png

存储

数据库需要如何选择?
图片应该是放在文件系统里。TWEET可以放在NOSQL里。用户信息存在SQL里。
这里需要分析一波,SQL VS NOSQL的优缺点。
我这里尝试分析一下为啥用户信息用SQL
1.首先用户的SCHEMA比较固定,是具备SECHMA的。

  1. 用户数据的QPS不会高,因为登陆注册是个使用频率比较低的行为。
  2. 使用SQL数据库,可能可以对用户的一些潜在需要TRANSACTION的行为进行直接HANDLE,如购买付费服务。
    那为啥TWEET需要存在NOSQL 呢?
  3. TWEET的数据是海量的,使用频率极高,用户来都会先读TWEET。NOSQL 响应快
  4. TWEET的信息是半SCHEMA的,也就是后面的列可能会动态变化。
  5. 大量的数据必然需要分布式,NOSQL 水平扩展性好。
    还有一个好友关系,SQL 都 NOSQL都可以。


    image.png

新鲜事如何存取?

PULL模型


image.png

这里要注意的一件事是我们生成了一次feed并将其存储在缓存中。 Jane关注的人们新来的帖子怎么样?如果Jane在线,我们应该有一个机制来排名并将这些新帖子添加到她的Feed中。我们可以定期(比如说每五分钟)执行上述步骤,将较新的帖子排序并添加到她的Feed中。然后,Jane可以通知她可以获取的Feed中有更新的项目。

PULL的优点,写的时候,只要写自己的就好。
查的时候,要查所有,会比较慢。
我们可以拥有专用服务器,这些服务器不断生成用户的新闻源并将其存储在内存中。因此,只要用户请求他们的Feed的新帖子,我们就可以从预先生成的存储位​​置提供服务。使用此方案,用户的新闻源不会在加载时编译,而是定期编译,并在用户请求时返回给用户。

每当这些服务器需要为用户生成订阅源时,他们将首先查询以查看为该用户生成订阅源的最后时间。然后,从那时起将生成新的数据。

Struct {
    LinkedHashMap<FeedItemID> feedItems;
    DateTime lastGenerated;
}

其他问题
a)在发出拉取请求之前,可能不会向用户显示新数据,b)很难找到正确的拉动节奏,因为大多数时间拉取请求将导致空响应没有新数据,造成资源浪费。

PUSH模型
每个用户都有一个NEW FEEDS LIST。 当一个用户发了一条推文时,就往所有关注他的人的LIST里加上一条。
我们可以看到这种方案,读可以直接读。 写是O N


image.png

这种方案的问题是那些明星用户,拥有百万粉丝。要写的工作量超级多。

混合模型
处理馈送数据的另一种方法可以是使用混合方法,即进行拉和推的组合。具体来说,我们可以停止推送具有大量粉丝(名人用户)的用户的帖子,并且只为那些拥有数百(或数千)粉丝的用户推送数据。对于名人用户,我们可以让关注者拉更新。由于推送操作对于拥有大量朋友或关注者的用户而言成本极高,因此,通过禁用推,我们可以节省大量资源。
另一种替代方法可能是用户发布帖子后;我们可以将推限制为只有她的在线朋友。此外,为了从这两种方法中获益,将推送通知和拉服务最终用户组合起来是一个很好的方法。纯粹的推拉模型不太通用。

扩展

如何抉择每次PULL的数量?

这个可以有个默认值,随后我们可以根据用户习惯去动态增大或缩小。比如用户习惯一次看40条,那么我们可以把这个值加大。当然这样增加了编码的复杂性。我们可以让用户自己设置这个SIZE,对一些有抱怨的用户。

我们是不是应该一有新消息就通知用户。

这样做是比较好的,缺点就是会费带宽。如果用户在用自己的流量,那么让用户主动刷新也是不错的选择。

如果我们当前已经用了PULL模型,如何可以改善PULL缺陷?

增加CACHE,访问CACHE的速度会比DB快100倍,同时使得可以接受的QPS提高100倍。


image.png

如果我们当前已经用了PUSH模型,如何可以改善PUSH缺陷?

PUSH最大的问题是明星用户问题。因为明星用户没发一条推,就会通知海量的粉丝。
有2个思路,思路1,对那些不活跃的用户之后更新,也就是设置一个优先级。活跃按照最近上线时间来判断。
思路2,就是设置一个阈值来决定是不是明星用户,如果是明星用户就不推了。让那些用户自己拉。
但是有阈值之后,就会有摇摆问题。比如一个明星的粉丝正好在阈值附近。
这个问题可以不要立刻更新,把明星用户做一个标签,统计分析最近一个月的平均粉丝,然后每周更新。可以避免这个问题。

什么情况下适合PULL,什么情况下适合PUSH?

因为PULL需要很多内存,资源充足很关键。
实时性要求高的也要用PULL。
用户发帖多,和单向好友关系。因为单向好友关系,就不需要对方同意,明星很容易有很多关注者。这时候用PULL比较好。

资源少,实时性要求不高,发帖少,双向好友关系,不容易有明星问题。可以用PUSH。

如何扩展?

首先可以想到根据USER ID 来SHARDING。 这样做的好处是查找自己的TIMELINE很方便。因为就在一台服务器上。但是坏处就是当一个用户非常热,这样会造成那个服务器负载过大。
其次,我们看下用TWEET ID 来SHARDING。 这样在整合TIMELINE 时,会不得不向好多服务器发起QUERY。这样会造成较大的延迟。
如果我们用TWEET 创建时间来SHARDING。 这样最近的TWEET都会在一个服务器上。NEWS FEED比较好的能够容易获取到。
这样会引申出一种比较巧妙的做法。就是TWEET ID 就是时间撮+递增ID。前32为放上秒数,后32位(应该不用)算下每秒最多可能有多少个TWEET。放ID。

缓存策略如何应用

首先使用LRU,可以缓存到最热的推文。
其次可以根据20 80的原则去缓存,20%最常看的推文。
这里很大可能是3天内的推文。我们可以为其建缓存。
我们的缓存就像一个哈希表,其中'key'将是'OwnerID','value'将是一个双向链表,其中包含过去三天来该用户的所有推文。由于我们想首先检索最新的数据,我们总是可以在链表的头部插入新的推文,这意味着所有较旧的推文都将在链表的尾部附近。因此,我们可以从尾部删除推文,为更新的推文腾出空间。

服务器挂了怎么办?

我们可以使用主从备份,读写分离的思想。我们有多个从库负责提供读。然后主库负责写。
主库挂了,从库顶上。
在服务器端,我们可以使用负载均衡器。

有能力监控我们的系统至关重要。我们应该不断收集数据,以便即时了解我们的系统如何运作。我们可以收集以下指标/计数器,以了解我们的服务表现:

每天/秒的新推文,每日峰值是多少?
时间线投放统计数据,我们的服务每天/秒发送多少推文。
用户看到刷新时间线的平均延迟。
通过监视这些计数器,我们将意识到是否需要更多复制或负载平衡或缓存等。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 213,711评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,079评论 3 387
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 159,194评论 0 349
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,089评论 1 286
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,197评论 6 385
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,306评论 1 292
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,338评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,119评论 0 269
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,541评论 1 306
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,846评论 2 328
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,014评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,694评论 4 337
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,322评论 3 318
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,026评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,257评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,863评论 2 365
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,895评论 2 351

推荐阅读更多精彩内容

  • X扯闲篇 系统设计题目就是一个大坑 没有一个标准答案的意思就是面试官如果真跟你过不去随便挂人 跟玩儿似的。说答案的...
    Sonass阅读 8,134评论 0 9
  • 每天进步一点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点~~从开始只能写几句话、模仿别人的观点,到现...
    一个帅气的名字呀阅读 18,069评论 4 31
  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 171,914评论 25 707
  • 星期五放学后我制作了周末的学习计划,周末时间里要完成哪些作业,学习哪些知识心里也就有目标了。这几天我把老师留的作业...
    张轩赫阅读 156评论 1 3
  • 《天灸》 (曬太陽) 出生于1905年的張明珠,她88歲的時候患腸癌,一共做過3次大手術,切除了全部結腸,大腸也被...
    AnnaLi_fed9阅读 458评论 0 0