圖解系統(tǒng)設(shè)計(jì)之Instagram
0 簡(jiǎn)介
Instagram,分享帶有字幕的照片和視頻的免費(fèi)社交應(yīng)用。帖子可使用標(biāo)簽和地理標(biāo)簽進(jìn)行組織,使其可搜索。若標(biāo)記,帖子對(duì)粉絲和公眾可見(jiàn)。用戶(hù)可將配置文件設(shè)置為私人以限制對(duì)粉絲的訪問(wèn)。
1 需求
1.1 功能性
- 發(fā)布照片和視頻:用戶(hù)可發(fā)布照片和視頻
- 關(guān)注/取關(guān)用戶(hù):用戶(hù)可關(guān)注/取關(guān)其他用戶(hù)
- 點(diǎn)贊或點(diǎn)踩帖子:用戶(hù)可以對(duì)他們關(guān)注的帳戶(hù)的帖子進(jìn)行點(diǎn)贊或不喜歡
- 搜索照片和視頻:用戶(hù)可根據(jù)字幕和位置搜索照片和視頻
- 生成新聞饋送:用戶(hù)可查看新聞饋送。包含他們關(guān)注的所有用戶(hù)的照片和視頻(按時(shí)間順序)。用戶(hù)還可以在其新聞饋送中查看建議的和推廣的照片
1.2 非功能性
- 可擴(kuò)展性:該系統(tǒng)在計(jì)算資源和存儲(chǔ)方面應(yīng)具有擴(kuò)展性,以處理數(shù)百萬(wàn)用戶(hù)
- 延遲:生成新聞饋送的延遲應(yīng)該很低
- 可用性:系統(tǒng)應(yīng)高度可用
- 持久性:任何上傳的內(nèi)容(照片和視頻)都不能丟
- 一致性:可在一致性稍微妥協(xié)。若內(nèi)容(照片或視頻)需一段時(shí)間才能在遠(yuǎn)程區(qū)域的關(guān)注者信息流中顯示,也可接受
- 可靠性:系統(tǒng)須能容忍硬件、軟件故障
2 存儲(chǔ)模式
2.1 實(shí)體
- 用戶(hù):存儲(chǔ)所有與用戶(hù)相關(guān)的數(shù)據(jù),如ID、姓名、電子郵件、簡(jiǎn)介、位置、帳戶(hù)創(chuàng)建日期、上次登錄時(shí)間等。
- 關(guān)注者:存儲(chǔ)用戶(hù)關(guān)系。Instagram有個(gè)單向關(guān)系,如若用戶(hù) A 接受用戶(hù) B 的關(guān)注請(qǐng)求,則用戶(hù) B 可查看用戶(hù) A 的帖子,但反之不成立
- 照片:存儲(chǔ)所有與照片相關(guān)的信息,如ID、位置、字幕、創(chuàng)建時(shí)間等。還需保留用戶(hù) ID 以確定哪張照片屬于哪個(gè)用戶(hù)。用戶(hù) ID 是來(lái)自用戶(hù)表的外鍵
- 視頻:存儲(chǔ)所有與視頻相關(guān)的信息,如ID、位置、字幕、創(chuàng)建時(shí)間等。還需保留用戶(hù) ID 以確定哪個(gè)視頻屬于哪個(gè)用戶(hù)。用戶(hù) ID 來(lái)自用戶(hù)表的外鍵
2.2 Instagram的數(shù)據(jù)模型
圖片
2.3 SQL or NoSQL?
我們的數(shù)據(jù)本質(zhì)是關(guān)系型,并且我們需要數(shù)據(jù)的順序(帖子應(yīng)按時(shí)間順序出現(xiàn))和即使在故障的情況下也不會(huì)丟失數(shù)據(jù)(數(shù)據(jù)持久性)。此外,我們的例子中,我們將從關(guān)系查詢(xún)中受益,如根據(jù)用戶(hù) ID 獲取關(guān)注者或圖像。因此,基于 SQL 的數(shù)據(jù)庫(kù)滿(mǎn)足這些要求。
因此,選擇關(guān)系數(shù)據(jù)庫(kù),并在該數(shù)據(jù)庫(kù)存儲(chǔ)相關(guān)數(shù)據(jù)。
3 頂層設(shè)計(jì)
圖片
- 負(fù)載均衡器:平衡來(lái)自終端用戶(hù)的請(qǐng)求負(fù)載
- 應(yīng)用服務(wù)器:向終端用戶(hù)托管我們的服務(wù)
- 關(guān)系數(shù)據(jù)庫(kù):存儲(chǔ)我們的數(shù)據(jù)
- Blob 存儲(chǔ):存儲(chǔ)用戶(hù)上傳的照片和視頻
4 詳細(xì)設(shè)計(jì)
4.1 上傳、查看和搜索照片
客戶(hù)端請(qǐng)求上傳照片,負(fù)載均衡器將請(qǐng)求傳遞給任何一個(gè)應(yīng)用服務(wù)器,后者向數(shù)據(jù)庫(kù)添加一個(gè)條目。向用戶(hù)發(fā)送已成功存儲(chǔ)照片的更新。若遇到錯(cuò)誤,也會(huì)通知用戶(hù)。
查看照片的過(guò)程與上述流程類(lèi)似??蛻?hù)端請(qǐng)求查看一張照片,從數(shù)據(jù)庫(kù)中獲取與請(qǐng)求匹配的合適的照片,并顯示給用戶(hù)??蛻?hù)端還可以提供關(guān)鍵字來(lái)搜索特定圖像。
讀請(qǐng)求多于寫(xiě)請(qǐng)求,并將內(nèi)容上傳到系統(tǒng)中需要時(shí)間。若分離讀(上傳)寫(xiě)服務(wù),效率會(huì)更高。 由許多服務(wù)器操作的多個(gè)服務(wù)處理相關(guān)請(qǐng)求。讀服 務(wù)執(zhí)行為用戶(hù)獲取所需內(nèi)容的任務(wù),而寫(xiě)服務(wù)有助于將內(nèi)容上傳到系統(tǒng)。
還需緩存數(shù)據(jù)來(lái)處理數(shù)百萬(wàn)次讀取。它通過(guò)使獲取過(guò)程快速來(lái)改善用戶(hù)體驗(yàn)。我們還將選擇延遲加載,這可以最大限度地減少客戶(hù)端的等待時(shí)間。它允許我們?cè)谟脩?hù)滾動(dòng)時(shí)加載內(nèi)容,從而節(jié)省帶寬,并專(zhuān)注于加載用戶(hù)當(dāng)前正在查看的內(nèi)容。這改善了在 Instagram 上查看或搜索特定照片或視頻的延遲。
照片上的讀/寫(xiě)操作:
圖片
4.2 生成timeline
① 拉取方式
當(dāng)用戶(hù)打開(kāi)他們的 Instagram 時(shí),我們發(fā)送timeline生成的請(qǐng)求:
- 先獲取用戶(hù)關(guān)注的人列表
- 獲取他們最近發(fā)布的照片
- 將其存儲(chǔ)在隊(duì)列中并顯示給用戶(hù)
但這種方法響應(yīng)***較慢***,因?yàn)槊看斡脩?hù)打開(kāi) Instagram 時(shí)我們都會(huì)生成timeline
可通過(guò)離線(xiàn)生成timeline,大大減少用戶(hù)感知到的延遲。如在用戶(hù)打開(kāi) Instagram 前,我們定義一個(gè)服務(wù),該服務(wù)會(huì)提前為用戶(hù)獲取相關(guān)數(shù)據(jù),當(dāng)該人打開(kāi) Instagram 時(shí),它會(huì)顯示timeline。這減少了顯示timeline的延遲率。
② 推送方法
推送方法中,每個(gè)用戶(hù)都負(fù)責(zé)將他們發(fā)布的內(nèi)容推送給關(guān)注他們的人的timeline。在之前的方法中,從每個(gè)關(guān)注者那里拉取帖子,但在當(dāng)前方法中,我們將帖子推送給每個(gè)關(guān)注者。
現(xiàn)在只需獲取推送到該特定用戶(hù)的的數(shù)據(jù)來(lái)生成timeline。
基于推送的方法:
圖片
混合方法 — 讓我們將我們的用戶(hù)分為兩類(lèi):
- 基于推送的用戶(hù):關(guān)注者數(shù)量為數(shù)百或數(shù)千的用戶(hù)。
- 基于拉取的用戶(hù):關(guān)注者數(shù)量為數(shù)十萬(wàn)或數(shù)百萬(wàn)的名人用戶(hù)。
時(shí)間軸服務(wù)從基于拉取的關(guān)注者那里拉取數(shù)據(jù)并將其添加到用戶(hù)的時(shí)間軸中?;谕扑偷挠脩?hù)將他們的帖子推送到他們關(guān)注者的時(shí)間軸服務(wù),以便時(shí)間軸服務(wù)可以將其添加到用戶(hù)的時(shí)間軸中。
4.3 在哪存儲(chǔ)時(shí)間軸?
我們針對(duì) userID 將用戶(hù)的時(shí)間表存儲(chǔ)在鍵值存儲(chǔ)中。在請(qǐng)求時(shí),我們從鍵值存儲(chǔ)中獲取數(shù)據(jù)并顯示給用戶(hù)。鍵是 userID,而值是時(shí)間軸內(nèi)容(指向照片和視頻的鏈接)。因?yàn)橹档拇鎯?chǔ)大小通常限制在幾兆字節(jié)內(nèi),所以當(dāng)我們接近大小限制時(shí),我們可以將時(shí)間軸數(shù)據(jù)存儲(chǔ)在 blob 中,并將指向 blob 的鏈接放在鍵的值中。
4.4 Instagram 故事
可向我們的 Instagram 添加一個(gè)名為故事的新功能。在故事功能中,用戶(hù)可以添加一張照片,該照片僅可供他人在 24 小時(shí)內(nèi)查看。我們可以通過(guò)在表中維護(hù)一個(gè)選項(xiàng)來(lái)實(shí)現(xiàn)這一點(diǎn),我們可以在其中存儲(chǔ)故事的持續(xù)時(shí)間。我們可以將其設(shè)置為 24 小時(shí),任務(wù)計(jì)劃程序刪除超過(guò) 24 小時(shí)限制的條目。
5 最終設(shè)計(jì)
Instagram 的最終設(shè)計(jì):
圖片
6 評(píng)估
- 可擴(kuò)展性:我們可以向應(yīng)用服務(wù)層添加更多服務(wù)器以使可擴(kuò)展性更好并處理來(lái)自客戶(hù)端的大量請(qǐng)求。我們還可以增加數(shù)據(jù)庫(kù)的數(shù)量以存儲(chǔ)不斷增長(zhǎng)的用戶(hù)數(shù)據(jù)。
- 延遲:使用緩存和 CDN 已減少了獲取內(nèi)容的時(shí)間。
- 可用性:通過(guò)使用跨全球復(fù)制的存儲(chǔ)和數(shù)據(jù)庫(kù)使系統(tǒng)可用于用戶(hù)。
- 持久性:擁有持久化存儲(chǔ),可維護(hù)數(shù)據(jù)的備份,因此任何上傳的內(nèi)容(照片和視頻)都不會(huì)丟失。
- 一致性:使用了 blob 存儲(chǔ)和數(shù)據(jù)庫(kù)等存儲(chǔ)來(lái)保持?jǐn)?shù)據(jù)的全局一致性。
- 可靠性:數(shù)據(jù)庫(kù)處理復(fù)制和冗余,因此我們的系統(tǒng)保持可靠,數(shù)據(jù)不會(huì)丟失。負(fù)載平衡層會(huì)路由繞過(guò)失敗服務(wù)器的請(qǐng)求
參考:
- 編程嚴(yán)選網(wǎng)