主頁(yè) > 知識(shí)庫(kù) > 趙海平大神談異步處理對(duì)分布式系統(tǒng)的優(yōu)化

趙海平大神談異步處理對(duì)分布式系統(tǒng)的優(yōu)化

熱門(mén)標(biāo)簽:威海語(yǔ)音外呼系統(tǒng)平臺(tái) 太原做地圖標(biāo)注的 機(jī)器人電銷(xiāo)原理 各國(guó)地圖標(biāo)注點(diǎn) 銅川外呼系統(tǒng)代理商 漢中電話機(jī)器人哪家好 wow地圖標(biāo)注插件怎么用 外呼系統(tǒng)是怎么實(shí)現(xiàn)高頻 如何代理外呼線路

單機(jī)時(shí)代的數(shù)據(jù)請(qǐng)求

十五年前寫(xiě)軟件是很簡(jiǎn)單的,一個(gè)Client對(duì)應(yīng)一個(gè)DB Server,或者多個(gè)Client對(duì)應(yīng)一個(gè)DB Server,每一個(gè)Client執(zhí)行各自的服務(wù)。當(dāng)時(shí)的討論很多是說(shuō),這個(gè)東西要寫(xiě)在Client端還是寫(xiě)在DB Server端,流行的思路有兩種:

1.把DB Server寫(xiě)得很復(fù)雜,比如Oracle數(shù)據(jù)庫(kù),而Client端則寫(xiě)得很簡(jiǎn)單,只有調(diào)用返回
2.DB很簡(jiǎn)單,只有簡(jiǎn)單的表,而Client寫(xiě)得復(fù)雜。很多創(chuàng)業(yè)公司會(huì)這樣做,因?yàn)樗麄儗?duì)SQL不是很熟悉,但是很熟悉PHP。早期Facebook就是典型的代表


大數(shù)據(jù)時(shí)代的數(shù)據(jù)請(qǐng)求

單機(jī)時(shí)代隨著兩個(gè)趨勢(shì)而逐漸成為歷史。一個(gè)趨勢(shì)是隨著互聯(lián)網(wǎng)的流行,越來(lái)越多的人開(kāi)始上網(wǎng)使用Web服務(wù),而且很多時(shí)候用戶增長(zhǎng)速度是非??斓?,結(jié)果造成一臺(tái)DB Server無(wú)法儲(chǔ)存下所有用戶的數(shù)據(jù)。第二個(gè)趨勢(shì)是計(jì)算機(jī)能力越來(lái)越強(qiáng),網(wǎng)絡(luò)服務(wù)針對(duì)每一個(gè)用戶要做的事情也變多了,比如Facebook不僅要保存一個(gè)用戶的個(gè)人信息,還有他的關(guān)系鏈信息,他的使用習(xí)慣、點(diǎn)擊習(xí)慣等,就造成一個(gè)用戶的數(shù)據(jù)量也大大增加,僅僅訪問(wèn)一個(gè)DB Server就準(zhǔn)備好一個(gè)頁(yè)面變成了不可能的事情。

這就帶來(lái)了一個(gè)問(wèn)題:針對(duì)多個(gè)DB Server的程序應(yīng)該怎么寫(xiě)?

針對(duì)這個(gè)問(wèn)題也有兩個(gè)思路:

1.串行同步。先query DB1,返回res1,再使用res1做另一個(gè)DB的query,返回res2。這是在第二個(gè)Query依賴第一個(gè)Query結(jié)果的情況
2.并行同步。針對(duì)DB1的query跟針對(duì)DB2的query同步進(jìn)行。這是兩個(gè)Query之間沒(méi)有依賴關(guān)系的情況。Facebook早期專(zhuān)門(mén)寫(xiě)了一個(gè)并行處理的函數(shù),用法是 ExecParallelQuery(conn1,Query1,conn2,Query2)
這個(gè)時(shí)候的代碼就比以前的代碼更加復(fù)雜了,不過(guò)還是能實(shí)現(xiàn)需要實(shí)現(xiàn)的需求。但這時(shí)候帶來(lái)了一個(gè)新的問(wèn)題,就是等待。一個(gè)頁(yè)面的加載可能需要調(diào)用不同的函數(shù),而不同的函數(shù)可能是由不同的團(tuán)隊(duì)寫(xiě)的。比如獲取朋友關(guān)系的函數(shù)getFriends把自己需要的數(shù)據(jù)用同步的方式獲取了,但如果一個(gè)第三方開(kāi)發(fā)者過(guò)來(lái),則不僅要調(diào)用這個(gè)函數(shù),還需要調(diào)用其他函數(shù),這樣其他函數(shù)的執(zhí)行就需要等待前面這個(gè)getFriends函數(shù)返回了結(jié)果之后才能開(kāi)始執(zhí)行,就很慢了。

要如何做到并行處理在代碼層面很直觀,在機(jī)器上的執(zhí)行效率又好呢?

異步的處理思路就是這么來(lái)的。

所謂異步就是,我這個(gè)函數(shù)知道這里需要訪問(wèn)哪幾個(gè)DB Server,但我先不著急去訪問(wèn),而是先記錄一下,等等看其他函數(shù)是不是也要訪問(wèn)這個(gè)DB,如果有的話,待會(huì)兒再一起去訪問(wèn)。異步處理的指令比如說(shuō)是 conn.asyncExec(Query) ,這個(gè)可以立刻返回一個(gè)Future對(duì)象,意思就是“待會(huì)兒再去執(zhí)行”。如果每個(gè)函數(shù)都返回這種Future對(duì)象,那么就可以根據(jù)這些Future對(duì)象來(lái)判斷哪些請(qǐng)求沒(méi)有依賴可以并行處理,哪些請(qǐng)求有依賴需要串行處理了。如此,不同的團(tuán)隊(duì)寫(xiě)出來(lái)的函數(shù)就不用一個(gè)等一個(gè),而是可以在更高層面上互相合作。

然而這又帶來(lái)了一個(gè)問(wèn)題,那就是異步處理的寫(xiě)法是具有傳染性的。如果一個(gè)服務(wù)中有的函數(shù)寫(xiě)的異步,有的函數(shù)沒(méi)寫(xiě)異步,就會(huì)造成有的函數(shù)返回了Future Object,有的函數(shù)返回了數(shù)值,導(dǎo)致無(wú)法執(zhí)行。要實(shí)現(xiàn)異步,需要關(guān)聯(lián)的所有函數(shù)都用異步的寫(xiě)法返回Future Object才可以。

所以Facebook在轉(zhuǎn)向異步處理的過(guò)程是非常痛苦的,一開(kāi)始做了局部修改,再修改調(diào)用了局部修改過(guò)的函數(shù)的函數(shù),所有調(diào)用的調(diào)用都要修改,最后全部改成了異步,只要有調(diào)用遠(yuǎn)程服務(wù)IO的操作都要改。每一個(gè)DB Query都拆分成兩步,一個(gè)set request,一個(gè)receive response。這里的工作量很大,所以如果創(chuàng)業(yè)團(tuán)隊(duì)的話,最好是第一天就用正確的寫(xiě)法,就不會(huì)這么痛苦。

所有函數(shù)改寫(xiě)后,每一個(gè)函數(shù)執(zhí)行都會(huì)返回Future Object。那么異步處理的第一步,就是將這些Future Object形成一棵依賴樹(shù)的結(jié)構(gòu),好像這樣:

這里每個(gè)節(jié)點(diǎn)都是一個(gè)Future對(duì)象,每一個(gè)Future對(duì)象有兩種狀態(tài),一個(gè)是等待執(zhí)行,一個(gè)是完成執(zhí)行。同級(jí)的節(jié)點(diǎn)是沒(méi)有依賴關(guān)系的,可以并行執(zhí)行;上下節(jié)點(diǎn)是有依賴關(guān)系的,需要串行執(zhí)行,先執(zhí)行下層再執(zhí)行上層。

樹(shù)結(jié)構(gòu)形成后,從下到上執(zhí)行,直到最上面的top parent節(jié)點(diǎn)被執(zhí)行進(jìn)入完成執(zhí)行的狀態(tài),就是完成,比如一個(gè)頁(yè)面加載完畢。

所以異步處理之后有一個(gè)很有意思的情況,那就是PHP這個(gè)語(yǔ)言已經(jīng)跟以前不同了,不再是一上來(lái)就是執(zhí)行,而是一上來(lái)先lazy一下,看清楚所有的Query之后再執(zhí)行。

異步處理還需要解決的問(wèn)題

到目前為止,這樣做異步處理似乎已經(jīng)是足夠好的優(yōu)化,但實(shí)際上還有問(wèn)題。看看下面這個(gè)例子。

比如我們現(xiàn)在有兩個(gè)查詢需求。一個(gè)是查詢你在淘寶上買(mǎi)過(guò)東西的朋友,另一個(gè)是查詢你在淘寶上買(mǎi)過(guò)保時(shí)捷的朋友。常理來(lái)說(shuō),我們會(huì)先想到查詢你在淘寶上的朋友,再進(jìn)行另一個(gè)條件的查詢,比如這樣:

Java Code復(fù)制內(nèi)容到剪貼板
  1. IdList friends = waitFor(getFriends(myId));   
  2. yield return getTaoBaoBuyers(friends);  

但是對(duì)于保時(shí)捷這個(gè)查詢而言,這是不對(duì)的,因?yàn)樘詫毶腺I(mǎi)保時(shí)捷的人是很少的,可能就一兩個(gè),而淘寶上的好友數(shù)可能有上百。因此保時(shí)捷的查詢應(yīng)該是這個(gè)次序比較優(yōu)化:

Java Code復(fù)制內(nèi)容到剪貼板
  1. IdList buyers = waitFor(getPorscheBuyer());   
  2. yield return getFriends(buyers);  

這個(gè)次序應(yīng)該如何決定?實(shí)際上不應(yīng)該在寫(xiě)程序的時(shí)候決定,因?yàn)閷?xiě)程序的時(shí)候是無(wú)法避免有先后順序的——編輯器只能一行一行的寫(xiě)代碼,但是機(jī)器執(zhí)行卻無(wú)需管這個(gè)。所以更好的方法應(yīng)該是在執(zhí)行代碼之前再加入一個(gè)phase。

其實(shí)傳統(tǒng)數(shù)據(jù)庫(kù)的cardinality(基數(shù))功能已經(jīng)解決了這個(gè)問(wèn)題。你在DB query里面使用 INNER JOIN 這個(gè)指令,其實(shí)DB已經(jīng)能夠預(yù)判哪一個(gè)表給出的row會(huì)比較少,從而以更優(yōu)化的次序去執(zhí)行。但現(xiàn)在我們用的編程語(yǔ)言,無(wú)論是PHP,Java,Python還是C/C++,并沒(méi)有考慮這個(gè)問(wèn)題。有人會(huì)開(kāi)很多線程來(lái)解決這個(gè)問(wèn)題,但這不是最佳方案,因?yàn)樵贚inux系統(tǒng)里,你的線程數(shù)要是上了200-300,就會(huì)有很大的overhead。

代碼執(zhí)行的次序,這是一個(gè)。另外最近幾年還有一個(gè)流行的優(yōu)化思路,就是上memcache。我們有時(shí)候會(huì)看到程序員把他自己的函數(shù)放進(jìn)了memcache,相當(dāng)于是依賴樹(shù)的中間的一個(gè)節(jié)點(diǎn),我就問(wèn)他為什么要把他這個(gè)Class放入memcache,他可能會(huì)說(shuō),他覺(jué)得這個(gè)節(jié)點(diǎn)和這個(gè)節(jié)點(diǎn)的child被調(diào)用的次數(shù)多。我覺(jué)得這可能不是特別理想的。你今天覺(jué)得這個(gè)Class被調(diào)用的多,可以放進(jìn)memcache,但明天是不是會(huì)有更重要的Class會(huì)更值得放進(jìn)memcache,于是你又要把memcache的資源讓給這個(gè)新的Class?如果你放入memcache的Class并不是最重要的,這就相當(dāng)于真正優(yōu)化的可能性被拿走了。

如何讓異步執(zhí)行的更好?

哪個(gè)query先執(zhí)行,哪個(gè)query后執(zhí)行,不應(yīng)該是在編碼階段來(lái)做的。哪個(gè)Class該進(jìn)memcache,哪個(gè)Class該出memcache,也不應(yīng)該在編碼階段來(lái)做。應(yīng)該有一個(gè)中間的階段,專(zhuān)門(mén)進(jìn)行這種調(diào)度工作,然而到目前為止,還沒(méi)有公司能夠做到,因?yàn)闆](méi)有合適的語(yǔ)言。

異步處理在分布式系統(tǒng)中怎樣做有更好的優(yōu)化作用,我們需要更多的思考。希望大家能夠把計(jì)算機(jī)當(dāng)作科學(xué)去思考,而不僅僅是工程應(yīng)用。我們現(xiàn)在看十幾年前,對(duì)單機(jī)是非常了解了,那么未來(lái)過(guò)了五年十年再回來(lái)看,可能對(duì)分布式系統(tǒng)也會(huì)了解的比現(xiàn)在更多很多,可能給分布式系統(tǒng)寫(xiě)程序也會(huì)變得跟給單機(jī)寫(xiě)程序一樣簡(jiǎn)單。當(dāng)然這就需要更合適的工具語(yǔ)言去給大家提供這種異步的便利。是不是會(huì)有Haskell那樣lazy的方式從系統(tǒng)層面解決這個(gè)問(wèn)題?希望跟大家一起思考探討。

標(biāo)簽:自貢 南京 辛集 石嘴山 茂名 三明 三門(mén)峽 成都

巨人網(wǎng)絡(luò)通訊聲明:本文標(biāo)題《趙海平大神談異步處理對(duì)分布式系統(tǒng)的優(yōu)化》,本文關(guān)鍵詞  趙海,平,大神,談,異步,處理,;如發(fā)現(xiàn)本文內(nèi)容存在版權(quán)問(wèn)題,煩請(qǐng)?zhí)峁┫嚓P(guān)信息告之我們,我們將及時(shí)溝通與處理。本站內(nèi)容系統(tǒng)采集于網(wǎng)絡(luò),涉及言論、版權(quán)與本站無(wú)關(guān)。
  • 相關(guān)文章
  • 下面列出與本文章《趙海平大神談異步處理對(duì)分布式系統(tǒng)的優(yōu)化》相關(guān)的同類(lèi)信息!
  • 本頁(yè)收集關(guān)于趙海平大神談異步處理對(duì)分布式系統(tǒng)的優(yōu)化的相關(guān)信息資訊供網(wǎng)民參考!
  • 企业400电话

    智能AI客服机器人
    15000

    在线订购

    合计11份范本:公司章程+合伙协议+出资协议+合作协议+股权转让协议+增资扩股协议+股权激励+股东会决议+董事会决议

    推薦文章