系統(tǒng)設(shè)計:設(shè)計Spotify
一、初始階段:基礎(chǔ)版本
需求: 初始要求是處理50萬用戶和3000萬首歌曲。我們將有播放歌曲的用戶和上傳歌曲的藝術(shù)家。
1.估算:數(shù)據(jù)計算
讓我們從估算我們需要的存儲開始。首先,我們需要將歌曲存儲在某種存儲中。
- 歌曲存儲: Spotify等服務(wù)通常使用Ogg Vorbis或AAC等格式進行流媒體傳輸,假設(shè)平均歌曲大小為3MB,我們需要3MB * 3000萬 = 90TB的存儲空間用于歌曲。
- 歌曲元數(shù)據(jù): 我們還需要存儲歌曲元數(shù)據(jù)和用戶配置文件信息。每首歌平均的元數(shù)據(jù)大小約為100字節(jié) — 100字節(jié) * 3000萬 = 3GB
- 用戶元數(shù)據(jù): 平均而言,我們將每個用戶存儲1KB的數(shù)據(jù) — 1KB * 50萬 = 0.5GB
2.高級設(shè)計
- 移動應(yīng)用: 我們將有一個移動應(yīng)用,是用戶與服務(wù)互動的前端。用戶可以搜索歌曲,播放音樂,創(chuàng)建播放列表等。當用戶執(zhí)行操作(如播放歌曲)時,應(yīng)用程序?qū)l(fā)送請求到后端服務(wù)器。
- 負載均衡器: 但在到達服務(wù)器之前,我們有一個負載均衡器,用于在多個web服務(wù)器之間分發(fā)傳入流量。這提高了應(yīng)用程序的可用性和容錯性。
- Web服務(wù)器(API): Web服務(wù)器是處理移動應(yīng)用程序發(fā)來的請求的API。例如,如果用戶想播放一首歌,請求將發(fā)送到這些Web服務(wù)器。服務(wù)器然后確定歌曲的位置(在數(shù)據(jù)庫或存儲服務(wù)中)以及如何檢索它。
3.數(shù)據(jù)存儲
數(shù)據(jù)存儲將分為兩個獨立的服務(wù) — 歌曲的Blob存儲,我們將在其中存儲實際的歌曲文件,以及SQL數(shù)據(jù)庫,我們將在其中存儲歌曲和用戶元數(shù)據(jù)。
- 歌曲 — Blob存儲(例如AWS S3、GCP、Azure Blob存儲): 實際的歌曲文件存儲在Blob(二進制大對象)存儲服務(wù)中。這些服務(wù)設(shè)計用于存儲大量非結(jié)構(gòu)化數(shù)據(jù)。
- 用戶、藝術(shù)家和歌曲元數(shù)據(jù) — SQL數(shù)據(jù)庫: 該SQL數(shù)據(jù)庫存儲結(jié)構(gòu)化數(shù)據(jù),如用戶信息(如用戶名、密碼和電子郵件地址)以及關(guān)于歌曲的元數(shù)據(jù)(如歌曲名稱、藝術(shù)家名稱、專輯詳細信息等)。
為什么使用SQL?SQL數(shù)據(jù)庫非常適合這種類型的結(jié)構(gòu)化數(shù)據(jù),因為它們允許進行復(fù)雜的查詢和不同類型數(shù)據(jù)之間的關(guān)系。
每個歌曲文件都存儲為“blob”,而SQL數(shù)據(jù)庫通常存儲對此文件的引用(如URL)。
4.SQL數(shù)據(jù)庫結(jié)構(gòu)
以下是我們SQL數(shù)據(jù)庫中表及其關(guān)系的基本大綱:
我們將需要一個用戶表,其中包含用戶元數(shù)據(jù),如UserID、Username、Email、PasswordHash、CreatedAt、LastLogin等。
- 歌曲表將保存歌曲的元數(shù)據(jù)信息,例如SongID、Title、ArtistID、Duration、ReleaseDate和FileURL,即指向歌曲文件存儲位置的URL(例如在blob存儲中)。
- 藝術(shù)家表將包含藝術(shù)家信息 — ArtistID、Name、Bio、Country等。
關(guān)系: 我們將在藝術(shù)家歌曲表中連接藝術(shù)家和歌曲表,其中將有**ArtistID**(指向藝術(shù)家表的外鍵)和**SongID**(指向歌曲表的外鍵)。從那里,我們可以獲取歌曲元數(shù)據(jù),其中還將包含指向歌曲所在的Blob存儲的**FileURL**屬性。
5.將所有內(nèi)容整合
因此,Web服務(wù)器將從SQL數(shù)據(jù)庫獲取歌曲元數(shù)據(jù),從中獲取fileURL,然后將其分塊流式傳輸?shù)揭苿討?yīng)用程序?;蛘呶覀兛梢灾苯訌膶ο蟠鎯α魇絺鬏?shù)娇蛻舳耍@過Web服務(wù)器以減輕負載。
二、擴展階段:5000萬用戶,2億首歌曲
現(xiàn)在如果我們擴展到5000萬用戶和2億首歌曲呢?我們首先需要重新計算數(shù)據(jù)。這意味著SQL數(shù)據(jù)存儲需要存儲200/30 = 約6.66倍的歌曲元數(shù)據(jù):
每首歌100字節(jié) * 2億首歌 = 20GB
用戶元數(shù)據(jù)也是如此:
每個用戶1KB * 5000萬用戶 = 50GB
1.引入CDN
由于流量增加 — 我們需要引入緩存和CDN(如Cloudfront / Cloudflare)來提供歌曲,每個CDN將在地理上接近一個區(qū)域;因此,它可以比Web服務(wù)器更快地提供歌曲。
我們可以使用LRU(Least Recently Used)淘汰策略緩存熱門歌曲,而不熱門的歌曲仍然將從Blob存儲中獲取,然后緩存在CDN中。
歌曲文件還可以直接從云存儲流式傳輸?shù)娇蛻舳?,這將減輕Web服務(wù)器的負載。
2.擴展數(shù)據(jù)庫:領(lǐng)導(dǎo)者-跟隨者技術(shù)
數(shù)據(jù)庫也需要擴展。由于我們知道我們的應(yīng)用程序獲得的讀取次數(shù)比寫入次數(shù)多,也就是有很多用戶聽歌曲,但相對較少的藝術(shù)家上傳歌曲 — 我們可以使用領(lǐng)導(dǎo)者 → 跟隨者技術(shù),有一個領(lǐng)導(dǎo)者數(shù)據(jù)庫負責接受讀取和寫入,以及多個跟隨者或從數(shù)據(jù)庫僅用于檢索歌曲和用戶元數(shù)據(jù)。
圖片