設(shè)計 Twitter 時間線和搜索 (或者 Facebook feed 和搜索)
第一步:通過討論,明確限制及用例,確定Scope
支持的用例:
- 用戶發(fā)一條tweet
- 系統(tǒng)將該tweet推送給該用戶的followers,并發(fā)送通知
- 用戶查看自己的user timeline
- 用戶查看別人的home timeline(follow 的人)
- 用戶通過關(guān)鍵詞搜索
- 系統(tǒng)高可用 high availability
不支持的用例:
- 系統(tǒng)不支持將該tweet推送給第三方系統(tǒng),例如Firehose。
- 系統(tǒng)不支持隱藏tweet功能。
- 系統(tǒng)不支持統(tǒng)計Analytics功能。
Constraints and assumptions:
- 訪問不均勻
- 發(fā)送及推送tweet要快
- 100 million 用戶
- 平均每個用戶有 10 個 followers
- 每天 500 million 新tweet,乘以10,等于每天 5 billion 個推送,每秒60,000次
- 每月 15 billion 寫請求 = 500 million * 30,每秒6,000次
- 每月 250 billion 讀請求,每秒100,000次
- 每月 10 billion 搜索請求,每秒4次
計算規(guī)模:
對于每一個tweet:
- tweet_id:8 bytes
- user_id:32 bytes
- text:140 bytes
- media:10 KB average
- 總共: ~10 KB
對于每一個月:
- 新tweet內(nèi)容:150 TB = 10 KB * 500 million * 30
- 三年:~5.4 PB = 150 TB * 36
第二步:高層次設(shè)計
設(shè)計 Twitter 時間線和搜索 (或者 Facebook feed 和搜索)
第三步:設(shè)計核心組件
Tweet基本信息存儲在關(guān)系型數(shù)據(jù)庫MySQL中。
Tweet包含的圖片及視頻等內(nèi)容存儲在 Object Store 中,可以是 Amazon S3,或者文檔型的NoSQL,例如 MongoDB。
對于Write API:設(shè)計為一個REST API
- 將Tweet基本信息存儲在關(guān)系型數(shù)據(jù)庫MySQL中。
- 圖片及視頻等內(nèi)容存儲在 Object Store 中。
- 使用 Fan Out Service:
- 使用 User Graph Service 來查詢該用戶的followers,隨后在Memory Cache中更新對應(yīng)每一個follower的home timeline。
- 使用Search Service來存儲這個tweet,用來支持快速查詢。
- 使用Notification Service來推送給該用戶的followers。
使用Redis作為Memory Cache,并使用list結(jié)構(gòu),例如:
tweet n+2 tweet n+1 tweet n
| 8 bytes 8 bytes 1 byte | 8 bytes 8 bytes 1 byte | 8 bytes 8 bytes 1 byte |
| tweet_id user_id meta | tweet_id user_id meta | tweet_id user_id meta |
對于Read API:設(shè)計為一個REST API
- 使用Tweet Info讀取tweet詳細信息。
- 使用User Info讀取user詳細信息。
- 從 Memory Cache 中讀取 user timeline 和 home timeline,找不到,則查詢數(shù)據(jù)庫。
對于Search API:設(shè)計為一個REST API
- 解析輸入字符串:
- 去除標記 markup
- 分詞
- Fix 輸入錯誤 typo
- 規(guī)范化大小寫
- 使用Search Service進行搜索。包括結(jié)果的 merges, ranks, sorts 等等。
第四步:擴展設(shè)計
設(shè)計 Twitter 時間線和搜索 (或者 Facebook feed 和搜索)
- 為了服務(wù)不同區(qū)域的用戶,加快訪問的速度,使用CDN加速,并緩存靜態(tài)內(nèi)容,例如圖片,視頻等等。
- 為了同時響應(yīng)更多請求,對服務(wù)器水平擴展,并使用Load Balancer做負載均衡。
- 由于是讀多寫少,可以采用主從復(fù)制的數(shù)據(jù)庫模式。主庫同時負責(zé)讀取和寫入操作,并復(fù)制寫入到一個或多個從庫中,從庫只負責(zé)讀操作。
其他一些優(yōu)化思想:
- Memory Cache 只保留活躍用戶(最近30天上線過)的timeline,且只保留最近的100條tweet。
- Tweet Info Service 只保留最近一個月的Tweet。
- User Info Service 只保留活躍用戶的信息。