圖解系統設計之Instagram

張哥說技術發表於2023-12-08



來源:JavaEdge

0 簡介

Instagram,分享帶有字幕的照片和影片的免費社交應用。帖子可使用標籤和地理標籤進行組織,使其可搜尋。若標記,帖子對粉絲和公眾可見。使用者可將配置檔案設定為私人以限制對粉絲的訪問。

1 需求

1.1 功能性

  • 釋出照片和影片:使用者可釋出照片和影片
  • 關注/取關使用者:使用者可關注/取關其他使用者
  • 點贊或點踩帖子:使用者可以對他們關注的帳戶的帖子進行點贊或不喜歡
  • 搜尋照片和影片:使用者可根據字幕和位置搜尋照片和影片
  • 生成新聞饋送:使用者可檢視新聞饋送。包含他們關注的所有使用者的照片和影片(按時間順序)。使用者還可以在其新聞饋送中檢視建議的和推廣的照片

1.2 非功能性

  • 可擴充套件性:該系統在計算資源和儲存方面應具有擴充套件性,以處理數百萬使用者
  • 延遲:生成新聞饋送的延遲應該很低
  • 可用性:系統應高度可用
  • 永續性:任何上傳的內容(照片和影片)都不能丟
  • 一致性:可在一致性稍微妥協。若內容(照片或影片)需一段時間才能在遠端區域的關注者資訊流中顯示,也可接受
  • 可靠性:系統須能容忍硬體、軟體故障

2 儲存模式

2.1 實體

  • 使用者:儲存所有與使用者相關的資料,如ID、姓名、電子郵件、簡介、位置、帳戶建立日期、上次登入時間等。
  • 關注者:儲存使用者關係。Instagram有個單向關係,如若使用者 A 接受使用者 B 的關注請求,則使用者 B 可檢視使用者 A 的帖子,但反之不成立
  • 照片:儲存所有與照片相關的資訊,如ID、位置、字幕、建立時間等。還需保留使用者 ID 以確定哪張照片屬於哪個使用者。使用者 ID 是來自使用者表的外來鍵
  • 影片:儲存所有與影片相關的資訊,如ID、位置、字幕、建立時間等。還需保留使用者 ID 以確定哪個影片屬於哪個使用者。使用者 ID 來自使用者表的外來鍵

2.2 Instagram的資料模型

圖解系統設計之Instagram

2.3 SQL or NoSQL?

我們的資料本質是關係型,並且我們需要資料的順序(帖子應按時間順序出現)和即使在故障的情況下也不會丟失資料(資料永續性)。此外,我們的例子中,我們將從關係查詢中受益,如根據使用者 ID 獲取關注者或影像。因此,基於 SQL 的資料庫滿足這些要求。

因此,選擇關聯式資料庫,並在該資料庫儲存相關資料。

3 頂層設計

圖解系統設計之Instagram
  • 負載均衡器:平衡來自終端使用者的請求負載
  • 應用伺服器:向終端使用者託管我們的服務
  • 關聯式資料庫:儲存我們的資料
  • Blob 儲存:儲存使用者上傳的照片和影片

4 詳細設計

4.1 上傳、檢視和搜尋照片

客戶端請求上傳照片,負載均衡器將請求傳遞給任何一個應用伺服器,後者向資料庫新增一個條目。向使用者傳送已成功儲存照片的更新。若遇到錯誤,也會通知使用者。

檢視照片的過程與上述流程類似。客戶端請求檢視一張照片,從資料庫中獲取與請求匹配的合適的照片,並顯示給使用者。客戶端還可以提供關鍵字來搜尋特定影像。

讀請求多於寫請求,並將內容上傳到系統中需要時間。若分離讀(上傳)寫服務,效率會更高。 由許多伺服器操作的多個服務處理相關請求。讀服 務執行為使用者獲取所需內容的任務,而寫服務有助於將內容上傳到系統。

還需快取資料來處理數百萬次讀取。它透過使獲取過程快速來改善使用者體驗。我們還將選擇延遲載入,這可以最大限度地減少客戶端的等待時間。它允許我們在使用者滾動時載入內容,從而節省頻寬,並專注於載入使用者當前正在檢視的內容。這改善了在 Instagram 上檢視或搜尋特定照片或影片的延遲。

照片上的讀/寫操作:

圖解系統設計之Instagram

4.2 生成timeline

① 拉取方式

當使用者開啟他們的 Instagram 時,我們傳送timeline生成的請求:

  • 先獲取使用者關注的人列表
  • 獲取他們最近釋出的照片
  • 將其儲存在佇列中並顯示給使用者

但這種方法響應***較慢***,因為每次使用者開啟 Instagram 時我們都會生成timeline

可透過離線生成timeline,大大減少使用者感知到的延遲。如在使用者開啟 Instagram 前,我們定義一個服務,該服務會提前為使用者獲取相關資料,當該人開啟 Instagram 時,它會顯示timeline。這減少了顯示timeline的延遲率。

② 推送方法

推送方法中,每個使用者都負責將他們釋出的內容推送給關注他們的人的timeline。在之前的方法中,從每個關注者那裡拉取帖子,但在當前方法中,我們將帖子推送給每個關注者。

現在只需獲取推送到該特定使用者的的資料來生成timeline。

基於推送的方法:

圖解系統設計之Instagram

混合方法 — 讓我們將我們的使用者分為兩類:

  • 基於推送的使用者:關注者數量為數百或數千的使用者。
  • 基於拉取的使用者:關注者數量為數十萬或數百萬的名人使用者。

時間軸服務從基於拉取的關注者那裡拉取資料並將其新增到使用者的時間軸中。基於推送的使用者將他們的帖子推送到他們關注者的時間軸服務,以便時間軸服務可以將其新增到使用者的時間軸中。

4.3 在哪儲存時間軸?

我們針對 userID 將使用者的時間表儲存在鍵值儲存中。在請求時,我們從鍵值儲存中獲取資料並顯示給使用者。鍵是 userID,而值是時間軸內容(指向照片和影片的連結)。因為值的儲存大小通常限制在幾兆位元組內,所以當我們接近大小限制時,我們可以將時間軸資料儲存在 blob 中,並將指向 blob 的連結放在鍵的值中。

4.4 Instagram 故事

可向我們的 Instagram 新增一個名為故事的新功能。在故事功能中,使用者可以新增一張照片,該照片僅可供他人在 24 小時內檢視。我們可以透過在表中維護一個選項來實現這一點,我們可以在其中儲存故事的持續時間。我們可以將其設定為 24 小時,任務計劃程式刪除超過 24 小時限制的條目。

5 最終設計

Instagram 的最終設計:

圖解系統設計之Instagram

6 評估

  • 可擴充套件性:我們可以嚮應用服務層新增更多伺服器以使可擴充套件性更好並處理來自客戶端的大量請求。我們還可以增加資料庫的數量以儲存不斷增長的使用者資料。
  • 延遲:使用快取和 CDN 已減少了獲取內容的時間。
  • 可用性:透過使用跨全球複製的儲存和資料庫使系統可用於使用者。
  • 永續性:擁有持久化儲存,可維護資料的備份,因此任何上傳的內容(照片和影片)都不會丟失。
  • 一致性:使用了 blob 儲存和資料庫等儲存來保持資料的全域性一致性。
  • 可靠性:資料庫處理複製和冗餘,因此我們的系統保持可靠,資料不會丟失。負載平衡層會路由繞過失敗伺服器的請求

參考:

  • 程式設計嚴選網

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/70024923/viewspace-2999233/,如需轉載,請註明出處,否則將追究法律責任。

相關文章