Spotify 是世界上最受歡迎的音樂流媒體平臺,每月活躍 使用者 (MAU) 超過 6 億,付費使用者超過 2 億。在本文中,我們將學習如何設計 像 Spotify 這樣的音樂流媒體服務,該服務每天可以處理數以百計的數百萬使用者和數十億個音樂流,確保低延遲和高可用性。
1.需求收集
功能需求
在深入研究設計之前,讓我們概述一下功能性和非功能性需求。
搜尋:使用者可以搜尋歌曲、藝術家、專輯和播放列表。
音樂流媒體:使用者可以實時流式傳輸歌曲。
播放列表:使用者可以建立、共享和修改播放列表。
音樂推薦:使用者根據其收聽歷史記錄和偏好接收歌曲推薦。
廣告支援模式:免費套餐使用者在播放幾首歌曲後就會看到廣告。
非功能性需求:
可擴充套件性:該系統應處理全球數以百計的數百萬使用者,並能夠同時流式傳輸數百萬首歌曲。
低延遲:實時流式處理必須具有低延遲,才能獲得無縫的使用者體驗。
高可用性:系統必須始終可用,停機時間最短。
全球覆蓋:支援來自不同地理區域的使用者,可能利用 CDN 更快地提供音訊檔案。
2. 容量估算
我們假設以量特徵:
使用者群
總活躍使用者數:5 億
日活躍使用者:1 億
每位使用者每天的平均流數:10
歌曲平均大小:5 MB
平均歌曲時長: 4 分鐘
歌曲目錄大小:1 億首歌曲
網路頻寬估算
每日歌曲流 = 100M 使用者× 10 首歌曲 = 10 億次流/天
每天的資料傳輸量 = 10 億× 5 MB = 5 PB/天
每秒資料傳輸量 = 5PB / 86400 = 58GB/秒
儲存估算
音樂總儲存 = 1 億首歌曲 × 5 MB/歌曲 = 500 TB
假設每首歌曲有 2 KB 的後設資料,每個使用者有 10 KB 的後設資料(使用者詳細資訊、首選項、播放列表等)
歌曲後設資料總儲存量 = 1 億首歌曲× 2 KB = 200 GB
5 億使用者的總儲存 = 5 億× (10KB) = 5TB
快取估計
快取在減少儲存系統的負載和確保熱門內容的低延遲方面發揮著重要作用:
經常播放的歌曲後設資料可以快取在記憶體中
讓我們假設前 20% 的歌曲貢獻了 80% 的請求
假設 Spotify 有 1 億首歌曲,並且前 20% 的歌曲被快取
快取大小 = 2000 萬首歌曲 × 2KB/首歌曲 = 40GB
3. 高層設計
Spotify 的系統架構可以分為幾個高階元件:
3.1 客戶端應用程式
客戶端應用程式包括 Spotify 的移動、桌面和 Web 版本,它提供了一個乾淨直觀的 UI 來與服務互動。它與用於搜尋、流式傳輸、播放列表和推薦的後端 API 進行通訊,並透過在裝置上快取音樂(下載的內容)來支援離線收聽。
3.2 負載均衡器
Load Balancer 是所有客戶端請求的入口點。它將傳入的客戶端請求均勻地分佈在後端服務的多個例項之間,從而防止任何單個伺服器過載。
3.3 應用伺服器
接收來自負載均衡器的傳入請求,並將請求重定向到相應的服務。
3.4 服務
流媒體服務:實時處理從儲存系統到使用者裝置的音樂流媒體。
搜尋服務:處理歌曲、藝術家、專輯和播放列表的搜尋。
推薦服務:根據使用者行為(如收聽歷史記錄、點贊和播放列表建立)提供個性化音樂推薦。
廣告服務:處理免費套餐使用者的廣告投放。
使用者服務:儲存和管理使用者配置檔案,包括個人資訊、訂閱型別和首選項。管理使用者播放列表,允許使用者建立、修改和共享它們。
3.5 儲存
資料庫:儲存使用者配置檔案、播放列表、歌曲後設資料和搜尋索引。
Blob 儲存:用於處理音訊和廣告檔案的大規模儲存的分散式儲存系統(例如 AWS S3)。
內容分發網路 (CDN):用於以最小的延遲高效地向全球使用者交付大型音訊檔案。
快取:快取經常訪問的資料,例如流行歌曲和推薦,以提高效能並減少儲存和資料庫系統的負載。
3.6 分析服務
分析和監控服務跟蹤使用者參與度、系統效能並記錄系統執行狀況。
它會在檢測到問題時生成警報,並記錄所有系統活動以進行故障排除。
4. 資料庫設計
以下是我們需要儲存在資料庫中的關鍵實體:
Users, Songs, Artists, Albums, Playlists, Streams, Search Index and Recommendations.
鑑於資料型別的多樣性和高查詢需求,我們結合使用了關聯式資料庫、NoSQL 資料庫和分散式儲存系統。
4.1 結構化資料的關聯式資料庫
要儲存高度結構化的資料,如使用者配置檔案、播放列表、歌曲後設資料、藝術家和專輯,我們可以使用 PostgreSQL 或 MySQL 等關聯式資料庫。
計劃型別(免費、高階、家庭等)。
儲存中歌曲檔案的 URL(例如 AWS S3)。
歌曲的長度(以秒為單位)。
4.2 用於非結構化資料的 NoSQL 資料庫
要儲存非結構化和半結構化資料,我們可以使用 MongoDB、Cassandra 或 DynamoDB 等 NoSQL 資料庫。NoSQL 資料庫提供靈活性和可擴充套件性,使其成為處理高度動態資料(如推薦和搜尋索引)的理想選擇。
推薦表
Spotify 根據使用者的收聽行為為使用者生成推薦,並且這些資料會經常更新。示例:
搜尋索引
搜尋索引儲存在 Elasticsearch 等 NoSQL 資料庫中 ,以便跨歌曲、藝術家和專輯進行快速、模糊的搜尋查詢。這些索引會隨著新內容的新增而不斷更新。示例
4.3 分散式儲存系統
要儲存大量音訊和廣告檔案,我們可以使用像 AWS S3 這樣的分散式儲存系統。S3 可確保高永續性和可用性,使其成為處理大型靜態檔案的理想儲存解決方案。
示例儲存物件:
檔案: https://s3.amazonaws.com/spotify/songs/blinding_lights.mp3
後設資料:檔案大小:4 MB,位元率:128 kbps,格式:MP3
4.4 內容分發網路 (CDN)
我們使用內容分發網路 (CDN) 以最小的延遲將大型音訊檔案(歌曲)分發給全球使用者。透過從 CDN 邊緣伺服器提供音樂,Spotify 確保 為世界各地的使用者提供低延遲的音樂流媒體體驗,最大限度地減少緩衝時間並減少中央儲存系統的負載。原始音樂檔案儲存在分散式儲存系統(例如 AWS S3)中。CDN 在首次請求歌曲時從此源儲存中提取歌曲,並將其快取以供將來請求。
4.5 快取層
快取經常訪問的資料(如使用者首選項、流行歌曲或推薦)可以提高效能。可以使用 Redis 等快取層 來臨時儲存此資料。
快取資料示例:
搜尋查詢:快取熱門搜尋查詢,以避免重複命中搜尋索引。
流行歌曲:可以快取經常流式傳輸的歌曲以減少資料庫查詢。
使用者首選項:將使用者喜歡的歌曲和播放列表儲存在快取中,以便更快地檢索。
示例 — 快取中使用者首選項的 SET/GET 查詢:
SET user:preferences:12345 "{liked_songs: [1, 2, 3], playlists: [10, 11, 12]}" GET user:preferences:12345
4.6 分析和監控資料(資料倉儲)
分析和監控資料對於跟蹤使用者參與度、系統效能和識別潛在問題至關重要。資料在資料倉儲或分散式資料儲存(例如 Hadoop、BigQuery)中聚合和處理。
Analytics 的主要用例:
使用者參與度:有關流、跳過和播放列表新增的資料用於生成對使用者行為的見解。
系統監控:來自各種服務的日誌用於監控系統執行狀況、檢測異常和執行效能調整。
版稅計算:流資料用於根據歌曲播放量和地理覆蓋範圍計算藝術家的付款。
流日誌示例:
5. 系統 API 設計
我們將設計直觀、高效且可擴充套件的 RESTful API。讓我們將 API 設計分解為幾個關鍵端點:
5.1 搜尋 API
搜尋 API 允許使用者搜尋歌曲、藝術家、專輯或播放列表。搜尋結果根據相關性、受歡迎程度和使用者偏好進行排名。
Endpoints 端點
GET /search
GET /搜尋
查詢引數:
query
: 搜尋詞(例如,“Blinding Lights”)。
type
:要搜尋的資源型別(歌曲
、藝術家
、專輯
、播放列表
)。
limit
:要返回的最大結果數(預設值:20)。
offset
:用於分頁(預設值:0)。
Response: 響應:
{
"results": [
{
"type": "song",
"id": "12345",
"title": "Blinding Lights",
"artist": "The Weeknd",
"album": "After Hours"
},
{
"type": "artist",
"id": "67890",
"name": "The Weeknd"
}
]
}
{
"results": [
{
"type": "song",
"id": "12345",
"title": "Blinding Lights",
"artist": "The Weeknd",
"album": "After Hours"
},
{
"type": "artist",
"id": "67890",
"name": "The Weeknd"
}
]
}
5.2 音樂流媒體 API
Streaming API 處理音樂檔案從後端或 CDN 到使用者裝置的交付。
Endpoint
獲取 /stream/{song_id}
響應:
HTTP 302 重定向到託管歌曲的 CDN URL:
{
"url": "https://cdn.spotify.com/song/12345"
}
5.3 推薦 API
Recommendations API 根據使用者的收聽歷史記錄、偏好和喜好提供個性化的歌曲建議.
端點
GET /recommendations/{user_id}
查詢引數:
limit
:要返回的建議數(預設值:10)。
響應:
{
"recommendations": [
{
"song_id": "12345",
"title": "Blinding Lights",
"artist": "The Weeknd",
"score": 0.98
},
{
"song_id": "67890",
"title": "Can't Feel My Face",
"artist": "The Weeknd",
"score": 0.95
}
]
}
5.4 廣告投放 API
對於免費套餐使用者,Spotify 將廣告注入他們的收聽體驗中。Ad Delivery API 根據使用者偏好和人口統計資料獲取和提供個性化廣告。
端點
獲取 /ads/{user_id}
獲取要在音樂流式傳輸期間播放的使用者廣告。
響應:
{
"ad_id": "ad12345",
"ad_url": "https://cdn.spotify.com/ads/ad12345.mp3",
"duration": 30
}
6. 深入研究關鍵元件
6.1 音樂流媒體服務
流媒體服務是 Spotify 架構的核心,負責高效、安全、可靠地實時向數百萬使用者交付音樂內容。音樂檔案的實際交付由內容分發網路(Cloudflare、AWS CloudFront)管理。這可確保從靠近使用者的地理分散式伺服器提供音樂,從而最大限度地減少延遲和頻寬消耗。
請求工作流
客戶端傳送流式處理請求(例如 /stream/{song_id}
)。
App 伺服器對使用者進行鑑權,並將請求路由到 Streaming Service。
如果歌曲不在 CDN 中,則流式處理服務會檢索音訊檔案的位置(從 Blob 儲存中)並將檔案推送到最近的 CDN 邊緣伺服器。CDN 返回指向流式處理服務的 URL 以流式傳輸音訊。
CDN URL 將返回給客戶端,允許客戶端流式傳輸音訊。
6.2 推薦服務
推薦系統分析使用者的收聽習慣、喜歡和播放列表。它結合使用了協作篩選(基於具有相似偏好的使用者)和基於內容的篩選(基於歌曲後設資料)。
協同過濾
協同過濾是推薦系統中最常用的技術之一。此方法利用具有相似音樂品味的使用者的行為來生成推薦。
基於使用者的協作過濾: 此技術根據使用者的收聽歷史記錄對使用者進行分組。例如,如果使用者 A 和使用者 B 都經常收聽同一組藝術家和歌曲,則系統可能會推薦使用者 A 聽過但使用者 B 沒有聽過的歌曲。
基於ITEM的協作過濾:在這種技術中,根據歌曲與使用者之前喜歡的歌曲的相似性來推薦歌曲。如果很多喜歡歌曲 X 的使用者也喜歡歌曲 Y,系統會將歌曲 Y 推薦給聽過歌曲 X 的使用者。
基於內容的篩選
基於內容的篩選側重於歌曲的屬性,例如流派、藝術家、專輯、速度和樂器,以向使用者推薦類似的歌曲。
歌曲屬性: Spotify 收集每首歌曲的後設資料,包括流派、節奏、情緒和樂器。此資料用於推薦與使用者已經喜歡或收聽的歌曲具有相似屬性的歌曲。
音樂人相似度:如果使用者聆聽了特定音樂人的多首歌曲,系統可能會根據共同的屬性(例如流派、風格)推薦類似音樂人的歌曲。
6.3 搜尋服務
Spotify 中的搜尋服務允許使用者有效地從龐大的目錄中查詢歌曲、藝術家、專輯、播放列表和播客。Search Service 的體系結構可以分為以下關鍵元件:
Query Parser:解釋和規範化使用者的搜尋查詢。
搜尋索引:動態更新的索引,包含所有歌曲、藝術家、專輯和播放列表的後設資料。可以使用 Elasticsearch 或 Apache Solr 等搜尋引擎來構建和管理此索引。
排名引擎:搜尋索引返回匹配結果後,排名引擎會對結果進行排序,以確保最相關的結果顯示在頂部。
個性化層:根據使用者的收聽歷史記錄、偏好和人口統計資訊自定義搜尋結果。
搜尋自動完成:在使用者鍵入查詢時為使用者提供建議,從而加快搜尋過程。
Cache Layer:快取經常搜尋的查詢,以提高效能並減少後端的負載。
搜尋索引更新器: 確保搜尋索引與新增到 Spotify 目錄中的新內容保持同步。
7. 解決關鍵問題和瓶頸
7.1 可擴充套件性
分片:要擴充套件 SQL 資料庫並均勻分配負載,請對使用者、播放列表和歌曲後設資料等大型表實施分片。
索引:在 user_id 和 playlist_id 等經常訪問的欄位上新增索引以提高查詢效能。
分割槽:NoSQL 資料庫可以使用分割槽策略將資料分佈到多個節點,從而確保即使在大規模情況下也能實現低延遲訪問。
TTL (Time to Live):為快取資料提供 TTL,以確保過時的資料定期失效。
7.2 可靠性
為了確保高可用性,Spotify 應實施容錯系統:
複製的資料庫:跨多個資料中心複製使用者、歌曲和播放列表資料,以防止資料丟失。
快取複製:Redis 可以配置為跨多個例項複製快取資料,以實現容錯。
自動擴充套件:根據流量負載自動擴充套件伺服器數量。
正常故障轉移:如果一臺伺服器發生故障,流量將重新路由到另一臺伺服器,而不會中斷服務。
監控和警報:實施全面的監控和警報系統。
7.3 使用者安全
Spotify 處理敏感資料,例如使用者個人資料和支付資訊。
身份驗證:使用 OAuth 2.0 進行安全的使用者身份驗證。
加密:加密所有傳輸中和靜態的敏感資料。
Rate Limiting:對使用者進行速率限制,以確保來自單個客戶端的過多 API 請求受到限制,以保護系統。
資料隱私:實施強大的訪問控制,以確保使用者資料不被洩露或濫用。
今天先到這兒,希望對雲原生,技術領導力, 企業管理,系統架構設計與評估,團隊管理, 專案管理, 產品管理,資訊保安,團隊建設 有參考作用 , 您可能感興趣的文章:
構建創業公司突擊小團隊
國際化環境下系統架構演化
微服務架構設計
影片直播平臺的系統架構演化
微服務與Docker介紹
Docker與CI持續整合/CD
網際網路電商購物車架構演變案例
網際網路業務場景下訊息佇列架構
網際網路高效研發團隊管理演進之一
訊息系統架構設計演進
網際網路電商搜尋架構演化之一
企業資訊化與軟體工程的迷思
企業專案化管理介紹
軟體專案成功之要素
人際溝通風格介紹一
精益IT組織與分享式領導
學習型組織與企業
企業創新文化與等級觀念
組織目標與個人目標
初創公司人才招聘與管理
人才公司環境與企業文化
企業文化、團隊文化與知識共享
高效能的團隊建設
專案管理溝通計劃
構建高效的研發與自動化運維
某大型電商雲平臺實踐
網際網路資料庫架構設計思路
IT基礎架構規劃方案一(網路系統規劃)
餐飲行業解決方案之客戶分析流程
餐飲行業解決方案之採購戰略制定與實施流程
餐飲行業解決方案之業務設計流程
供應鏈需求調研CheckList
企業應用之效能實時度量系統演變
如有想了解更多軟體設計與架構, 系統IT,企業資訊化, 團隊管理 資訊,請關注我的微信訂閱號:
作者:Petter Liu
出處:http://www.cnblogs.com/wintersun/
本文版權歸作者和部落格園共有,歡迎轉載,但未經作者同意必須保留此段宣告,且在文章頁面明顯位置給出原文連線,否則保留追究法律責任的權利。
該文章也同時釋出在我的獨立部落格中-Petter Liu Blog。