聊聊Twitter的架構(gòu)決策
研究大規(guī)?;ヂ?lián)網(wǎng)應(yīng)用可以學(xué)到很多東西,像Netflix這樣的公司,其復(fù)雜的架構(gòu)不僅能夠向數(shù)百萬(wàn)用戶提供內(nèi)容,而且還改善了用戶體驗(yàn),增加了用戶粘性。
在一家小公司中,像推送通知這樣的機(jī)制可以是主代碼庫(kù)的一部分,并且可以在同一臺(tái)機(jī)器上與應(yīng)用程序的其他部分一起運(yùn)行。
但在Netflix,負(fù)責(zé)推送通知的服務(wù)器部署在全球多個(gè)數(shù)據(jù)中心,在本文的最后有一個(gè)關(guān)于這一架構(gòu)演進(jìn)的詳細(xì)討論的鏈接。
雖然學(xué)習(xí)這些案例研究很有趣,但大多數(shù)人仍然沒(méi)有在如此大的規(guī)模下工作的經(jīng)驗(yàn)。在某些情況下,我們更容易了解公司如何從傳統(tǒng)的主流應(yīng)用服務(wù)方式轉(zhuǎn)變?yōu)橛嫌脩趔w驗(yàn)的現(xiàn)代解決方案。
下面我們以Twitter為例加以說(shuō)明。
10年前,大約在2012 - 2013年,Twitter呈指數(shù)級(jí)增長(zhǎng),服務(wù)1.5億用戶。
當(dāng)時(shí)Twitter每秒鐘處理6000條來(lái)自用戶的推文。我想說(shuō)的是,這仍然在可控范圍之內(nèi),我們擁有高吞吐量的數(shù)據(jù)庫(kù)可以處理這一寫入速率。
但對(duì)于閱讀推文的用戶來(lái)說(shuō),就有問(wèn)題了。當(dāng)每個(gè)用戶查詢Twitter主頁(yè)時(shí),必須獲取到所關(guān)注的每個(gè)人的推文組合,這就是每秒鐘30萬(wàn)請(qǐng)求!
如果直接從數(shù)據(jù)庫(kù)讀取,這個(gè)讀取速率會(huì)讓人發(fā)瘋!
每個(gè)請(qǐng)求是什么樣子?我舉個(gè)例子。想象一個(gè)人關(guān)注了5000個(gè)用戶,當(dāng)他打開Twitter網(wǎng)站時(shí),后端使用如下查詢?cè)L問(wèn)數(shù)據(jù)庫(kù):
Get?all?the?tweets?ordered?according?to?time,?if?it?belongs?to?any?of?these?5000?users
如果某個(gè)用戶在這5000個(gè)用戶內(nèi),獲取該用戶所有的推文,并按時(shí)間排序
即使將查詢限制為幾條推文,仍然會(huì)給數(shù)據(jù)庫(kù)帶來(lái)沉重的負(fù)擔(dān)。
—?1?—
Twitter有兩條時(shí)間線:
用戶時(shí)間線:?用戶自己所有推文的集合,從磁盤中獲取。
主頁(yè)時(shí)間線:?用戶關(guān)注的人的推文的集合,組成了用戶的主頁(yè)。
在設(shè)計(jì)數(shù)據(jù)庫(kù)時(shí),最簡(jiǎn)單的數(shù)據(jù)庫(kù)只是將所有寫操作附加到文件的末尾,并在需要時(shí)讀取。沒(méi)有什么比簡(jiǎn)單的附加到文件中更快的了,但是,隨著數(shù)據(jù)庫(kù)文件的增長(zhǎng),從這種類型的數(shù)據(jù)庫(kù)中查詢某些內(nèi)容將花費(fèi)很長(zhǎng)時(shí)間。
為了減少查詢時(shí)間,我們?cè)谄渲刑砑铀饕?。但是添加索引將意味著寫入將花費(fèi)更長(zhǎng)的時(shí)間,因?yàn)楸仨氃趯⑵鋵懭霐?shù)據(jù)庫(kù)之前編輯索引。但由于讀取的數(shù)量將遠(yuǎn)遠(yuǎn)多于寫入的數(shù)量,這是一種公平的權(quán)衡。
同樣,Twitter的閱讀量也遠(yuǎn)遠(yuǎn)超過(guò)了寫入量。所以他們構(gòu)建了一個(gè)系統(tǒng),可以更好的為用戶的主頁(yè)時(shí)間線服務(wù)。他們預(yù)先計(jì)算出所有用戶的主頁(yè)時(shí)間線,并將其存儲(chǔ)在Redis集群中。就這么簡(jiǎn)單!
現(xiàn)在,無(wú)論用戶何時(shí)發(fā)布消息,該消息都會(huì)被插入每個(gè)關(guān)注者的時(shí)間線隊(duì)列中。所以如果你有5000個(gè)粉絲,你的推文就會(huì)有5000個(gè)寫操作!外加上1個(gè)數(shù)據(jù)庫(kù)本身的寫操作??
這聽起來(lái)很瘋狂,但你仔細(xì)想想,這是有道理的?,F(xiàn)在可以同時(shí)為數(shù)百萬(wàn)用戶提供服務(wù)而不需要訪問(wèn)磁盤,這可以從根本上減少延遲。這個(gè)過(guò)程叫做扇出(fan-out)!
那么到目前為止,Twitter的架構(gòu)是怎樣的呢?
用戶訪問(wèn)Twitter的主頁(yè)。
Twitter在Redis集群中查找用戶的主頁(yè)時(shí)間線。
一旦找到,就向用戶直接展示。
當(dāng)用戶發(fā)送一條推文時(shí),該推文會(huì)被復(fù)制到用戶的所有關(guān)注者的時(shí)間線上。
還有一些其他的細(xì)節(jié):
Twitter維護(hù)了一個(gè)圖數(shù)據(jù)庫(kù),其保存了用戶關(guān)注關(guān)系的所有數(shù)據(jù)。當(dāng)發(fā)生扇出時(shí),扇出服務(wù)查詢這個(gè)圖數(shù)據(jù)庫(kù)以確定將推文推送到何處。
扇出將在數(shù)據(jù)中心的3臺(tái)不同的機(jī)器上進(jìn)行復(fù)制,即每個(gè)用戶的時(shí)間線存儲(chǔ)在3臺(tái)不同的機(jī)器上。這是必需的,因?yàn)槿绻渲幸慌_(tái)機(jī)器出現(xiàn)故障,其他機(jī)器可以作為備份提供服務(wù)。
推文本身并不存儲(chǔ)在集群中,而只存儲(chǔ)推文ID。推文將在傳遞給用戶的同時(shí)被檢索出來(lái)。
如果用戶超過(guò)30天沒(méi)有登錄Twitter,該用戶的時(shí)間線將不會(huì)保存在Redis集群中。對(duì)于這類用戶,只有當(dāng)他們返回并向主頁(yè)時(shí)間線發(fā)出請(qǐng)求時(shí),才會(huì)從磁盤重構(gòu)他們的時(shí)間線。
每個(gè)用戶的主頁(yè)時(shí)間線上存儲(chǔ)的推文數(shù)量是有限制的,每次只向用戶顯示800條推文,這是為了控制內(nèi)存使用而做出的設(shè)計(jì)決策!
—?2?—
上述優(yōu)化適用于普通用戶,但名人有特殊的處理,下面我們以Lady Gaga為例,她當(dāng)時(shí)有大約3100萬(wàn)粉絲。

當(dāng)Lady Gaga發(fā)布推文時(shí),會(huì)發(fā)生3100萬(wàn)次扇出操作!而且要復(fù)制3次!
結(jié)果就是,有些用戶可能會(huì)在Lady Gaga的推文發(fā)布5分鐘后才能看到,因?yàn)樗麄兊臅r(shí)間線沒(méi)有被及時(shí)更新。
這就產(chǎn)生了一個(gè)不太好的效果,一個(gè)可以看到Lady Gaga推文的用戶會(huì)回復(fù)這條推文,這條回復(fù)將會(huì)在其他用戶的時(shí)間線中出現(xiàn),而這些用戶還沒(méi)有收到lady Gaga的原始推文,也許可以稱之為無(wú)頭推文(Headless tweets)??
為了避免這種情況,Twitter想出了一種混合方法:
如果一個(gè)人有太多的關(guān)注者,那么就不對(duì)他們的推文做扇出操作。
這些用戶的推文只有在有人請(qǐng)求主頁(yè)時(shí)才會(huì)被合并到時(shí)間線中。
又一個(gè)簡(jiǎn)單的解決方案!
—?3?—
研究Twitter的整個(gè)架構(gòu)是非常困難的,尤其是現(xiàn)在已經(jīng)成為了大公司以后。
但從他們過(guò)去解決大規(guī)模問(wèn)題的方式中學(xué)習(xí),也可以幫助我們?cè)诠ぷ鞯臅r(shí)候做出決策。即使在成千上萬(wàn)的地方存儲(chǔ)一條推文聽起來(lái)很荒謬,如果能夠有效解決問(wèn)題并且沒(méi)有任何副作用,這就一個(gè)很好的解決方案!
參考鏈接:
https://www.infoq.com/presentations/Twitter-Timeline-Scalability/ https://blog.twitter.com/engineering/en_us/topics/infrastructure/2017/the-infrastructure-behind-twitter-scale https://www.youtube.com/watch?v=6w6E_B55p0E
END
-猜你想看-
事件驅(qū)動(dòng)的分布式事務(wù)架構(gòu)設(shè)計(jì)
國(guó)內(nèi)又一個(gè)開源基金會(huì)來(lái)了,Go生態(tài)項(xiàng)目夜鶯成為首選項(xiàng)目
想要了解Go更多內(nèi)容,歡迎掃描下方???關(guān)注?公眾號(hào),回復(fù)關(guān)鍵詞 [實(shí)戰(zhàn)群]? ,就有機(jī)會(huì)進(jìn)群和我們進(jìn)行交流~
分享、在看與點(diǎn)贊,至少我要擁有一個(gè)叭~


