中文字幕在线观看,亚洲а∨天堂久久精品9966,亚洲成a人片在线观看你懂的,亚洲av成人片无码网站,亚洲国产精品无码久久久五月天

Twitter 架構(gòu)如何支持上億用戶

2018-07-20    來(lái)源:編程學(xué)習(xí)網(wǎng)

容器云強(qiáng)勢(shì)上線!快速搭建集群,上萬(wàn)Linux鏡像隨意使用

談到設(shè)計(jì)Twitter, 我們首先要問(wèn)一個(gè)本質(zhì)問(wèn)題: 設(shè)計(jì)Twitter的基本方法論是什么?

其實(shí)是我們計(jì)算機(jī)設(shè)計(jì)最基本的方法: 分治法(Divide and Conquer)。

什么是分治法呢?就是把問(wèn)題不斷的拆解,拆解到你可以解決為止,它的藝術(shù)在于,從哪個(gè)維度來(lái)拆解非?简(yàn)我們能力。

如果要求一周開(kāi)發(fā)出Twitter,你會(huì)怎么做?

你的架構(gòu)是什么樣的呢?

相信你一定不會(huì)給出復(fù)雜的架構(gòu)。前端是各種各樣的業(yè)務(wù)邏輯,后端是MySQL數(shù)據(jù)庫(kù),這樣就夠了。因?yàn)檫@已經(jīng)解決了當(dāng)時(shí)的問(wèn)題,滿足了一周開(kāi)發(fā)出來(lái)的要求。

Twitter 架構(gòu)如何支持上億用戶

但隨著Twitter的成長(zhǎng),我們會(huì)遇到各種各樣新的挑戰(zhàn):

  • MySQL難擴(kuò)展。

    為什么難擴(kuò)展?因?yàn)樗淹瑯拥囊粋(gè)數(shù)據(jù)分成各種關(guān)系存在里面,每次取的時(shí)候,都要通過(guò)Join來(lái)進(jìn)行復(fù)雜的操作,這個(gè)Join當(dāng)數(shù)據(jù)被切分的時(shí)候存在更多的服務(wù)器上,會(huì)變得越來(lái)越復(fù)雜,所以很難擴(kuò)展。

  • 小變化也要全部部署。

    任何變化都需要部署到所有機(jī)器上,因?yàn)榉⻊?wù)不斷升級(jí),就變成了每天不斷部署,變成了daily deployment。所以每次部署的時(shí)候耽誤時(shí)間很長(zhǎng)。

  • 性能差。

    因?yàn)樗蟹⻊?wù)都要部署在一起,造成了它的內(nèi)存占用率大,而且部分核心模塊還因?yàn)樽畛醍?dāng)時(shí)的單線程設(shè)計(jì)成為了各種瓶頸。

  • 架構(gòu)混亂。

    因?yàn)樗心K在一起很混亂。

Twitter 架構(gòu)如何支持上億用戶

那要怎么破解這些問(wèn)題?

答案是將問(wèn)題拆解開(kāi)來(lái)。

第一刀將存儲(chǔ)切開(kāi)。

我們看后臺(tái),可以拆成存Tweets,存User,存Timeline,存Social Graph不同內(nèi)容,Timeline可以拿Redis這樣的數(shù)據(jù)庫(kù)來(lái)保存,而對(duì)于其它的數(shù)據(jù)比如Gizzard其實(shí)是一個(gè)分布式的MySQL數(shù)據(jù)庫(kù)。并不是所有數(shù)據(jù)都不適合用MySQL分布,我們可以把這些適合的用MySQL來(lái)shutting一下,而不適合的用別的數(shù)據(jù)庫(kù)來(lái)存,就是一個(gè)存儲(chǔ)切開(kāi)的方法。

第二刀是將路由、展示、邏輯切開(kāi)。

我們可以看到又多出了一層,邏輯層。Tweets,User,Timeline它們分別對(duì)應(yīng)后邊的各種數(shù)據(jù)存儲(chǔ)。前端會(huì)有外部訪問(wèn)的接口,API訪問(wèn)接口,并且它還保存了以前數(shù)據(jù)的整個(gè)架構(gòu),用來(lái)進(jìn)行一些小規(guī)模的使用。最前面需要有一個(gè)Routing,來(lái)將不同的請(qǐng)求分布到不同的API上。所以之后Twitter就變成了上百上千個(gè)小小的數(shù)據(jù)模塊,包括它的服務(wù)模塊,他們通過(guò)之間的相互調(diào)用來(lái)完成具體的請(qǐng)求。

Twitter 架構(gòu)如何支持上億用戶

如果Lady Gaga發(fā)了個(gè)推文,會(huì)發(fā)生什么呢?

首先她發(fā)出一個(gè)推文,會(huì)到達(dá)最上面一層的外部模塊,負(fù)責(zé)把推文寫(xiě)出來(lái);接著到了API模塊,負(fù)責(zé)接收這個(gè)推文;再往后是Fanout,F(xiàn)anout將推文的ID推薦給所有訂閱這個(gè)用戶的信息收件箱里,收件箱就是Timeline,比如有400萬(wàn)人訂閱了Lady Gaga,就會(huì)有400萬(wàn)的收件箱收到這個(gè)消息;緊接著由于我們Timeline要發(fā)到收件箱里,收件箱必然是一個(gè)最復(fù)雜的操作,為了優(yōu)化它的性能,就把它們用分布式的方式存儲(chǔ)在Redis里面,Redis是偏向內(nèi)存的數(shù)據(jù)庫(kù),所以能夠很快的存儲(chǔ)這些信息;但Redis里存的只是ID,所以當(dāng)一個(gè)用戶具體要她推文的時(shí)候,實(shí)際上要通過(guò)Timeline服務(wù)去找到這個(gè)用戶對(duì)應(yīng)的是哪個(gè)Redis服務(wù)器上存了推文的 Timeline list,接著找到所有ID,然后這個(gè)Timeline service把ID的具體內(nèi)容通過(guò)另外的數(shù)據(jù)庫(kù)裝載進(jìn)來(lái),最終得到結(jié)果反饋給用戶。這些保證了我們推整個(gè)數(shù)據(jù)的時(shí)候速度最快,能夠達(dá)到每秒30萬(wàn)次的性能。

Twitter 架構(gòu)如何支持上億用戶

雖然有了這樣的過(guò)程,如何支持搜索呢?

很簡(jiǎn)單的想法是當(dāng)我們寫(xiě)入API,它Fanout到每個(gè)用戶的Timeline list的時(shí)候,我們可以拿另外的Ingester把這個(gè)推文放到里面,Ingesert最后把它放到Earlybird,就是所謂的倒排索引中。比如有個(gè)推文發(fā)過(guò)來(lái)“我喜歡太陽(yáng)”,就把我,喜歡,太陽(yáng),拆成三個(gè)詞,把這些單詞,進(jìn)行倒排索引,存到Search index里面。這時(shí)候?qū)嶋H會(huì)用到很多很多Earlybird,這樣就能建立很多倒排索引,能夠并行的去做。當(dāng)用戶一個(gè)請(qǐng)求過(guò)來(lái)之后,比如搜索“早上吃飯”,就會(huì)把morning和eat作為兩個(gè)關(guān)鍵詞發(fā)到我的Earlybird集群里,得到結(jié)果后Blender會(huì)把它組合到一塊,并反饋結(jié)果。當(dāng)然很多用戶可以并行的向Blender發(fā)送請(qǐng)求,從而得到最終結(jié)果,這就是我們的搜索服務(wù)。

Twitter 架構(gòu)如何支持上億用戶

如何通知用戶新消息到達(dá)呢?

第一個(gè)方法是另外再開(kāi)一個(gè)Write API,在有新東西發(fā)生以后,我把它放到一個(gè)Push的服務(wù)里,那所有用戶只要都連到這個(gè)后臺(tái)里,HTTP PUSH,就會(huì)通知他有新消息產(chǎn)生了。同理對(duì)Mobile ,會(huì)有Mobile Push,當(dāng)然大家對(duì)不同的信息有不同的對(duì)接方法,大家可以去仔細(xì)考慮下怎么能做到這個(gè)樣子。

Twitter 架構(gòu)如何支持上億用戶

如何搭建這樣的服務(wù)呢?

最基本的是開(kāi)源項(xiàng)目Twitter-Server。

  • 配置服務(wù),IP之類;

  • 管理服務(wù),哪些down了、控制、啟動(dòng)等;

  • 日志服務(wù),運(yùn)行怎么樣,以后出問(wèn)題找誰(shuí)等;

  • 生命周期服務(wù),什么時(shí)候啟,什么時(shí)候關(guān),什么時(shí)候控制;

  • 監(jiān)控服務(wù),到底有沒(méi)有出錯(cuò),出錯(cuò)以后怎么辦,互相報(bào)警等

這些東西合到一起,就構(gòu)成了這樣服務(wù)的基本架構(gòu)。

Twitter 架構(gòu)如何支持上億用戶

各個(gè)服務(wù)之間如何交流?

這就是傳統(tǒng)的RPC(遠(yuǎn)程的進(jìn)程調(diào)用),大家能夠通訊的不僅是數(shù)據(jù),而且可以通訊命令或請(qǐng)求之類的。這時(shí)需要開(kāi)源項(xiàng)目Finagle。

  • 能夠提供服務(wù)發(fā)現(xiàn),因?yàn)橛泻芏喾⻊?wù),所以要找誰(shuí)發(fā)送這個(gè)請(qǐng)求呢;

  • 負(fù)載均衡,可能有十個(gè)人提供服務(wù),先放到誰(shuí)那兒?

  • 重試,如果失敗了怎么辦,是否需要重試?

  • 基本的線程池和鏈接池,大家可以復(fù)用,不用每次去創(chuàng)建,浪費(fèi)資源了;

  • 統(tǒng)計(jì)信息的收集;

  • 分布式調(diào)試。

Twitter 架構(gòu)如何支持上億用戶

如何調(diào)用一個(gè)服務(wù)?

因?yàn)閺腁調(diào)用B,大家之間各種遠(yuǎn)程,寫(xiě)代碼上要怎么做呢?可以使用函數(shù)來(lái)調(diào)用(Service as a Function),背后實(shí)際上是Function programming的思想。

可以看下這個(gè)基本例子:trait Service[Req,Rep]extends(Req=>Future[Rep])

簡(jiǎn)單理解為:我有一個(gè)請(qǐng)求想得到一個(gè)Response,就是Request到Response。這里面實(shí)際上可以先面向未來(lái)實(shí)現(xiàn),之后當(dāng)它執(zhí)行的時(shí)候,就會(huì)得到相對(duì)應(yīng)的結(jié)果。

Twitter 架構(gòu)如何支持上億用戶

多個(gè)服務(wù)的調(diào)用如何整合在一起?

我們看一看它要如何運(yùn)行?比如我們有一個(gè)請(qǐng)求是得到一個(gè)用戶的所有Timeline數(shù)據(jù)。它其實(shí)有很多步,第一步是得到User ID;第二步得到User timeline list里的那些消息ID;下一步是針對(duì)每一個(gè)消息,得到它的每一個(gè)具體內(nèi)容,比如“我早上吃飯”這些內(nèi)容,這些內(nèi)容里面可能還有圖片,還需要得到圖片的數(shù)據(jù)。這是一個(gè)很復(fù)雜的過(guò)程,但這個(gè)箭頭表達(dá)了它們最基本的執(zhí)行順序。

Twitter 架構(gòu)如何支持上億用戶

最佳的執(zhí)行路徑是什么?

首先是得到ID,再得到Timeline以后可以并行地讀取每個(gè)tweet,可能會(huì)有的快有的慢,然后又得到一些它的具體信息,比如說(shuō)圖片之類,所以這就是最優(yōu)策略。

下面我們來(lái)看一看代碼:

第一行是得到用戶ID,用一個(gè)面向未來(lái)的方程得到一個(gè)用戶ID。

第二行根據(jù)ID拿FlatMap,F(xiàn)latMap其實(shí)是后面針對(duì)每一個(gè)ID執(zhí)行的函數(shù),這個(gè)函數(shù)來(lái)得到這個(gè)ID用戶的Timeline list。所以這也是我們Function programming,或者如果用Spark也會(huì)經(jīng)常碰見(jiàn)的函數(shù)。

得到每一個(gè)ID以后,實(shí)際上要針對(duì)每個(gè)ID執(zhí)行,所以需要Map。Map每一個(gè)ID是做什么的,得到這個(gè)Tweet的具體信息。代碼第二行就是根據(jù)ID得到他的具體內(nèi)容。

當(dāng)然如果這個(gè)東西有圖片,那需要得到圖片。

中間一步還需要把這些東西并行起來(lái),大家都去單獨(dú)得到Tweet,并且把它集合放到一塊兒去。整個(gè)過(guò)程我們就得到了最終的代碼。

這其實(shí)就是 第三刀:切開(kāi)“做什么”和“怎么做”。 在這個(gè)代碼過(guò)程中,所謂面向函數(shù)的編程,只是寫(xiě)了想做什么事兒,但具體怎么做,比如從哪個(gè)機(jī)器找、連接服務(wù)器、從誰(shuí)那兒抓取,怎么并行等都沒(méi)有寫(xiě),實(shí)際上這些東西都被封裝到了一個(gè)底層的庫(kù)里面。所以現(xiàn)在Twitter就可以有兩個(gè)團(tuán)隊(duì),一個(gè)團(tuán)隊(duì)負(fù)責(zé)寫(xiě)代碼,“做什么”;另一個(gè)團(tuán)隊(duì)負(fù)責(zé)寫(xiě)底層是怎么實(shí)現(xiàn)的。這樣就能實(shí)現(xiàn)并行開(kāi)發(fā),這也是Function programming的一個(gè)好處。

Twitter 架構(gòu)如何支持上億用戶

一個(gè)服務(wù)器的架構(gòu)長(zhǎng)什么樣呢?

上方是你的服務(wù),下方就是你的服務(wù)器,包括一些集群的管理、內(nèi)存、Java的虛擬機(jī)、操作系統(tǒng)和硬件。

Twitter 架構(gòu)如何支持上億用戶

有很多服務(wù)如何整合?

結(jié)果整合到一起就是很多層,底層都是一樣的,但上層跑了不同的服務(wù):HTTP、聚集器、時(shí)間timeline服務(wù)等。我們所有東西加在一起,系統(tǒng)就會(huì)跑上千個(gè)不同的小服務(wù)器,而且之間會(huì)有各種各樣的備份。

Twitter 架構(gòu)如何支持上億用戶

那如何來(lái)統(tǒng)計(jì)出現(xiàn)的服務(wù)器情況呢?

比如會(huì)統(tǒng)計(jì)平均延遲,或統(tǒng)計(jì)一些信息來(lái)驗(yàn)證服務(wù)器是不是出問(wèn)題了,實(shí)際上,在這種大規(guī)模里面,一個(gè)比較好的方法就是不要拿平均值統(tǒng)計(jì),因?yàn)樘厥馇闆r會(huì)拉低所有情況。舉個(gè)例子,假設(shè)北京有一個(gè)人,他年收入是100萬(wàn),另外99個(gè)人每個(gè)人年收入都是1元。那平均下來(lái)每個(gè)人收入都是1萬(wàn)塊錢,但實(shí)際上大多數(shù)人是很窮困的。所以不能拿平均數(shù)來(lái)算,尤其是在服務(wù)器的情況下。所以大家一般都會(huì)取中位數(shù)(median),百分之90的點(diǎn),百分之99的點(diǎn)和百分之999的點(diǎn)。我們可以看到,下圖是一個(gè)服務(wù)發(fā)生故障的前后。在服務(wù)故障發(fā)生前,百分之99點(diǎn)的平均延遲是100毫秒,但故障發(fā)生后變成400毫秒,發(fā)現(xiàn)這個(gè)問(wèn)題以后就會(huì)去抓。但如果用平均值,很可能就發(fā)現(xiàn)不了這個(gè)問(wèn)題。

這樣還有一個(gè)好處,當(dāng)我們做到上面整合的架構(gòu)以后,每一個(gè)負(fù)責(zé)寫(xiě)代碼的團(tuán)隊(duì),只負(fù)責(zé)處理跟它相關(guān)的上下層就行,而不用做那么多交互,所以每個(gè)人的東西都非常簡(jiǎn)單,這也是所謂微服務(wù)的一個(gè)好處。

Twitter 架構(gòu)如何支持上億用戶

如何監(jiān)控一個(gè)服務(wù)呢?

實(shí)際上針對(duì)這個(gè)服務(wù)在整個(gè)棧里面用的時(shí)間,會(huì)有一個(gè)圖表達(dá)出來(lái)。

Twitter 架構(gòu)如何支持上億用戶

如何監(jiān)控一個(gè)請(qǐng)求呢?

實(shí)際上,基于一個(gè)請(qǐng)求,會(huì)有一個(gè)整個(gè)運(yùn)行的最佳策略,這就需要運(yùn)行的整個(gè)過(guò)程的圖。這就是我們之前講的,得到一個(gè)用戶所有Timeline內(nèi)容信息的鋸齒圖,Zipkin,這也是一個(gè)開(kāi)源項(xiàng)目。

Twitter 架構(gòu)如何支持上億用戶

如何監(jiān)控系統(tǒng)的運(yùn)行情況呢?

因?yàn)檫@個(gè)時(shí)候失敗已經(jīng)成為常事了。舉個(gè)例子,假設(shè)每秒有30萬(wàn)的請(qǐng)求,有99.99%的成功率,那每秒一定會(huì)有30個(gè)失敗的,所以不能說(shuō)每次失敗怎么樣,統(tǒng)計(jì)失敗率會(huì)比單獨(dú)的失敗更重要,而且寫(xiě)代碼的時(shí)候要為這個(gè)失敗來(lái)進(jìn)行自動(dòng)重試。大家不用糾結(jié)每次的失敗,只要大部分過(guò)去就行了。

Twitter 架構(gòu)如何支持上億用戶

最后做下總結(jié)

  • 學(xué)好分治法,走遍天下都不怕。

  • 函數(shù)式設(shè)計(jì)切分做什么和怎么做。做什么是由函數(shù)式設(shè)計(jì)來(lái)寫(xiě),而怎么做由底層的語(yǔ)言和編譯器來(lái)優(yōu)化。

  • 面向錯(cuò)誤讓我們使用了統(tǒng)計(jì)域監(jiān)控。99.9%的點(diǎn)出什么問(wèn)題了,這樣就叫做基于統(tǒng)計(jì)域的監(jiān)控方式。

參考資料:《Real-Time Systems at Twitter》

 

 

 

來(lái)自:http://mp.weixin.qq.com/s/c9mFDmHRLbuKbqS6aGUdiQ

 

標(biāo)簽: Mysql 代碼 服務(wù)器 數(shù)據(jù)庫(kù) 搜索

版權(quán)申明:本站文章部分自網(wǎng)絡(luò),如有侵權(quán),請(qǐng)聯(lián)系:west999com@outlook.com
特別注意:本站所有轉(zhuǎn)載文章言論不代表本站觀點(diǎn)!
本站所提供的圖片等素材,版權(quán)歸原作者所有,如需使用,請(qǐng)與原作者聯(lián)系。

上一篇:iOS面試題:阿里-P6一面-參考思路

下一篇:Linux服務(wù)器上監(jiān)控網(wǎng)絡(luò)帶寬的18個(gè)常用命令